diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 88925ff34c..f6117f941a 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,6 +6,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # Define env vars ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium +ENV NODE_OPTIONS=--max-old-space-size=8192 # [Optional] Uncomment if you want to install an additional version of node using nvm ARG EXTRA_NODE_VERSION="lts/hydrogen" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b7866aa4c3..8219955e2f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -38,6 +38,7 @@ "esbenp.prettier-vscode", "dbaeumer.vscode-eslint", "firsttris.vscode-jest-runner", + "elltg.elltg-npm-script-run", "octref.vetur" ], "settings": { diff --git a/.devcontainer/scripts/git/pre-push b/.devcontainer/scripts/git/pre-push new file mode 100644 index 0000000000..415ef0262a --- /dev/null +++ b/.devcontainer/scripts/git/pre-push @@ -0,0 +1,4 @@ +#!/bin/sh + +yarn run k:build +yarn run k:test:all \ No newline at end of file diff --git a/.devcontainer/scripts/postCreateCommand.sh b/.devcontainer/scripts/postCreateCommand.sh index 313f26169d..08ff58d37a 100644 --- a/.devcontainer/scripts/postCreateCommand.sh +++ b/.devcontainer/scripts/postCreateCommand.sh @@ -3,5 +3,10 @@ echo "Set permissions" sudo chown -R node:node node_modules +echo "Set Git hooks" +echo "Set pre-push hook" +cp .devcontainer/scripts/git/pre-push .git/hooks +chmod +x .git/hooks/pre-push + echo "Installing Deps" yarn install \ No newline at end of file diff --git a/packages/ketchup-react/package.json b/packages/ketchup-react/package.json index abf4ddeedb..a4c6134e45 100644 --- a/packages/ketchup-react/package.json +++ b/packages/ketchup-react/package.json @@ -1,6 +1,6 @@ { "name": "@sme.up/ketchup-react", - "version": "9.6.4", + "version": "9.6.5", "module": "dist/index.js", "typings": "dist/index.d.ts", "keywords": [ @@ -20,7 +20,7 @@ "description": "Ketchup React Components library by smeup", "license": "Apache-2.0", "dependencies": { - "@sme.up/ketchup": "^9.6.4", + "@sme.up/ketchup": "^9.6.5", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/ketchup-showcase/package.json b/packages/ketchup-showcase/package.json index 869b1aadd6..f0c9657656 100644 --- a/packages/ketchup-showcase/package.json +++ b/packages/ketchup-showcase/package.json @@ -19,7 +19,7 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "@sme.up/ketchup": "^9.6.4", + "@sme.up/ketchup": "^9.6.5", "core-js": "^3.30.2", "vue": "^2.6.14", "vue-router": "^3.5.1" diff --git a/packages/ketchup-showcase/src/App.vue b/packages/ketchup-showcase/src/App.vue index 713f3ab6ef..bc094ccb1c 100644 --- a/packages/ketchup-showcase/src/App.vue +++ b/packages/ketchup-showcase/src/App.vue @@ -55,8 +55,8 @@ @kup-tree-nodeselected="treeClick" >
v9.6.4v9.6.5
diff --git a/packages/ketchup-showcase/src/views/components/advanced/planner/examples/PlannerDemo.vue b/packages/ketchup-showcase/src/views/components/advanced/planner/examples/PlannerDemo.vue index 2ce2c42438..2d67ffae0d 100644 --- a/packages/ketchup-showcase/src/views/components/advanced/planner/examples/PlannerDemo.vue +++ b/packages/ketchup-showcase/src/views/components/advanced/planner/examples/PlannerDemo.vue @@ -121,6 +121,15 @@ export default { default: 'undefined', try: 'field', }, + { + prop: 'detailHours', + description: + 'Columns containing detail duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + isArray: true, + try: 'field', + }, { prop: 'detailIdCol', description: 'Column containing unique detail identifier', @@ -135,6 +144,15 @@ export default { default: 'undefined', try: 'field', }, + { + prop: 'detailPrevHours', + description: + 'Columns containing fForecast detail duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + isArray: true, + try: 'field', + }, { prop: 'detailPrevDates', description: @@ -198,6 +216,15 @@ export default { try: 'field', isArray: true, }, + { + prop: 'phaseHours', + description: + 'Columns containing phase duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + try: 'field', + isArray: true, + }, { prop: 'phaseIdCol', description: 'Column containing unique phase identifier', @@ -212,6 +239,15 @@ export default { default: 'undefined', try: 'field', }, + { + prop: 'phasePrevHours', + description: + 'Columns containing forecast phase duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + try: 'json', + isArray: true, + }, { prop: 'phasePrevDates', description: @@ -228,6 +264,13 @@ export default { default: 'false', try: 'switch', }, + { + prop: 'scrollableTaskList', + description: 'Enable/disable scrollbar for task list', + type: 'boolean', + default: 'false', + try: 'switch', + }, { prop: 'showSecondaryDates', description: 'Enable/disable display of secondary dates', @@ -260,6 +303,15 @@ export default { default: 'undefined', try: 'field', }, + { + prop: 'taskHours', + description: + 'Columns containing task duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + try: 'json', + isArray: true, + }, { prop: 'taskIdCol', description: 'Column containing unique task identifier', @@ -288,6 +340,15 @@ export default { default: 'undefined', try: 'field', }, + { + prop: 'taskPrevHours', + description: + 'Columns containing forecast task duration, from (firstHour) to (secondHour)', + type: 'string', + default: 'undefined', + try: 'json', + isArray: true, + }, { prop: 'taskPrevDates', description: diff --git a/packages/ketchup-showcase/src/views/components/basic/pdf/examples/PdfDemo.vue b/packages/ketchup-showcase/src/views/components/basic/pdf/examples/PdfDemo.vue index f4721f63af..0c0b3ad83a 100644 --- a/packages/ketchup-showcase/src/views/components/basic/pdf/examples/PdfDemo.vue +++ b/packages/ketchup-showcase/src/views/components/basic/pdf/examples/PdfDemo.vue @@ -58,7 +58,7 @@ export default { function createComp() { const comp = document.createElement('kup-pdf'); comp.id = 'demo-component'; - comp.pdfPath = '/assets/kup-pdf-sample.pdf'; + comp.pdfPath = 'assets/kup-pdf-sample.pdf'; return comp; } diff --git a/packages/ketchup/package.json b/packages/ketchup/package.json index 68bb1436ec..84bf91fa00 100644 --- a/packages/ketchup/package.json +++ b/packages/ketchup/package.json @@ -1,6 +1,6 @@ { "name": "@sme.up/ketchup", - "version": "9.6.4", + "version": "9.6.5", "keywords": [ "smeup", "KetchUP", diff --git a/packages/ketchup/src/assets/image-list.js b/packages/ketchup/src/assets/image-list.js index ec338e0819..be092f981a 100644 --- a/packages/ketchup/src/assets/image-list.js +++ b/packages/ketchup/src/assets/image-list.js @@ -591,7 +591,7 @@ const data = [ }, ], expandable: true, - icon: 'web', + icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Square_-_black_simple.svg/768px-Square_-_black_simple.svg.png', isExpanded: false, value: 'Framework', visible: true, @@ -610,7 +610,337 @@ const data = [ }, ], expandable: true, - icon: 'library_books', + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + badgeData: [ + { + imageData: { + resource: + 'https://ketchup.smeup.com/ketchup-showcase/header_logo_dark.svg', + sizeX: '1.75rem', + sizeY: 'auto', + color: 'var(--kup-text-on-primary-color)', + }, + position: 'BL', + }, + ], + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + badgeData: [ + { + imageData: { + resource: + 'https://ketchup.smeup.com/ketchup-showcase/header_logo_dark.svg', + sizeX: '1.75rem', + sizeY: 'auto', + color: 'var(--kup-text-on-primary-color)', + }, + position: 'BL', + }, + ], + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://dfstudio-d420.kxcdn.com/wordpress/wp-content/uploads/2019/06/digital_camera_photo-1080x675.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + cells: { + ROUTE: { + value: 'accordion', + }, + }, + icon: 'view-sequential', + value: 'Accordion', + visible: true, + }, + { + cells: { + ROUTE: { + value: 'accordion', + }, + }, + icon: 'view-sequential', + value: 'Accordion', + visible: true, + }, + { + cells: { + ROUTE: { + value: 'accordion', + }, + }, + icon: 'view-sequential', + value: 'Accordion', + visible: true, + }, + { + cells: { + ROUTE: { + value: 'accordion', + }, + }, + icon: 'view-sequential', + value: 'Accordion', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', + isExpanded: false, + value: 'Guides', + visible: true, + }, + { + children: [ + { + cells: { + ROUTE: { + value: 'customization', + }, + }, + icon: 'style', + value: 'Style customization', + visible: true, + }, + ], + expandable: true, + icon: 'https://c8.alamy.com/compit/f4j1rh/verticale-di-tronchi-di-alberi-di-boschi-guardando-verso-l-alto-da-terra-con-il-sole-che-splende-attraverso-foglie-f4j1rh.jpg', isExpanded: false, value: 'Guides', visible: true, diff --git a/packages/ketchup/src/assets/input-panel.js b/packages/ketchup/src/assets/input-panel.js index b2574f9e2b..650db95bb5 100644 --- a/packages/ketchup/src/assets/input-panel.js +++ b/packages/ketchup/src/assets/input-panel.js @@ -17,7 +17,12 @@ let data = { }, { name: 'CIT', - title: 'City', + title: 'Tree Options', + visible: true, + }, + { + name: 'LIS', + title: 'Table Options', visible: true, }, { @@ -102,80 +107,221 @@ let data = { }, editable: true, mandatory: true, - options: [ - { - id: 'ROM', - label: 'Rome', - }, - { - id: 'FLO', - label: 'Florence', - }, - { - id: 'VEN', - label: 'Venice', - }, - { - id: 'MAD', - label: 'Madrid', - }, - { - id: 'BAR', - label: 'Barcelona', - }, - { - id: 'SEV', - label: 'Seville', - }, - { - id: 'BER', - label: 'Berlin', - }, - { - id: 'MUN', - label: 'Munich', - }, - { - id: 'HAM', - label: 'Hamburg', - }, - { - id: 'PAR', - label: 'Paris', - }, - { - id: 'MAR', - label: 'Marseille', - }, - { - id: 'LYO', - label: 'Lyon', - }, - { - id: 'LIS', - label: 'Lisbon', - }, - { - id: 'POR', - label: 'Porto', - }, - { - id: 'FAR', - label: 'Faro', - }, - { - id: 'LON', - label: 'London', - }, - { - id: 'MAN', - label: 'Manchester', - }, - { - id: 'LIV', - label: 'Liverpool', - }, - ], + options: { + type: 'SmeupTree', + messages: [], + children: [ + { + content: { + codice: 'ROM', + testo: 'Rome', + }, + children: [ + { + content: { + codice: 'ROS', + testo: 'Rome Sud', + }, + children: [], + }, + { + content: { + codice: 'RON', + testo: 'Rome Nord', + }, + children: [], + }, + ], + }, + { + content: { + codice: 'FLO', + testo: 'Florence', + }, + children: [], + }, + { + content: { + codice: 'VEN', + testo: 'Venice', + }, + }, + { + content: { + codice: 'MAD', + testo: 'Madrid', + }, + }, + { + content: { + codice: 'BAR', + testo: 'Barcelona', + }, + }, + { + content: { + codice: 'SEV', + testo: 'Seville', + }, + }, + { + content: { + codice: 'BER', + testo: 'Berlin', + }, + }, + { + content: { + codice: 'MUN', + testo: 'Munich', + }, + }, + { + content: { + codice: 'HAM', + testo: 'Hamburg', + }, + }, + { + content: { + codice: 'PAR', + testo: 'Paris', + }, + }, + { + content: { + codice: 'MAR', + testo: 'Marseille', + }, + }, + { + content: { + codice: 'LYO', + testo: 'Lyon', + }, + }, + { + content: { + codice: 'LIS', + testo: 'Lisbon', + }, + }, + { + content: { + codice: 'POR', + testo: 'Porto', + }, + }, + { + content: { + codice: 'FAR', + testo: 'Faro', + }, + }, + { + content: { + codice: 'LON', + testo: 'London', + }, + }, + { + content: { + codice: 'MAN', + testo: 'Manchester', + }, + }, + { + content: { + codice: 'LIV', + testo: 'Liverpool', + }, + }, + ], + }, + fun: 'FUN ', + shape: 'ACP', + }, + LIS: { + value: '', + obj: { + t: '', + p: '', + k: '', + }, + editable: true, + mandatory: true, + options: { + type: 'SmeupTable', + messages: [], + rows: [ + { + fields: { + E1: { + smeupObject: { + codice: 'E1', + testo: 'Element 1', + }, + }, + E2: { + smeupObject: { + codice: 'E2', + testo: 'Element 2', + }, + }, + E3: { + smeupObject: { + codice: 'E3', + testo: 'Element 3', + }, + }, + }, + }, + { + fields: { + E4: { + smeupObject: { + codice: 'E4', + testo: 'Element 4', + }, + }, + E5: { + smeupObject: { + codice: 'E5', + testo: 'Element 5', + }, + }, + E6: { + smeupObject: { + codice: 'E6', + testo: 'Element 6', + }, + }, + }, + }, + { + fields: { + E14: { + smeupObject: { + codice: 'E14', + testo: 'Element 14', + }, + }, + E15: { + smeupObject: { + codice: 'E15', + testo: 'Element 15', + }, + }, + E16: { + smeupObject: { + codice: 'E16', + testo: 'Element 16', + }, + }, + }, + }, + ], + }, shape: 'ACP', }, CHK: { @@ -209,7 +355,67 @@ let data = { shape: 'RAD', }, }, - layout: {}, + layout: { + sections: [ + { + content: [ + { + id: 'NAM', + colStart: 1, + colEnd: 1, + rowStart: 1, + rowEnd: 1, + }, + { + id: 'SUR', + colStart: 2, + colEnd: 2, + rowStart: 1, + rowEnd: 1, + }, + { + id: 'NAT', + colStart: 1, + colEnd: 1, + rowStart: 2, + rowEnd: 2, + }, + { + id: 'CIT', + colStart: 2, + colEnd: 2, + rowStart: 2, + rowEnd: 2, + }, + { + id: 'CHK', + colStart: 1, + colEnd: 1, + rowStart: 3, + rowEnd: 3, + }, + { + id: 'RAD', + colSpan: 2, + rowStart: 3, + rowEnd: 3, + }, + { + id: 'LIS', + colStart: 3, + colEnd: 3, + rowStart: 2, + rowEnd: 2, + }, + ], + dim: '50%', + gridCols: 3, + gridRows: 3, + gap: 2, + }, + ], + horizontal: true, + }, }, ], }; @@ -246,4 +452,29 @@ const inputPanelCallback = [ }, ]; +const optionsHandlerCallback = () => { + return Promise.resolve({ + type: 'SmeupTree', + messages: [], + children: [ + { + content: { + codice: 'ROM', + testo: 'Rome', + }, + children: [], + }, + { + content: { + codice: 'TAR', + testo: 'Taranto', + }, + children: [], + }, + ], + }); +}; + inputPanel.valueChangeCb = inputPanelCallback; +inputPanel.optionsHandler = optionsHandlerCallback; +inputPanel.submitCb = (e) => console.log(e); diff --git a/packages/ketchup/src/assets/planner-example-5.js b/packages/ketchup/src/assets/planner-example-5.js index 7e17d8c6a5..8e93fb252c 100644 --- a/packages/ketchup/src/assets/planner-example-5.js +++ b/packages/ketchup/src/assets/planner-example-5.js @@ -9,6 +9,14 @@ document.addEventListener('kup-button-click', () => { comp.remove(); }); +document.addEventListener('kup-planner-datechange', (e) => { + console.log(e) +}); + +document.addEventListener('kup-planner-phasedrop', (e) => { + console.log(e) +}); + const props = { customStyle: '', data: { @@ -1482,11 +1490,11 @@ const props = { }, isEditable: false, obj: { - k: '20991231', + k: '20241231', p: '*YYMD', t: 'D8', }, - value: '2099-12-31', + value: '2024-12-31', }, DATORD: { @@ -1498,11 +1506,11 @@ const props = { }, isEditable: false, obj: { - k: '20991231', + k: '20241231', p: '*YYMD', t: 'D8', }, - value: '2099-12-31', + value: '2024-12-31', }, DATINZ: { @@ -1514,11 +1522,11 @@ const props = { }, isEditable: false, obj: { - k: '20991231', + k: '20241231', p: '*YYMD', t: 'D8', }, - value: '2099-12-31', + value: '2024-12-31', }, 'R§COMM': { @@ -1602,7 +1610,7 @@ const props = { phaseNameCol: 'DESFAS', phasePrevDates: ['DATINZ', 'DATFPO'], readOnly: false, - showSecondaryDates: true, + showSecondaryDates: false, taskColumns: ['R§COMM', 'R§CDCL', 'DATINZ', 'DATPRE'], taskDates: ['DATINZ', 'DATPRE'], taskHeight: 400, @@ -1610,6 +1618,10 @@ const props = { taskNameCol: 'R§COMM', taskPrevDates: ['INZORD', 'DATORD'], titleMess: '', + detailHours: ['INITHHMM', 'ENDHHMM'], + phaseHours: ['INITHHMMSS', 'ENDHHMMSS'], + taskHours: ['INITHHMM', 'ENDHHMM'], + scrollableTaskList: true }; if (props) { diff --git a/packages/ketchup/src/assets/planner-example-6.js b/packages/ketchup/src/assets/planner-example-6.js index c770344ccf..4807b96cfd 100644 --- a/packages/ketchup/src/assets/planner-example-6.js +++ b/packages/ketchup/src/assets/planner-example-6.js @@ -396,6 +396,9 @@ const props = { detailHours: ['INITHHMM', 'ENDHHMM'], phaseHours: ['INITHHMMSS', 'ENDHHMMSS'], taskHours: ['INITHHMM', 'ENDHHMM'], + detailPrevHours: ['INPRHHMM', 'ENPRHHMM'], + phasePrevHours: ['INPRHHMMSS', 'ENPRHHMMSS'], + taskPrevHours: ['INPRHHMM', 'ENPRHHMM'], scrollableTaskList: true, }; diff --git a/packages/ketchup/src/assets/planner.js b/packages/ketchup/src/assets/planner.js index 0290dc26d2..9c6e187d66 100644 --- a/packages/ketchup/src/assets/planner.js +++ b/packages/ketchup/src/assets/planner.js @@ -529,12 +529,12 @@ const props = { }, isEditable: false, obj: { - k: 'MAC.FMRSI-31-150-CNC', + k: 'MAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNC', p: '', t: '', }, - value: 'MAC.FMRSI-31-150-CNC', - displayedValue: 'MAC.FMRSI-31-150-CNC', + value: 'MAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNC', + displayedValue: 'MAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNCMAC.FMRSI-31-150-CNC', }, 'R£CDCL': { data: { @@ -2780,6 +2780,7 @@ const props = { taskNameCol: 'R£COMM', taskPrevDates: [], titleMess: '', + scrollableTaskList: true }; if (props) { diff --git a/packages/ketchup/src/components.d.ts b/packages/ketchup/src/components.d.ts index e8a71d8de5..1d3501a0f2 100644 --- a/packages/ketchup/src/components.d.ts +++ b/packages/ketchup/src/components.d.ts @@ -43,7 +43,7 @@ import { FImageData } from "./f-components/f-image/f-image-declarations"; import { KupImageClickEventPayload } from "./components/kup-image/kup-image-declarations"; import { KupImageListDataNode, KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; import { KupTreeColumnMenuEventPayload, KupTreeColumnRemoveEventPayload, KupTreeContextMenuEventPayload, KupTreeDynamicMassExpansionEventPayload, KupTreeExpansionMode, KupTreeNode, KupTreeNodeButtonClickEventPayload, KupTreeNodeCollapseEventPayload, KupTreeNodeExpandEventPayload, KupTreeNodeSelectedEventPayload, TreeNodePath } from "./components/kup-tree/kup-tree-declarations"; -import { InputPanelEventsCallback, KupInputPanelData } from "./components/kup-input-panel/kup-input-panel-declarations"; +import { InputPanelOptionsHandler, KupInputPanelData, KupInputPanelSubmit } from "./components/kup-input-panel/kup-input-panel-declarations"; import { KupLazyRender } from "./components/kup-lazy/kup-lazy-declarations"; import { KupNavBarStyling } from "./components/kup-nav-bar/kup-nav-bar-declarations"; import { KupNumericPickerEventPayload } from "./components/kup-numeric-picker/kup-numeric-picker-declarations"; @@ -93,7 +93,7 @@ export { FImageData } from "./f-components/f-image/f-image-declarations"; export { KupImageClickEventPayload } from "./components/kup-image/kup-image-declarations"; export { KupImageListDataNode, KupImageListEventPayload } from "./components/kup-image-list/kup-image-list-declarations"; export { KupTreeColumnMenuEventPayload, KupTreeColumnRemoveEventPayload, KupTreeContextMenuEventPayload, KupTreeDynamicMassExpansionEventPayload, KupTreeExpansionMode, KupTreeNode, KupTreeNodeButtonClickEventPayload, KupTreeNodeCollapseEventPayload, KupTreeNodeExpandEventPayload, KupTreeNodeSelectedEventPayload, TreeNodePath } from "./components/kup-tree/kup-tree-declarations"; -export { InputPanelEventsCallback, KupInputPanelData } from "./components/kup-input-panel/kup-input-panel-declarations"; +export { InputPanelOptionsHandler, KupInputPanelData, KupInputPanelSubmit } from "./components/kup-input-panel/kup-input-panel-declarations"; export { KupLazyRender } from "./components/kup-lazy/kup-lazy-declarations"; export { KupNavBarStyling } from "./components/kup-nav-bar/kup-nav-bar-declarations"; export { KupNumericPickerEventPayload } from "./components/kup-numeric-picker/kup-numeric-picker-declarations"; @@ -1167,9 +1167,12 @@ export namespace Components { "onclickTaskList": (id: string) => void; "oncontextmenuTaskList": (event: MouseEvent, id: string) => void; "ondblclickTaskList": (id: string) => void; + "ontaskListScrollWidth": (width: number) => void; "rowHeight": number; "rowWidth": string; + "scrollableTaskList": boolean; "setSelectedTask": (taskId: string) => void; + "taskListScrollX": number; "tasks": KupPlannerTask[]; } interface KupDashboard { @@ -2098,6 +2101,7 @@ export namespace Components { "label": string; "listCellWidth": KupPlannerGanttProps['listCellWidth']; "locale": KupPlannerGanttProps['locale']; + "phaseDrop": KupPlannerGanttProps['phaseDrop']; "preStepsCount": KupPlannerGanttProps['preStepsCount']; "progressChange": KupPlannerGanttProps['progressChange']; "projectBackgroundColor": KupPlannerGanttProps['projectBackgroundColor']; @@ -2115,6 +2119,7 @@ export namespace Components { "rtl": KupPlannerGanttProps['rtl']; "scrollXChange": KupPlannerGanttProps['scrollXChange']; "scrollYChange": KupPlannerGanttProps['scrollYChange']; + "scrollableTaskList"?: boolean; "select": KupPlannerGanttProps['select']; "setDoubleView"?: (checked: boolean) => void; "showSecondaryDates": KupPlannerGanttProps['showSecondaryDates']; @@ -2290,6 +2295,8 @@ export namespace Components { "ganttEvent": KupPlannerTaskGanttContentProps['ganttEvent']; "gridProps": KupPlannerTaskGanttProps['gridProps']; "hideLabel"?: KupPlannerTaskGanttContentProps['hideLabel']; + "phaseDragScroll": (scrollY: number) => void; + "phaseDrop": KupPlannerEventOption['phaseDrop']; "progressChange": KupPlannerEventOption['progressChange']; "projection"?: KupPlannerTaskGanttContentProps['projection']; "readOnly": KupPlannerTaskGanttContentProps['readOnly']; @@ -2306,9 +2313,14 @@ export namespace Components { } interface KupHorizontalScroll { "horizontalScroll": (event: UIEvent) => void; + "horizontalTaskListScroll": (event: UIEvent) => void; + "listCellWidth": string; "rtl": boolean; "scrollNumber": number; + "scrollableTaskList": boolean; "svgWidth": number; + "taskListScrollNumber": number; + "taskListScrollWidth": number; "taskListTrueRef": HTMLKupTaskListElement; "taskListWidth": number; } @@ -2407,7 +2419,7 @@ export namespace Components { interface KupImageList { /** * Number of columns to display in the grid layout. - * @default 4 + * @default null */ "columns": number; /** @@ -2471,16 +2483,16 @@ export namespace Components { * @returns List of props as object, each key will be a prop. */ "getProps": (descriptions?: boolean) => Promise; - /** - * Sets the callbacks functions on ketchup events - * @default [] - */ - "handleEventsCallbacks": InputPanelEventsCallback[]; /** * Creates a hidden submit button in order to submit the form with enter. * @default false */ "hiddenSubmitButton": boolean; + /** + * Sets the callback function on loading options via FUN + * @default [] + */ + "optionsHandler": InputPanelOptionsHandler; /** * This method is used to trigger a new render of the component. */ @@ -2494,7 +2506,7 @@ export namespace Components { * Sets the callback function on submit form * @default null */ - "submitCb": (e: SubmitEvent) => unknown; + "submitCb": (e: KupInputPanelSubmit) => unknown; } interface KupLazy { /** @@ -2880,6 +2892,11 @@ export namespace Components { * @default null */ "detailHeight": number; + /** + * Columns containing detail hour duration, from (firstDate) to (secondDate) + * @default null + */ + "detailHours": string[]; /** * Column containing icon name to show, for detail * @default null @@ -2910,6 +2927,11 @@ export namespace Components { * @default null */ "detailPrevDates": string[]; + /** + * Columns containing forecast detail duration, from (firstHour) to (secondHour) + * @default null + */ + "detailPrevHours": string[]; /** * Used to retrieve component's props values. * @param descriptions - When provided and true, the result will be the list of props with their description. @@ -2951,6 +2973,11 @@ export namespace Components { * @default null */ "phaseDates": string[]; + /** + * Columns containing phase hour duration, from (firstDate) to (secondDate) + * @default null + */ + "phaseHours": string[]; /** * Column containing icon name to show, for phase * @default null @@ -2971,6 +2998,11 @@ export namespace Components { * @default null */ "phasePrevDates": string[]; + /** + * Columns containing forecast phase duration, from (firstHour) to (secondHour) + * @default null + */ + "phasePrevHours": string[]; /** * When true, the two gantts are not interactable. * @default false @@ -2980,6 +3012,11 @@ export namespace Components { * This method is used to trigger a new render of the component. */ "refresh": () => Promise; + /** + * Sets the scroll bar for task list. + * @default false + */ + "scrollableTaskList": boolean; /** * Sets the filter for secondary gantt. * @default undefined @@ -3017,6 +3054,11 @@ export namespace Components { * @default null */ "taskHeight": number; + /** + * Columns containing task hours duration, from (firstDate) to (secondDate) + * @default null + */ + "taskHours": string[]; /** * Column containing icon name to show, for task * @default null @@ -3047,6 +3089,11 @@ export namespace Components { * @default null */ "taskPrevDates": string[]; + /** + * Columns containing forecast task duration, from (firstHour) to (secondHour) + * @default null + */ + "taskPrevHours": string[]; /** * Message displayed on top * @default null @@ -3470,6 +3517,7 @@ export namespace Components { "calendarProps": KupPlannerTaskGanttProps['calendarProps']; "ganttHeight": KupPlannerTaskGanttProps['ganttHeight']; "gridProps": KupPlannerTaskGanttProps['gridProps']; + "phaseDragScroll": (scrollY: number) => void; "scrollX": KupPlannerTaskGanttProps['scrollX']; "scrollY": KupPlannerTaskGanttProps['scrollY']; "taskGanttRef": KupPlannerTaskGanttProps['taskGanttRef']; @@ -3498,13 +3546,17 @@ export namespace Components { "horizontalContainerClass"?: string; "label": string; "locale": string; + "ontaskListScrollWidth": (width: number) => void; "rowHeight": number; "rowWidth": string; "scrollY": number; + "scrollableTaskList"?: boolean; "selectedTask": KupPlannerBarTask | undefined; "setDoubleView"?: (checked: boolean) => void; "setSelectedTask": KupPlannerTaskListProps['setSelectedTask']; + "taskListScrollX": number; "tasks": KupPlannerTask[]; + "updateTaskListScrollX": boolean; } interface KupTaskListHeader { "fontFamily": string; @@ -4868,6 +4920,7 @@ declare global { "kup-planner-click": KupPlannerEventPayload; "kup-planner-dblclick": KupPlannerEventPayload; "kup-planner-datechange": KupPlannerEventPayload; + "kup-planner-phasedrop": KupPlannerEventPayload; "kup-planner-ready": KupPlannerEventPayload; "kup-planner-contextmenu": KupPlannerClickEventPayload; "kup-planner-didunload": KupPlannerUnloadEventPayload; @@ -6103,9 +6156,12 @@ declare namespace LocalJSX { "onclickTaskList"?: (id: string) => void; "oncontextmenuTaskList"?: (event: MouseEvent, id: string) => void; "ondblclickTaskList"?: (id: string) => void; + "ontaskListScrollWidth"?: (width: number) => void; "rowHeight"?: number; "rowWidth"?: string; + "scrollableTaskList"?: boolean; "setSelectedTask"?: (taskId: string) => void; + "taskListScrollX"?: number; "tasks"?: KupPlannerTask[]; } interface KupDashboard { @@ -6856,6 +6912,7 @@ declare namespace LocalJSX { "label"?: string; "listCellWidth"?: KupPlannerGanttProps['listCellWidth']; "locale"?: KupPlannerGanttProps['locale']; + "phaseDrop"?: KupPlannerGanttProps['phaseDrop']; "preStepsCount"?: KupPlannerGanttProps['preStepsCount']; "progressChange"?: KupPlannerGanttProps['progressChange']; "projectBackgroundColor"?: KupPlannerGanttProps['projectBackgroundColor']; @@ -6869,6 +6926,7 @@ declare namespace LocalJSX { "rtl"?: KupPlannerGanttProps['rtl']; "scrollXChange"?: KupPlannerGanttProps['scrollXChange']; "scrollYChange"?: KupPlannerGanttProps['scrollYChange']; + "scrollableTaskList"?: boolean; "select"?: KupPlannerGanttProps['select']; "setDoubleView"?: (checked: boolean) => void; "showSecondaryDates"?: KupPlannerGanttProps['showSecondaryDates']; @@ -7014,6 +7072,8 @@ declare namespace LocalJSX { "ganttEvent"?: KupPlannerTaskGanttContentProps['ganttEvent']; "gridProps"?: KupPlannerTaskGanttProps['gridProps']; "hideLabel"?: KupPlannerTaskGanttContentProps['hideLabel']; + "phaseDragScroll"?: (scrollY: number) => void; + "phaseDrop"?: KupPlannerEventOption['phaseDrop']; "progressChange"?: KupPlannerEventOption['progressChange']; "projection"?: KupPlannerTaskGanttContentProps['projection']; "readOnly"?: KupPlannerTaskGanttContentProps['readOnly']; @@ -7030,9 +7090,14 @@ declare namespace LocalJSX { } interface KupHorizontalScroll { "horizontalScroll"?: (event: UIEvent) => void; + "horizontalTaskListScroll"?: (event: UIEvent) => void; + "listCellWidth"?: string; "rtl"?: boolean; "scrollNumber"?: number; + "scrollableTaskList"?: boolean; "svgWidth"?: number; + "taskListScrollNumber"?: number; + "taskListScrollWidth"?: number; "taskListTrueRef"?: HTMLKupTaskListElement; "taskListWidth"?: number; } @@ -7105,7 +7170,7 @@ declare namespace LocalJSX { interface KupImageList { /** * Number of columns to display in the grid layout. - * @default 4 + * @default null */ "columns"?: number; /** @@ -7151,11 +7216,6 @@ declare namespace LocalJSX { * @default null */ "data"?: KupInputPanelData; - /** - * Sets the callbacks functions on ketchup events - * @default [] - */ - "handleEventsCallbacks"?: InputPanelEventsCallback[]; /** * Creates a hidden submit button in order to submit the form with enter. * @default false @@ -7165,11 +7225,16 @@ declare namespace LocalJSX { * When component load is complete */ "onKup-input-panel-ready"?: (event: KupInputPanelCustomEvent) => void; + /** + * Sets the callback function on loading options via FUN + * @default [] + */ + "optionsHandler"?: InputPanelOptionsHandler; /** * Sets the callback function on submit form * @default null */ - "submitCb"?: (e: SubmitEvent) => unknown; + "submitCb"?: (e: KupInputPanelSubmit) => unknown; } interface KupLazy { /** @@ -7444,6 +7509,11 @@ declare namespace LocalJSX { * @default null */ "detailHeight"?: number; + /** + * Columns containing detail hour duration, from (firstDate) to (secondDate) + * @default null + */ + "detailHours"?: string[]; /** * Column containing icon name to show, for detail * @default null @@ -7474,6 +7544,11 @@ declare namespace LocalJSX { * @default null */ "detailPrevDates"?: string[]; + /** + * Columns containing forecast detail duration, from (firstHour) to (secondHour) + * @default null + */ + "detailPrevHours"?: string[]; /** * Total size of the cells inside to the left box, near the gantt * @default '300px' @@ -7500,6 +7575,7 @@ declare namespace LocalJSX { * When component unload is complete */ "onKup-planner-didunload"?: (event: KupPlannerCustomEvent) => void; + "onKup-planner-phasedrop"?: (event: KupPlannerCustomEvent) => void; "onKup-planner-ready"?: (event: KupPlannerCustomEvent) => void; /** * Column containing the name of the parent phases @@ -7521,6 +7597,11 @@ declare namespace LocalJSX { * @default null */ "phaseDates"?: string[]; + /** + * Columns containing phase hour duration, from (firstDate) to (secondDate) + * @default null + */ + "phaseHours"?: string[]; /** * Column containing icon name to show, for phase * @default null @@ -7541,11 +7622,21 @@ declare namespace LocalJSX { * @default null */ "phasePrevDates"?: string[]; + /** + * Columns containing forecast phase duration, from (firstHour) to (secondHour) + * @default null + */ + "phasePrevHours"?: string[]; /** * When true, the two gantts are not interactable. * @default false */ "readOnly"?: boolean; + /** + * Sets the scroll bar for task list. + * @default false + */ + "scrollableTaskList"?: boolean; /** * Sets the filter for secondary gantt. * @default undefined @@ -7578,6 +7669,11 @@ declare namespace LocalJSX { * @default null */ "taskHeight"?: number; + /** + * Columns containing task hours duration, from (firstDate) to (secondDate) + * @default null + */ + "taskHours"?: string[]; /** * Column containing icon name to show, for task * @default null @@ -7608,6 +7704,11 @@ declare namespace LocalJSX { * @default null */ "taskPrevDates"?: string[]; + /** + * Columns containing forecast task duration, from (firstHour) to (secondHour) + * @default null + */ + "taskPrevHours"?: string[]; /** * Message displayed on top * @default null @@ -7950,6 +8051,7 @@ declare namespace LocalJSX { "calendarProps"?: KupPlannerTaskGanttProps['calendarProps']; "ganttHeight"?: KupPlannerTaskGanttProps['ganttHeight']; "gridProps"?: KupPlannerTaskGanttProps['gridProps']; + "phaseDragScroll"?: (scrollY: number) => void; "scrollX"?: KupPlannerTaskGanttProps['scrollX']; "scrollY"?: KupPlannerTaskGanttProps['scrollY']; "taskGanttRef"?: KupPlannerTaskGanttProps['taskGanttRef']; @@ -7978,13 +8080,17 @@ declare namespace LocalJSX { "horizontalContainerClass"?: string; "label"?: string; "locale"?: string; + "ontaskListScrollWidth"?: (width: number) => void; "rowHeight"?: number; "rowWidth"?: string; "scrollY"?: number; + "scrollableTaskList"?: boolean; "selectedTask"?: KupPlannerBarTask | undefined; "setDoubleView"?: (checked: boolean) => void; "setSelectedTask"?: KupPlannerTaskListProps['setSelectedTask']; + "taskListScrollX"?: number; "tasks"?: KupPlannerTask[]; + "updateTaskListScrollX"?: boolean; } interface KupTaskListHeader { "fontFamily"?: string; diff --git a/packages/ketchup/src/components/kup-badge/styles/kup-badge-classes.scss b/packages/ketchup/src/components/kup-badge/styles/kup-badge-classes.scss index 5ea3c87825..879b188ad4 100644 --- a/packages/ketchup/src/components/kup-badge/styles/kup-badge-classes.scss +++ b/packages/ketchup/src/components/kup-badge/styles/kup-badge-classes.scss @@ -7,7 +7,7 @@ right: 0; bottom: unset; left: unset; - transform: translate(50%, -50%); + transform: translate(-15%, 15%); } :host(.#{$kup-class-bottom-right}) { @@ -15,7 +15,7 @@ right: 0; bottom: 0; left: unset; - transform: translate(50%, 50%); + transform: translate(-15%, -15%); } :host(.#{$kup-class-bottom-left}) { @@ -23,7 +23,7 @@ right: unset; bottom: 0; left: 0; - transform: translate(-50%, 50%); + transform: translate(15%, -15%); } :host(.#{$kup-class-danger}) { diff --git a/packages/ketchup/src/components/kup-badge/styles/kup-badge-main.scss b/packages/ketchup/src/components/kup-badge/styles/kup-badge-main.scss index d99a5233aa..aff7c60884 100644 --- a/packages/ketchup/src/components/kup-badge/styles/kup-badge-main.scss +++ b/packages/ketchup/src/components/kup-badge/styles/kup-badge-main.scss @@ -29,7 +29,7 @@ position: absolute; top: 0; left: 0; - transform: translate(-50%, -50%); + transform: translate(15%, 15%); } #kup-component { diff --git a/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx b/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx index b442e7851b..f3f836311e 100644 --- a/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx +++ b/packages/ketchup/src/components/kup-image-list/kup-image-list.tsx @@ -42,6 +42,7 @@ import { import { KupStore } from '../kup-state/kup-store'; import { KupImageListState } from './kup-image-list-state'; import { TreeNodePath } from '../kup-tree/kup-tree-declarations'; +import { KupBadge } from '../kup-badge/kup-badge'; import { KupPointerEventTypes } from '../../managers/kup-interact/kup-interact-declarations'; @Component({ @@ -107,9 +108,9 @@ export class KupImageList { /*-------------------------------------------------*/ /** * Number of columns to display in the grid layout. - * @default 4 + * @default null */ - @Prop() columns: number = 4; + @Prop() columns: number = null; /** * Custom style of the component. * @default "" @@ -258,8 +259,15 @@ export class KupImageList { wrapperClass: 'image-list__image', badgeData: node.badgeData, }; + const image = ; const label =
{node.value}
; + + const hasExternalResource = + props.resource.indexOf('.') > -1 || + props.resource.indexOf('/') > -1 || + props.resource.indexOf('\\') > -1; + return ( -
+
+ {!hasExternalResource && ( + + )} {image} {label}
@@ -425,6 +444,11 @@ export class KupImageList { const holdCb = (e: PointerEvent) => { if (e.pointerType === 'pen' || e.pointerType === 'touch') { this.#hold = true; + this.kupContextMenu.emit({ + comp: this, + id: this.rootElement.id, + details: this.#contextMenuHandler(e), + }); } }; this.#kupManager.interact.on( @@ -438,11 +462,6 @@ export class KupImageList { KupPointerEventTypes.DOUBLETAP, doubletapCb ); - this.#kupManager.interact.on( - this.#el, - KupPointerEventTypes.HOLD, - holdCb - ); } /*-------------------------------------------------*/ diff --git a/packages/ketchup/src/components/kup-image-list/readme.md b/packages/ketchup/src/components/kup-image-list/readme.md index c2448f711c..1a9c4747f6 100644 --- a/packages/ketchup/src/components/kup-image-list/readme.md +++ b/packages/ketchup/src/components/kup-image-list/readme.md @@ -9,7 +9,7 @@ | Property | Attribute | Description | Type | Default | | -------------- | -------------- | ---------------------------------------------------------------- | ------------------------ | ----------- | -| `columns` | `columns` | Number of columns to display in the grid layout. | `number` | `4` | +| `columns` | `columns` | Number of columns to display in the grid layout. | `number` | `null` | | `customStyle` | `custom-style` | Custom style of the component. | `string` | `''` | | `data` | -- | Actual data of the component. | `KupImageListDataNode[]` | `[]` | | `ripple` | `ripple` | When enabled displays Material's ripple effect on clicked items. | `boolean` | `true` | diff --git a/packages/ketchup/src/components/kup-image-list/styles/kup-image-list-main.scss b/packages/ketchup/src/components/kup-image-list/styles/kup-image-list-main.scss index c8ef6b7b95..8d6fd0e507 100644 --- a/packages/ketchup/src/components/kup-image-list/styles/kup-image-list-main.scss +++ b/packages/ketchup/src/components/kup-image-list/styles/kup-image-list-main.scss @@ -20,7 +20,7 @@ transparent ); --kup_imagelist_columns: var(--kup-imagelist-columns, 4); - --kup_imagelist_grid_gap: var(--kup-imagelist-grid-gap, 0.5em); + --kup_imagelist_grid_gap: var(--kup-imagelist-grid-gap, var(--kup-space-03)); --kup_imagelist_image_min_height: var( --kup-imagelist-image-min-height, var(--kup-space-09) @@ -128,8 +128,26 @@ .f-cell { height: 100%; width: 100%; + .f-cell__content{ + height: 100%; + } .f-cell__content .image-list__wrapper { - padding: var(--kup-space-03) var(--kup-space-02); + display: flex; + flex-direction: column; + justify-content: space-between; + box-sizing: border-box; + position: relative; + } + .f-cell__content .image-list__wrapper.images{ + height: 100%; + justify-content: flex-end; + + .f-image{ + position: unset; + overflow: auto; + height: 100%; + display: flex; + } } } @@ -146,10 +164,17 @@ } &__image.f-image { - margin-bottom: var(--kup-space-03); + position: absolute; + padding: var(--kup-space-03); + padding-bottom: 0px; + box-sizing: border-box; + width: 100%; + height: calc(100% - 16px - var(--kup-space-03)*2); + overflow: hidden; + .f-image__icon { - min-height: var(--kup_imagelist_image_min_height); + mask-size: 100%!important; } } @@ -158,6 +183,22 @@ text-align: center; text-overflow: ellipsis; white-space: nowrap; + padding: var(--kup-space-03); @include kup-label-01; } } + + +@media screen and (min-width: 678px) { + :host { + --kup_imagelist_columns: var(--kup-imagelist-columns, 8); + } + + .image-list { + grid-template-columns: repeat( + var(--kup_imagelist_columns, 8), + minmax(0px, 1fr) + ); + grid-gap: var(--kup-space-05); + } +} diff --git a/packages/ketchup/src/components/kup-input-panel/kup-input-panel-declarations.ts b/packages/ketchup/src/components/kup-input-panel/kup-input-panel-declarations.ts index de898df515..22cd63a37d 100644 --- a/packages/ketchup/src/components/kup-input-panel/kup-input-panel-declarations.ts +++ b/packages/ketchup/src/components/kup-input-panel/kup-input-panel-declarations.ts @@ -1,8 +1,14 @@ +import { GenericObject } from '../../components'; import { KupDataCell, KupDataColumn, } from '../../managers/kup-data/kup-data-declarations'; +export interface KupInputPanelSubmit { + after: KupInputPanelData; + before: KupInputPanelData; +} + export interface KupInputPanelData { columns?: KupDataColumn[]; rows?: KupInputPanelRow[]; @@ -24,7 +30,7 @@ export interface KupInputPanelRowCells { } export interface KupInputPanelCell extends KupDataCell { - options?: KupInputPanelCellOptions[]; + options?: GenericObject | GenericObject[]; editable?: boolean; mandatory?: boolean; fun?: string; @@ -48,23 +54,27 @@ export interface KupInputPanelLayoutSection { horizontal?: boolean; gridCols?: number; gridRows?: number; + // Gap is in rem gap?: number; } export interface KupInputPanelLayoutField { id: string; + // Span is referred to start colSpan?: number; colStart?: number; colEnd?: number; + // Span is referred to start rowSpan?: number; rowStart?: number; rowEnd?: number; } export type DataAdapterFn = ( - options: KupInputPanelCellOptions[], + options: GenericObject, fieldLabel: string, - currentValue: string + currentValue: string, + fun?: string ) => Object; export type InputPanelCells = { @@ -80,15 +90,12 @@ export type InputPanelEvent = { }; }; -export type InputPanelEventsCallback = { - eventName: string; - eventCallback: (e: InputPanelEvent) => unknown; -}; +export type InputPanelOptionsHandler = (fun: string) => Promise; export enum KupInputPanelProps { customStyle = 'Custom style of the component.', data = 'Actual data of the input panel.', hiddenSubmitButton = 'Creates a hidden submit button in order to submit the form with enter.', submitCb = 'Sets the callback function on submit form', - valueChangeCb = 'Sets the callback function on value change event', + optionsHandler = 'Sets the callback function to recieve options', } diff --git a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.e2e.ts b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.e2e.ts index e407b41532..e328a24cbe 100644 --- a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.e2e.ts +++ b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.e2e.ts @@ -110,24 +110,30 @@ describe('kup-input-panel', () => { editable: true, mandatory: true, options: [ - 'Florence', - 'Venice', - 'Rome', - 'Madrid', - 'Barcelona', - 'Seville', - 'Berlin', - 'Munich', - 'Hamburg', - 'Paris', - 'Marseille', - 'Lyon', - 'Lisbon', - 'Porto', - 'Faro', - 'London', - 'Manchester', - 'Liverpool', + { + id: 'FLO', + label: 'Florence', + }, + { + id: 'VEN', + label: 'Venice', + }, + { + id: 'ROM', + label: 'Rome', + }, + { + id: 'MAD', + label: 'Madrid', + }, + { + id: 'BAR', + label: 'Barcelona', + }, + { + id: 'SEV', + label: 'Seville', + }, ], shape: 'ACP', }, @@ -176,7 +182,7 @@ describe('kup-input-panel', () => { const listOptions = await page.findAll('kup-list >>> ul.list li'); expect(listOptions).not.toBeNull(); - expect(listOptions).toHaveLength(2); + expect(listOptions).toHaveLength(1); const firstOptionValue = await listOptions[0].find('span'); expect(firstOptionValue).toEqualText('Rome'); @@ -207,12 +213,30 @@ describe('kup-input-panel', () => { NAT: { value: '', options: [ - 'Italy', - 'Spain', - 'Germany', - 'France', - 'Portugal', - 'England', + { + id: 'ITA', + label: 'Italy', + }, + { + id: 'SPA', + label: 'Spain', + }, + { + id: 'GER', + label: 'Germany', + }, + { + id: 'FRA', + label: 'France', + }, + { + id: 'POR', + label: 'Portugal', + }, + { + id: 'ENG', + label: 'England', + }, ], editable: true, shape: 'CMB', @@ -345,7 +369,24 @@ describe('kup-input-panel', () => { cells: { RAD: { value: '1', - options: ['1', '2', '3', '4'], + options: [ + { + id: '1', + label: 'One', + }, + { + id: '2', + label: 'Two', + }, + { + id: '3', + label: 'Three', + }, + { + id: '4', + label: 'Four', + }, + ], editable: true, shape: 'RAD', }, @@ -375,13 +416,13 @@ describe('kup-input-panel', () => { for (const [i, radioButton] of radioButtons.entries()) { const label = await radioButton.find('label'); expect(label).not.toBeNull(); - expect(label).toEqualText(radioOptions[i]); + expect(label).toEqualText(radioOptions[i].label); const input = await radioButton.find('input'); expect(input).not.toBeNull(); const value = await input.getProperty('value'); - expect(value).toBe(radioOptions[i]); + expect(value).toBe(radioOptions[i].id); if (data.rows[0].cells.RAD.value === value) { const radioButtonCircle = await radioButton.find('div.radio'); diff --git a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.scss b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.scss index 1611ec6300..02ea026dae 100644 --- a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.scss +++ b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.scss @@ -1,6 +1,49 @@ -.input-panel { - .f-cell .f-checkbox .checkbox .checkbox__native-control { - height: 40px; - width: 40px; +/** +* @prop --kup-input-panel-background-color: Sets background of the component. +* @prop --kup-input-panel-color: Sets text color of the component. +* @prop --kup-input-panel-font-family: Sets font family of the component. +* @prop --kup-input-panel-font-size: Sets font size of the component. +* @prop --kup-input-panel-label-alignment: Sets the text alignment of labels. +* @prop --kup-input-panel-label-width: Sets the width of labels. +* @prop --kup-input-panel-padding: Sets the padding of the input panel. +*/ + +:host { + --kup_input_panel_background_color: var(--kup-input-panel-background-color, + var(--kup-background-color)); + --kup_input_panel_color: var(--kup-input-panel-color, var(--kup-text-color)); + --kup_input_panel_font_family: var(--kup-input-panel-font-family, var(--kup-font-family)); + --kup_input_panel_font_size: var(--kup-input-panel-font-size, var(--kup-font-size)); + --kup_input_panel_label_alignment: var(--kup-input-panel-label-alignment); + --kup_input_panel_label_width: var(--kup-input-panel-label-width); + --kup_input_panel_padding: var(--kup-input-panel-padding, 1em 0); + + .input-panel { + background: var(--kup_input_panel_background_color); + color: var(--kup_input_panel_color); + display: flex; + flex-grow: 1; + overflow: auto; + padding: var(--kup_input_panel_padding); + position: relative; + + &--column { + flex-direction: column; + } + + &__section { + display: grid; + } + + &__horizontal-section { + display: inline-grid; + } + + .f-cell .f-checkbox .checkbox .checkbox__native-control { + height: 40px; + width: 40px; + } + + } } \ No newline at end of file diff --git a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.tsx b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.tsx index caf800fd68..4fbfd66538 100644 --- a/packages/ketchup/src/components/kup-input-panel/kup-input-panel.tsx +++ b/packages/ketchup/src/components/kup-input-panel/kup-input-panel.tsx @@ -4,6 +4,7 @@ import { Event, EventEmitter, Host, + Listen, Method, Prop, State, @@ -12,39 +13,40 @@ import { forceUpdate, h, } from '@stencil/core'; +import { KupAutocompleteEventPayload, KupDataCell } from '../../components'; +import { FButton } from '../../f-components/f-button/f-button'; +import { FCell } from '../../f-components/f-cell/f-cell'; import { - DataAdapterFn, - InputPanelCells, - InputPanelEvent, - InputPanelEventsCallback, - KupInputPanelCell, - KupInputPanelCellOptions, - KupInputPanelColumn, - KupInputPanelData, - KupInputPanelProps, - KupInputPanelRow, -} from './kup-input-panel-declarations'; + FCellProps, + FCellTypes, +} from '../../f-components/f-cell/f-cell-declarations'; +import { FTextFieldMDC } from '../../f-components/f-text-field/f-text-field-mdc'; +import { KupLanguageGeneric } from '../../managers/kup-language/kup-language-declarations'; import { KupManager, kupManagerInstance, } from '../../managers/kup-manager/kup-manager'; +import { KupDom } from '../../managers/kup-manager/kup-manager-declarations'; import { GenericObject, KupComponent, KupEventPayload, } from '../../types/GenericTypes'; +import { getProps, setProps } from '../../utils/utils'; import { componentWrapperId } from '../../variables/GenericVariables'; -import { FButton } from '../../f-components/f-button/f-button'; -import { KupLanguageGeneric } from '../../managers/kup-language/kup-language-declarations'; import { - FCellProps, - FCellTypes, -} from '../../f-components/f-cell/f-cell-declarations'; -import { FTextFieldMDC } from '../../f-components/f-text-field/f-text-field-mdc'; -import { FCell } from '../../f-components/f-cell/f-cell'; -import { KupDom } from '../../managers/kup-manager/kup-manager-declarations'; -import { KupDataCell } from '../../components'; -import { getProps, setProps } from '../../utils/utils'; + DataAdapterFn, + InputPanelCells, + InputPanelOptionsHandler, + KupInputPanelCell, + KupInputPanelColumn, + KupInputPanelData, + KupInputPanelLayoutField, + KupInputPanelLayoutSection, + KupInputPanelProps, + KupInputPanelRow, + KupInputPanelSubmit, +} from './kup-input-panel-declarations'; const dom: KupDom = document.documentElement as KupDom; @Component({ @@ -86,13 +88,13 @@ export class KupInputPanel { * Sets the callback function on submit form * @default null */ - @Prop() submitCb: (e: SubmitEvent) => unknown = null; + @Prop() submitCb: (e: KupInputPanelSubmit) => unknown = null; /** - * Sets the callbacks functions on ketchup events + * Sets the callback function on loading options via FUN * @default [] */ - @Prop() handleEventsCallbacks: InputPanelEventsCallback[] = []; + @Prop() optionsHandler: InputPanelOptionsHandler = null; //#endregion //#region STATES @@ -113,6 +115,16 @@ export class KupInputPanel { /*-------------------------------------------------*/ #kupManager: KupManager = kupManagerInstance(); + + #optionsAdapterMap = new Map< + string, + (options: any, currentValue: string) => GenericObject[] + >([ + ['SmeupTree', this.#treeOptionsNodeAdapter.bind(this)], + ['SmeupTable', this.#tableOptionsAdapter.bind(this)], + ]); + + #originalData: KupInputPanelData = null; //#endregion //#region WATCHERS @@ -122,6 +134,9 @@ export class KupInputPanel { @Watch('data') onDataChanged() { + if (!this.#originalData) { + this.#originalData = structuredClone(this.data); + } this.#mapCells(this.data); } //#endregion @@ -180,17 +195,24 @@ export class KupInputPanel { /*-------------------------------------------------*/ #renderRow(inputPanelCell: InputPanelCells) { - // todo layout - const horizontal = inputPanelCell.row.layout?.horizontal || false; - - const rowContent: VNode[] = inputPanelCell.cells.map((cell) => - this.#renderCell(cell.cell, inputPanelCell.row, cell.column) - ); + const layout = inputPanelCell.row.layout; + const horizontal = layout?.horizontal || false; + + let rowContent: VNode[]; + + if (!layout?.sections?.length) { + rowContent = inputPanelCell.cells.map((cell) => + this.#renderCell(cell.cell, inputPanelCell.row, cell.column) + ); + } else { + rowContent = layout.sections.map((section) => + this.#renderSection(inputPanelCell, section) + ); + } const classObj = { - form: true, 'input-panel': true, - 'form--column': !horizontal, + 'input-panel--column': !horizontal, }; // We create a form for each row in data @@ -198,10 +220,16 @@ export class KupInputPanel {
{ + e.preventDefault(); + this.submitCb({ + before: { ...this.#originalData }, + after: this.#reverseMapCells(), + }); + }} > {rowContent} - {this.hiddenSubmitButton ? ( + {!this.hiddenSubmitButton ? ( ; } + #renderSection( + cells: InputPanelCells, + section: KupInputPanelLayoutSection + ) { + let content = []; + + if (section.sections?.length) { + content = section.sections.map((innerSection) => + this.#renderSection(cells, innerSection) + ); + } else if (section.content?.length) { + content = section.content.map((field) => + this.#renderField(cells, field) + ); + } + + const classObj = { + 'input-panel__section': !section.horizontal, + 'input-panel__horizontal-section': section.horizontal, + }; + + const styleObj: GenericObject = { + gap: section.gap ? `${section.gap}rem` : '', + 'grid-template-columns': section.gridCols + ? `repeat(${section.gridCols}, 1fr)` + : '', + 'grid-template-rows': section.gridRows + ? `repeat(${section.gridRows}, 1fr)` + : '', + }; + + if (cells.row?.layout?.horizontal) { + styleObj.maxWidth = section.dim; + } else { + styleObj.maxHeight = section.dim; + } + + return ( +
+ {content} +
+ ); + } + + #renderField(cells: InputPanelCells, field: KupInputPanelLayoutField) { + const fieldCell = cells.cells.find( + (cell) => cell.column.name === field.id + ); + + const colStart = field.colSpan + ? `span ${field.colSpan}` + : `${field.colStart}`; + + const colEnd = field.colEnd ? `${field.colEnd}` : ''; + + const rowStart = field.rowSpan + ? `span ${field.rowSpan}` + : `${field.rowStart}`; + + const rowEnd = field.rowEnd ? `${field.rowEnd}` : ''; + + const styleObj = { + 'grid-column-start': colStart, + 'grid-column-end': colEnd, + 'grid-row-start': rowStart, + 'grid-row-end': rowEnd, + }; + + return ( +
+ {this.#renderCell(fieldCell.cell, cells.row, fieldCell.column)} +
+ ); + } + #mapCells(data: KupInputPanelData) { const inpuPanelCells = data?.rows?.length ? data.rows.reduce((inpuPanelCells, row) => { const cells = data.columns .filter((column) => column.visible) .map((column) => { - const cell = row.cells[column.name]; + const cell = structuredClone(row.cells[column.name]); const mappedCell = { ...cell, data: { @@ -258,6 +361,48 @@ export class KupInputPanel { this.inputPanelCells = inpuPanelCells; } + #reverseMapCells(): KupInputPanelData { + return this.inputPanelCells.reduce( + (data, curr) => { + const updatedCells = Object.keys(curr.row.cells).reduce( + (cells, key) => { + const cellState = curr.cells.find( + (c) => c.column.name === key + ).cell; + + return { + ...cells, + [key]: { + ...curr.row.cells[key], + value: cellState.value, + obj: cellState.obj, + }, + }; + }, + {} + ); + + return { + columns: [ + ...data.columns, + ...curr.cells.map((cell) => cell.column), + ], + rows: [ + ...data.rows, + { + cells: updatedCells, + layout: curr.row.layout, + }, + ], + }; + }, + { + columns: [], + rows: [], + } + ); + } + #mapData(cell: KupInputPanelCell, col: KupInputPanelColumn) { const options = cell.options; const fieldLabel = col.title; @@ -265,20 +410,22 @@ export class KupInputPanel { const cellType = dom.ketchup.data.cell.getType(cell, cell.shape); const dataAdapterMap = new Map([ - [FCellTypes.AUTOCOMPLETE, this.#CMBandACPAdapter], - [FCellTypes.BUTTON_LIST, this.#BTNAdapter], - [FCellTypes.CHART, this.#GRAAdapter], - [FCellTypes.CHIP, this.#CHIAdapter], - [FCellTypes.CHECKBOX, this.#CHKAdapter], - [FCellTypes.COLOR_PICKER, this.#CLPAdapter], - [FCellTypes.COMBOBOX, this.#CMBandACPAdapter], - [FCellTypes.RADIO, this.#RADAdapter], - [FCellTypes.STRING, this.#ITXAdapter], + [FCellTypes.AUTOCOMPLETE, this.#CMBandACPAdapter.bind(this)], + [FCellTypes.BUTTON_LIST, this.#BTNAdapter.bind(this)], + [FCellTypes.CHART, this.#GRAAdapter.bind(this)], + [FCellTypes.CHIP, this.#CHIAdapter.bind(this)], + [FCellTypes.CHECKBOX, this.#CHKAdapter.bind(this)], + [FCellTypes.COLOR_PICKER, this.#CLPAdapter.bind(this)], + [FCellTypes.COMBOBOX, this.#CMBandACPAdapter.bind(this)], + [FCellTypes.RADIO, this.#RADAdapter.bind(this)], + [FCellTypes.STRING, this.#ITXAdapter.bind(this)], ]); const adapter = dataAdapterMap.get(cellType); - return adapter ? adapter(options, fieldLabel, currentValue) : null; + return adapter + ? adapter(options, fieldLabel, currentValue, cell.fun) + : null; } #slotData(cell: KupInputPanelCell, col: KupInputPanelColumn) { @@ -300,7 +447,7 @@ export class KupInputPanel { } #CHIAdapter( - options: KupInputPanelCellOptions[], + options: GenericObject, _fieldLabel: string, currentValue: string ) { @@ -331,7 +478,7 @@ export class KupInputPanel { } #BTNAdapter( - _options: KupInputPanelCellOptions[], + _options: GenericObject, _fieldLabel: string, _currentValue: string ) { @@ -347,11 +494,12 @@ export class KupInputPanel { } #CMBandACPAdapter( - options: KupInputPanelCellOptions[], + rawOptions: GenericObject, fieldLabel: string, - currentValue: string + currentValue: string, + fun: string ) { - return { + const configCMandACP = { data: { 'kup-text-field': { trailingIcon: true, @@ -360,21 +508,30 @@ export class KupInputPanel { }, 'kup-list': { showIcons: true, - data: options?.length - ? options.map((option) => ({ - value: option.label, - id: option.id, - selected: currentValue === option.id, - })) - : [], + data: [], }, }, label: fieldLabel, }; + + const options = fun ? this.optionsHandler(fun) : rawOptions; + + if (options instanceof Promise) { + options.then( + (data) => + (configCMandACP.data['kup-list'].data = + this.#optionsTreeComboAdapter(data, currentValue) ?? []) + ); + } else if (options) { + configCMandACP.data['kup-list'].data = + this.#optionsTreeComboAdapter(options, currentValue); + } + + return configCMandACP; } #CHKAdapter( - _options: KupInputPanelCellOptions[], + _options: GenericObject, fieldLabel: string, currentValue: string ) { @@ -385,7 +542,7 @@ export class KupInputPanel { } #CLPAdapter( - _options: KupInputPanelCellOptions[], + _options: GenericObject, fieldLabel: string, _currentValue: string ) { @@ -399,7 +556,7 @@ export class KupInputPanel { } #ITXAdapter( - _options: KupInputPanelCellOptions[], + _options: GenericObject, fieldLabel: string, _currentValue: string ) { @@ -407,7 +564,7 @@ export class KupInputPanel { } #RADAdapter( - options: KupInputPanelCellOptions[], + options: GenericObject, _fieldLabel: string, currentValue: string ) { @@ -420,6 +577,49 @@ export class KupInputPanel { }; } + #optionsTreeComboAdapter(options: any, currentValue: string) { + const adapter = this.#optionsAdapterMap.get(options.type); + + if (adapter) { + return adapter(options, currentValue); + } else { + return options.map((option) => ({ + value: option.label, + id: option.id, + selected: currentValue === option.id, + })); + } + } + + #treeOptionsNodeAdapter( + options: any, + currentValue: string + ): GenericObject[] { + return options.children.map((child) => ({ + id: child.content.codice, + value: child.content.testo, + selected: currentValue === child.content.codice, + children: child.children?.length + ? this.#treeOptionsNodeAdapter(child, currentValue) + : [], + })); + } + + #tableOptionsAdapter(options: any, currentValue: string): GenericObject[] { + return options.rows + .filter((row) => row.fields) + .map(({ fields }) => { + const keys = Object.keys(fields); + + return keys.map((key) => ({ + id: fields[key].smeupObject.codice, + value: fields[key].smeupObject.testo, + selected: currentValue === fields[key].smeupObject.codice, + })); + }) + .flat(); + } + //#endregion //#region LIFECYCLE HOOKS @@ -438,23 +638,23 @@ export class KupInputPanel { this.kupReady.emit({ comp: this, id: this.rootElement.id }); this.#kupManager.debug.logLoad(this, true); - this.handleEventsCallbacks.map((cbData) => { - this.rootElement.addEventListener(cbData.eventName, (e: any) => { - const inputPanelEvent: InputPanelEvent = { - state: this.inputPanelCells.find((data) => - data.cells.find( - (cell) => cell.column.name === e.detail.id - ) - ).cells, - data: { - field: e.detail.id, - value: e.detail.inputValue || e.detail.value, - }, - }; - - cbData.eventCallback(inputPanelEvent); - }); - }); + // this.handleEventsCallbacks.map((cbData) => { + // this.rootElement.addEventListener(cbData.eventName, (e: any) => { + // const inputPanelEvent: InputPanelEvent = { + // state: this.inputPanelCells.find((data) => + // data.cells.find( + // (cell) => cell.column.name === e.detail.id + // ) + // ).cells, + // data: { + // field: e.detail.id, + // value: e.detail.inputValue || e.detail.value, + // }, + // }; + + // cbData.eventCallback(inputPanelEvent); + // }); + // }); } componentWillRender() { diff --git a/packages/ketchup/src/components/kup-input-panel/readme.md b/packages/ketchup/src/components/kup-input-panel/readme.md index f0732adc04..e6fd8dad82 100644 --- a/packages/ketchup/src/components/kup-input-panel/readme.md +++ b/packages/ketchup/src/components/kup-input-panel/readme.md @@ -7,13 +7,13 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ----------------------- | ---------------------- | ---------------------------------------------------------------------- | ----------------------------- | ------- | -| `customStyle` | `custom-style` | Custom style of the component. | `string` | `''` | -| `data` | -- | Actual data of the form. | `KupInputPanelData` | `null` | -| `handleEventsCallbacks` | -- | Sets the callbacks functions on ketchup events | `InputPanelEventsCallback[]` | `[]` | -| `hiddenSubmitButton` | `hidden-submit-button` | Creates a hidden submit button in order to submit the form with enter. | `boolean` | `false` | -| `submitCb` | -- | Sets the callback function on submit form | `(e: SubmitEvent) => unknown` | `null` | +| Property | Attribute | Description | Type | Default | +| -------------------- | ---------------------- | ---------------------------------------------------------------------- | ----------------------------------------- | ------- | +| `customStyle` | `custom-style` | Custom style of the component. | `string` | `''` | +| `data` | -- | Actual data of the form. | `KupInputPanelData` | `null` | +| `hiddenSubmitButton` | `hidden-submit-button` | Creates a hidden submit button in order to submit the form with enter. | `boolean` | `false` | +| `optionsHandler` | -- | Sets the callback function on loading options via FUN | `(fun: string) => Promise` | `null` | +| `submitCb` | -- | Sets the callback function on submit form | `(e: KupInputPanelSubmit) => unknown` | `null` | ## Events @@ -68,12 +68,23 @@ Type: `Promise` +## CSS Custom Properties + +| Name | Description | +| ------------------------------------ | ------------------------------------ | +| `--kup-input-panel-background-color` | Sets background of the component. | +| `--kup-input-panel-color` | Sets text color of the component. | +| `--kup-input-panel-font-family` | Sets font family of the component. | +| `--kup-input-panel-font-size` | Sets font size of the component. | +| `--kup-input-panel-label-alignment` | Sets the text alignment of labels. | +| `--kup-input-panel-label-width` | Sets the width of labels. | +| `--kup-input-panel-padding` | Sets the padding of the input panel. | + + ## Dependencies ### Depends on -- [kup-card](../kup-card) -- [kup-dialog](../kup-dialog) - [kup-badge](../kup-badge) - [kup-autocomplete](../kup-autocomplete) - [kup-chip](../kup-chip) @@ -88,12 +99,12 @@ Type: `Promise` - [kup-chart](../kup-chart) - [kup-gauge](../kup-gauge) - [kup-progress-bar](../kup-progress-bar) +- [kup-card](../kup-card) +- [kup-dialog](../kup-dialog) ### Graph ```mermaid graph TD; - kup-input-panel --> kup-card - kup-input-panel --> kup-dialog kup-input-panel --> kup-badge kup-input-panel --> kup-autocomplete kup-input-panel --> kup-chip @@ -108,6 +119,11 @@ graph TD; kup-input-panel --> kup-chart kup-input-panel --> kup-gauge kup-input-panel --> kup-progress-bar + kup-input-panel --> kup-card + kup-input-panel --> kup-dialog + kup-badge --> kup-badge + kup-badge --> kup-card + kup-badge --> kup-dialog kup-card --> kup-autocomplete kup-card --> kup-chip kup-card --> kup-text-field @@ -146,9 +162,6 @@ graph TD; kup-dialog --> kup-badge kup-dialog --> kup-card kup-dialog --> kup-dialog - kup-badge --> kup-badge - kup-badge --> kup-card - kup-badge --> kup-dialog kup-chip --> kup-card kup-chip --> kup-dialog kup-chip --> kup-badge diff --git a/packages/ketchup/src/components/kup-planner/kup-planner-declarations.ts b/packages/ketchup/src/components/kup-planner/kup-planner-declarations.ts index f58eb26a28..273fea6553 100644 --- a/packages/ketchup/src/components/kup-planner/kup-planner-declarations.ts +++ b/packages/ketchup/src/components/kup-planner/kup-planner-declarations.ts @@ -65,6 +65,8 @@ export enum KupPlannerTaskAction { onDblClick = 'onDblClick', onResize = 'onResize', onRightClick = 'onRightClick', + onPhase = 'onPhase', + onTask = 'onTask', } export interface KupPlannerEventPayload extends KupEventPayload { @@ -141,14 +143,17 @@ export const defaultStylingOptions = { barProgressSelectedColor: '#A2A415', barBackgroundColor: '#A2A415', barBackgroundSelectedColor: '#A2A415', + barDropZoneColor: '#4d9f0240' }; export interface KupPlannerDatesSanitized { dateValues: string[]; secDateValues: string[]; + hourValues: string[]; + secHourValues: string[]; } -export type KupPlannerViewMode = 'day' | 'week' | 'month' | 'year'; +export type KupPlannerViewMode = 'hour' | 'day' | 'week' | 'month' | 'year'; export interface KupPlannerStoredSettings { showSecondaryDates: boolean; @@ -183,6 +188,10 @@ export interface KupPlannerGanttTaskN extends KupPlannerGanttRow { phases?: KupPlannerPhaseGantt[]; details?: KupPlannerItemDetail[]; icon?: KupPlannerTaskIcon; + startHour?: string; + endHour?: string; + secondaryStartHour?: string; + secondaryEndHour?: string; } /** Fase */ @@ -195,6 +204,10 @@ export interface KupPlannerPhaseGantt extends KupPlannerGanttRow { selectedColor?: string; dependencies?: string[]; icon?: KupPlannerTaskIcon; + startHour?: string; + endHour?: string; + secondaryStartHour?: string; + secondaryEndHour?: string; } /** Risorsa */ @@ -208,6 +221,8 @@ export interface KupPlannerScheduleItem { color?: string; selectedColor?: string; icon?: KupPlannerTaskIcon; + startHour?: string; + endHour?: string; } export interface KupPlannerTask { @@ -236,6 +251,10 @@ export interface KupPlannerTask { hideChildren?: boolean; displayOrder?: number; icon?: KupPlannerTaskIcon; + startHour?: string; + endHour?: string; + secondaryStartHour?: string; + secondaryEndHour?: string; } export interface KupPlannerTimeframe { @@ -382,6 +401,15 @@ export interface KupPlannerEventOption { * Invokes on scroll Y */ scrollYChange?: (y: number) => void; + /** + * Invokes on end and start time change. Chart undoes operation if method return false or error. + */ + phaseDrop?: ( + originalPhaseData: KupPlannerTask, + originalTaskData: KupPlannerTask, + finalPhaseData: KupPlannerTask, + destinationData: KupPlannerTask, + ) => void | boolean | Promise | Promise; } export interface KupPlannerDisplayOption { @@ -475,6 +503,7 @@ export interface KupPlannerBarTask extends KupPlannerTask { progressColor: string; progressSelectedColor: string; }; + ySecondary?: number } export type KupPlannerTaskTypeInternal = KupPlannerTaskType | 'smalltask'; @@ -635,6 +664,7 @@ export type KupPlannerBarDisplayProps = { xSecondary?: number; widthSecondary?: number; showSecondaryDates: boolean; + ySecondary?: number }; export type KupPlannerBarDateHandleProps = { @@ -684,13 +714,13 @@ export interface KupGanttPlannerProps { initialScrollX?: number; initialScrollY?: number; readOnly?: boolean; - /** Events */ onDateChange?: (row: KupPlannerGanttRow) => void; onClick?: (row: KupPlannerGanttRow) => void; onDblClick?: (row: KupPlannerGanttRow) => void; onContextMenu?: (event: MouseEvent, row: KupPlannerGanttRow) => void; onScrollY?: (y: number) => void; + onPhaseDrop?: (row: KupPlannerGanttRow) => void; } export interface KupGanttPlannerDetailsProps { @@ -721,6 +751,7 @@ export interface PlannerProps { secondaryGantt?: KupGanttPlannerDetailsProps; preStepsCount?: number; viewMode: KupPlannerViewMode; + scrollableTaskList?: boolean; onSetDoubleView?: (checked: boolean) => void; onSetViewMode?: (value: KupPlannerViewMode) => void; onScrollX?: (x: number) => void; diff --git a/packages/ketchup/src/components/kup-planner/kup-planner-helper.ts b/packages/ketchup/src/components/kup-planner/kup-planner-helper.ts index 1121c73e57..b91d2a9c01 100644 --- a/packages/ketchup/src/components/kup-planner/kup-planner-helper.ts +++ b/packages/ketchup/src/components/kup-planner/kup-planner-helper.ts @@ -14,7 +14,11 @@ export function sanitizeAllDates( startDateCell: KupDataCell, endDateCell: KupDataCell, secStartDateCell?: KupDataCell, - secEndDateCell?: KupDataCell + secEndDateCell?: KupDataCell, + startHourCell?: KupDataCell, + endHourCell?: KupDataCell, + secStartHourCell?: KupDataCell, + secEndHourCell?: KupDataCell ): KupPlannerDatesSanitized { const sanitizedDateValues = sanitizeDates(startDateCell, endDateCell); let sanitizedSecDateValues = []; @@ -28,9 +32,33 @@ export function sanitizeAllDates( sanitizedSecDateValues = [...sanitizedDateValues]; } } + let sanitizedHourValues = []; + if (startHourCell && endHourCell) { + if (isAtLeastOneHourValid(startHourCell, endHourCell)) { + sanitizedHourValues = sanitizeHours( + startHourCell, + endHourCell + ); + } else { + sanitizedSecDateValues = [...sanitizedDateValues]; + } + } + let sanitizedSecHourValues = []; + if (secStartHourCell && secEndHourCell) { + if (isAtLeastOneHourValid(secStartHourCell, secEndHourCell)) { + sanitizedSecHourValues = sanitizeHours( + secStartHourCell, + secEndHourCell + ); + } else { + sanitizedSecDateValues = [...sanitizedDateValues]; + } + } return { dateValues: sanitizedDateValues, secDateValues: sanitizedSecDateValues, + hourValues: sanitizedHourValues, + secHourValues: sanitizedSecHourValues }; } @@ -50,6 +78,22 @@ function sanitizeDates( } } +function sanitizeHours( + startHourCell: KupDataCell, + endHourCell: KupDataCell +): string[] { + let returnValues = [startHourCell.value, endHourCell.value]; + if (isHourValid(startHourCell) && isHourValid(endHourCell)) { + return returnValues; + } else if (isHourValid(startHourCell)) { + return [startHourCell.value, startHourCell.value]; + } else if (isHourValid(endHourCell)) { + return [endHourCell.value, endHourCell.value]; + } else { + return returnValues; + } +} + function isDateValid(dateCell: KupDataCell) { return ( kupManager.objects.isDate(dateCell.obj) && @@ -57,6 +101,12 @@ function isDateValid(dateCell: KupDataCell) { ); } +function isHourValid(dateCell: KupDataCell) { + return ( + kupManager.objects.isTime(dateCell.obj) || kupManager.objects.isTimeWithSeconds(dateCell.obj) + ); +} + export function isAtLeastOneDateValid( startDateCell: KupDataCell, endDateCell: KupDataCell @@ -64,6 +114,13 @@ export function isAtLeastOneDateValid( return isDateValid(startDateCell) || isDateValid(endDateCell); } +export function isAtLeastOneHourValid( + startHourCell: KupDataCell, + endHourCell: KupDataCell +): boolean { + return isHourValid(startHourCell) || isHourValid(endHourCell); +} + export function getValuesToShow( row: KupDataRow, idCol: string, diff --git a/packages/ketchup/src/components/kup-planner/kup-planner.tsx b/packages/ketchup/src/components/kup-planner/kup-planner.tsx index a136af196f..ddddd041c5 100644 --- a/packages/ketchup/src/components/kup-planner/kup-planner.tsx +++ b/packages/ketchup/src/components/kup-planner/kup-planner.tsx @@ -249,6 +249,13 @@ export class KupPlanner { @Prop() detailHeight: number; + /** + * Columns containing detail hour duration, from (firstDate) to (secondDate) + * @default null + */ + @Prop() + detailHours: string[] = []; + /** * Column containing icon name to show, for detail * @default null @@ -270,6 +277,13 @@ export class KupPlanner { @Prop() detailNameCol: string; + /** + * Columns containing forecast detail duration, from (firstHour) to (secondHour) + * @default null + */ + @Prop() + detailPrevHours: string[] = []; + /** * Columns containing forecast detail duration, from (firstDate) to (secondDate) * @default null @@ -333,6 +347,13 @@ export class KupPlanner { @Prop() phaseDates: string[]; + /** + * Columns containing phase hour duration, from (firstDate) to (secondDate) + * @default null + */ + @Prop() + phaseHours: string[] = []; + /** * Column containing icon name to show, for phase * @default null @@ -354,6 +375,13 @@ export class KupPlanner { @Prop() phaseNameCol: string; + /** + * Columns containing forecast phase duration, from (firstHour) to (secondHour) + * @default null + */ + @Prop() + phasePrevHours: string[] = []; + /** * Columns containing forecast phase duration, from (firstDate) to (secondDate) * @default null @@ -403,6 +431,13 @@ export class KupPlanner { @Prop() taskHeight: number; + /** + * Columns containing task hours duration, from (firstDate) to (secondDate) + * @default null + */ + @Prop() + taskHours: string[] = []; + /** * Column containing icon name to show, for task * @default null @@ -438,6 +473,13 @@ export class KupPlanner { @Prop() taskNameCol: string; + /** + * Columns containing forecast task duration, from (firstHour) to (secondHour) + * @default null + */ + @Prop() + taskPrevHours: string[] = []; + /** * Columns containing forecast task duration, from (firstDate) to (secondDate) * @default null @@ -473,6 +515,13 @@ export class KupPlanner { @Prop() secondaryFilter: HTMLElement; + /** + * Sets the scroll bar for task list. + * @default false + */ + @Prop() + scrollableTaskList: boolean = false; + /*-------------------------------------------------*/ /* S t a t e s */ /*-------------------------------------------------*/ @@ -529,6 +578,14 @@ export class KupPlanner { }) kupDateChange: EventEmitter; + @Event({ + eventName: 'kup-planner-phasedrop', + composed: true, + cancelable: false, + bubbles: true, + }) + kupPhaseDrop: EventEmitter; + @Event({ eventName: 'kup-planner-ready', composed: true, @@ -611,7 +668,11 @@ export class KupPlanner { row.cells[this.phaseDates[0]], row.cells[this.phaseDates[1]], row.cells[this.phasePrevDates[0]], - row.cells[this.phasePrevDates[1]] + row.cells[this.phasePrevDates[1]], + row.cells[this.phaseHours[0]], + row.cells[this.phaseHours[1]], + row.cells[this.phasePrevHours[0]], + row.cells[this.phasePrevHours[1]], ); const valuesToShow = getValuesToShow( row, @@ -655,6 +716,10 @@ export class KupPlanner { icon: iconUrl ? { url: iconUrl, color: iconColor ?? '#595959' } : undefined, + startHour: datesSanitized.hourValues[0], + endHour: datesSanitized.hourValues[1], + secondaryStartHour: datesSanitized.secHourValues[0], + secondaryEndHour: datesSanitized.secHourValues[1], }; return phase; }); @@ -689,7 +754,11 @@ export class KupPlanner { row.cells[this.taskDates[0]], row.cells[this.taskDates[1]], row.cells[this.taskPrevDates[0]], - row.cells[this.taskPrevDates[1]] + row.cells[this.taskPrevDates[1]], + row.cells[this.taskHours[0]], + row.cells[this.taskHours[1]], + row.cells[this.taskPrevHours[0]], + row.cells[this.taskPrevHours[1]], ); const valuesToShow = getValuesToShow( row, @@ -729,6 +798,10 @@ export class KupPlanner { icon: iconUrl ? { url: iconUrl, color: iconColor ?? '#595959' } : undefined, + startHour: datesSanitized.hourValues[0], + endHour: datesSanitized.hourValues[1], + secondaryStartHour: datesSanitized.secHourValues[0], + secondaryEndHour: datesSanitized.secHourValues[1] }; return task; }); @@ -744,7 +817,7 @@ export class KupPlanner { .filter((row) => isAtLeastOneDateValid( row.cells[this.detailDates[0]], - row.cells[this.detailDates[1]] + row.cells[this.detailDates[1]], ) ) .forEach((row) => { @@ -753,7 +826,11 @@ export class KupPlanner { const datesSanitized = sanitizeAllDates( row.cells[this.detailDates[0]], - row.cells[this.detailDates[1]] + row.cells[this.detailDates[1]], + undefined, + undefined, + row.cells[this.detailHours[0]], + row.cells[this.detailHours[1]], ); const valuesToShow = getValuesToShow( @@ -794,6 +871,8 @@ export class KupPlanner { icon: iconUrl ? { url: iconUrl, color: iconColor ?? '#595959' } : undefined, + startHour: datesSanitized.hourValues[0], + endHour: datesSanitized.hourValues[1] }); }); @@ -1005,7 +1084,7 @@ export class KupPlanner { let taskScrollYTimeout: number; let detailScrollYTimeout: number; const scrollDelay = 500; - + this.plannerProps = { mainGantt: { title: this.titleMess, @@ -1045,6 +1124,9 @@ export class KupPlanner { scrollDelay ); }, + onPhaseDrop: ( + nativeEvent: KupPlannerGanttTask | KupPlannerPhase + ) => this.handleOnPhaseDrop(nativeEvent), }, secondaryGantt: details ? { @@ -1082,6 +1164,7 @@ export class KupPlanner { onSetViewMode: (value: KupPlannerViewMode) => this.handleOnSetViewMode(value), viewMode: this.viewMode, + scrollableTaskList: this.scrollableTaskList, onScrollX: (x: number) => { window.clearTimeout(scrollXTimeout); scrollXTimeout = window.setTimeout( @@ -1188,6 +1271,18 @@ export class KupPlanner { }); } + onKupPhaseDrop( + event: KupPlannerGanttRow, + taskAction?: KupPlannerTaskAction + ) { + this.kupPhaseDrop.emit({ + comp: this, + id: this.rootElement.id, + value: event, + taskAction: taskAction, + }); + } + handleOnDblClick( nativeEvent: KupPlannerGanttTask | KupPlannerPhase | KupPlannerDetail ) { @@ -1341,6 +1436,15 @@ export class KupPlanner { } } + handleOnPhaseDrop( + nativeEvent: KupPlannerGanttTask | KupPlannerPhase | KupPlannerDetail + ) { + this.onKupPhaseDrop( + nativeEvent, + KupPlannerTaskAction.onTask + ); + } + //======== Utility methods ======== #getIconUrl(row: KupDataRow, columnName: string): string { let iconUrl = undefined; diff --git a/packages/ketchup/src/components/kup-planner/readme.md b/packages/ketchup/src/components/kup-planner/readme.md index 126ab5492c..21e27d06b2 100644 --- a/packages/ketchup/src/components/kup-planner/readme.md +++ b/packages/ketchup/src/components/kup-planner/readme.md @@ -7,50 +7,57 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ---------------------- | ------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------- | ----------- | -| `customStyle` | `custom-style` | Custom style of the component. | `string` | `''` | -| `data` | -- | Dataset containg the tasks list | `KupDataDataset` | `undefined` | -| `detailColorCol` | `detail-color-col` | Column containing the detail color, in hex format | `string` | `undefined` | -| `detailColumns` | -- | Columns containing informations displayed in the left box, near the gantt of details | `string[]` | `undefined` | -| `detailData` | -- | Dataset containg the details list | `KupDataDataset` | `undefined` | -| `detailDates` | -- | Columns containing detail duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `detailFilter` | `detail-filter` | Sets the detail's filter. | `string` | `undefined` | -| `detailHeight` | `detail-height` | Height for detail gantt | `number` | `undefined` | -| `detailIconCol` | `detail-icon-col` | Column containing icon name to show, for detail | `string` | `undefined` | -| `detailIdCol` | `detail-id-col` | Column containing unique detail identifier | `string` | `undefined` | -| `detailInitialScrollX` | `detail-initial-scroll-x` | Sets the initial scroll X for the detail. | `number` | `undefined` | -| `detailInitialScrollY` | `detail-initial-scroll-y` | Sets the initial scroll Y for the detail. | `number` | `undefined` | -| `detailNameCol` | `detail-name-col` | Column containing detail name displayed | `string` | `undefined` | -| `detailPrevDates` | -- | Columns containing forecast detail duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `listCellWidth` | `list-cell-width` | Total size of the cells inside to the left box, near the gantt | `string` | `'300px'` | -| `mainFilter` | -- | Sets the filter for main gantt. | `HTMLElement` | `undefined` | -| `maxWidth` | `max-width` | Max width for component | `string` | `'90vw'` | -| `phaseColParDep` | `phase-col-par-dep` | Column containing the name of the parent phases | `string` | `undefined` | -| `phaseColorCol` | `phase-color-col` | Column containing the phase color in hex format | `string` | `undefined` | -| `phaseColumns` | -- | Columns containing informations displayed in the left box ,near the gantt of phases | `string[]` | `undefined` | -| `phaseDates` | -- | Columns containing phase duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `phaseIconCol` | `phase-icon-col` | Column containing icon name to show, for phase | `string` | `undefined` | -| `phaseIdCol` | `phase-id-col` | Column containing unique phase identifier | `string` | `undefined` | -| `phaseNameCol` | `phase-name-col` | Column containing phase name displayed | `string` | `undefined` | -| `phasePrevDates` | -- | Columns containing forecast phase duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `readOnly` | `read-only` | When true, the two gantts are not interactable. | `boolean` | `false` | -| `secondaryFilter` | -- | Sets the filter for secondary gantt. | `HTMLElement` | `undefined` | -| `showSecondaryDates` | `show-secondary-dates` | Enable/disable display of secondary dates | `boolean` | `false` | -| `stateId` | `state-id` | | `string` | `''` | -| `store` | -- | | `KupStore` | `undefined` | -| `taskColumns` | -- | Columns containing informations displayed in the left box, near the gantt | `string[]` | `undefined` | -| `taskDates` | -- | Columns containing task duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `taskFilter` | `task-filter` | Sets the task's filter. | `string` | `undefined` | -| `taskHeight` | `task-height` | Height for main gantt | `number` | `undefined` | -| `taskIconCol` | `task-icon-col` | Column containing icon name to show, for task | `string` | `undefined` | -| `taskIdCol` | `task-id-col` | Column containing unique task identifier | `string` | `undefined` | -| `taskInitialScrollX` | `task-initial-scroll-x` | Sets the initial scroll X for the task. | `number` | `undefined` | -| `taskInitialScrollY` | `task-initial-scroll-y` | Sets the initial scroll Y for the task. | `number` | `undefined` | -| `taskNameCol` | `task-name-col` | Column containing task name displayed | `string` | `undefined` | -| `taskPrevDates` | -- | Columns containing forecast task duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | -| `titleMess` | `title-mess` | Message displayed on top | `string` | `undefined` | -| `viewMode` | `view-mode` | Sets the view mode. | `"day" \| "month" \| "week" \| "year"` | `'month'` | +| Property | Attribute | Description | Type | Default | +| ---------------------- | ------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------ | ----------- | +| `customStyle` | `custom-style` | Custom style of the component. | `string` | `''` | +| `data` | -- | Dataset containg the tasks list | `KupDataDataset` | `undefined` | +| `detailColorCol` | `detail-color-col` | Column containing the detail color, in hex format | `string` | `undefined` | +| `detailColumns` | -- | Columns containing informations displayed in the left box, near the gantt of details | `string[]` | `undefined` | +| `detailData` | -- | Dataset containg the details list | `KupDataDataset` | `undefined` | +| `detailDates` | -- | Columns containing detail duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `detailFilter` | `detail-filter` | Sets the detail's filter. | `string` | `undefined` | +| `detailHeight` | `detail-height` | Height for detail gantt | `number` | `undefined` | +| `detailHours` | -- | Columns containing detail hour duration, from (firstDate) to (secondDate) | `string[]` | `[]` | +| `detailIconCol` | `detail-icon-col` | Column containing icon name to show, for detail | `string` | `undefined` | +| `detailIdCol` | `detail-id-col` | Column containing unique detail identifier | `string` | `undefined` | +| `detailInitialScrollX` | `detail-initial-scroll-x` | Sets the initial scroll X for the detail. | `number` | `undefined` | +| `detailInitialScrollY` | `detail-initial-scroll-y` | Sets the initial scroll Y for the detail. | `number` | `undefined` | +| `detailNameCol` | `detail-name-col` | Column containing detail name displayed | `string` | `undefined` | +| `detailPrevDates` | -- | Columns containing forecast detail duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `detailPrevHours` | -- | Columns containing forecast detail duration, from (firstHour) to (secondHour) | `string[]` | `[]` | +| `listCellWidth` | `list-cell-width` | Total size of the cells inside to the left box, near the gantt | `string` | `'300px'` | +| `mainFilter` | -- | Sets the filter for main gantt. | `HTMLElement` | `undefined` | +| `maxWidth` | `max-width` | Max width for component | `string` | `'90vw'` | +| `phaseColParDep` | `phase-col-par-dep` | Column containing the name of the parent phases | `string` | `undefined` | +| `phaseColorCol` | `phase-color-col` | Column containing the phase color in hex format | `string` | `undefined` | +| `phaseColumns` | -- | Columns containing informations displayed in the left box ,near the gantt of phases | `string[]` | `undefined` | +| `phaseDates` | -- | Columns containing phase duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `phaseHours` | -- | Columns containing phase hour duration, from (firstDate) to (secondDate) | `string[]` | `[]` | +| `phaseIconCol` | `phase-icon-col` | Column containing icon name to show, for phase | `string` | `undefined` | +| `phaseIdCol` | `phase-id-col` | Column containing unique phase identifier | `string` | `undefined` | +| `phaseNameCol` | `phase-name-col` | Column containing phase name displayed | `string` | `undefined` | +| `phasePrevDates` | -- | Columns containing forecast phase duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `phasePrevHours` | -- | Columns containing forecast phase duration, from (firstHour) to (secondHour) | `string[]` | `[]` | +| `readOnly` | `read-only` | When true, the two gantts are not interactable. | `boolean` | `false` | +| `scrollableTaskList` | `scrollable-task-list` | Sets the scroll bar for task list. | `boolean` | `false` | +| `secondaryFilter` | -- | Sets the filter for secondary gantt. | `HTMLElement` | `undefined` | +| `showSecondaryDates` | `show-secondary-dates` | Enable/disable display of secondary dates | `boolean` | `false` | +| `stateId` | `state-id` | | `string` | `''` | +| `store` | -- | | `KupStore` | `undefined` | +| `taskColumns` | -- | Columns containing informations displayed in the left box, near the gantt | `string[]` | `undefined` | +| `taskDates` | -- | Columns containing task duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `taskFilter` | `task-filter` | Sets the task's filter. | `string` | `undefined` | +| `taskHeight` | `task-height` | Height for main gantt | `number` | `undefined` | +| `taskHours` | -- | Columns containing task hours duration, from (firstDate) to (secondDate) | `string[]` | `[]` | +| `taskIconCol` | `task-icon-col` | Column containing icon name to show, for task | `string` | `undefined` | +| `taskIdCol` | `task-id-col` | Column containing unique task identifier | `string` | `undefined` | +| `taskInitialScrollX` | `task-initial-scroll-x` | Sets the initial scroll X for the task. | `number` | `undefined` | +| `taskInitialScrollY` | `task-initial-scroll-y` | Sets the initial scroll Y for the task. | `number` | `undefined` | +| `taskNameCol` | `task-name-col` | Column containing task name displayed | `string` | `undefined` | +| `taskPrevDates` | -- | Columns containing forecast task duration, from (firstDate) to (secondDate) | `string[]` | `undefined` | +| `taskPrevHours` | -- | Columns containing forecast task duration, from (firstHour) to (secondHour) | `string[]` | `[]` | +| `titleMess` | `title-mess` | Message displayed on top | `string` | `undefined` | +| `viewMode` | `view-mode` | Sets the view mode. | `"day" \| "hour" \| "month" \| "week" \| "year"` | `'month'` | ## Events @@ -62,6 +69,7 @@ | `kup-planner-datechange` | | `CustomEvent` | | `kup-planner-dblclick` | | `CustomEvent` | | `kup-planner-didunload` | When component unload is complete | `CustomEvent` | +| `kup-planner-phasedrop` | | `CustomEvent` | | `kup-planner-ready` | | `CustomEvent` | diff --git a/packages/ketchup/src/components/kup-planner/utils/custom-task-list-table.tsx b/packages/ketchup/src/components/kup-planner/utils/custom-task-list-table.tsx index 60d688bb49..aad56cf182 100644 --- a/packages/ketchup/src/components/kup-planner/utils/custom-task-list-table.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/custom-task-list-table.tsx @@ -1,6 +1,7 @@ -import { Component, Fragment, h, Prop } from '@stencil/core'; +import { Component, Fragment, h, Prop, Watch } from '@stencil/core'; import { KupPlannerTask } from '../kup-planner-declarations'; import { KupDates } from '../../../managers/kup-dates/kup-dates'; +import { createArrayFromNum } from './helpers/other.helpers'; @Component({ tag: 'kup-custom-task-list-table', styleUrl: 'gantt-table.module.scss', @@ -27,6 +28,12 @@ export class KupCustomTaskListTable { @Prop() fontSize: string = ''; + @Prop() + scrollableTaskList: boolean; + + @Prop() + taskListScrollX: number; + @Prop() setSelectedTask: (taskId: string) => void; @@ -39,159 +46,246 @@ export class KupCustomTaskListTable { @Prop() oncontextmenuTaskList: (event: MouseEvent, id: string) => void; + @Prop() + ontaskListScrollWidth: (width: number) => void; + + private projectWrapperRef: HTMLDivElement; + + componentDidLoad() { + this.ontaskListScrollWidth(this.projectWrapperRef?.clientWidth) + } + + componentDidUpdate() { + this.ontaskListScrollWidth(this.projectWrapperRef?.clientWidth) + } + + @Watch('taskListScrollX') + updateTaskListScroll() { + this.projectWrapperRef && + (this.projectWrapperRef.parentElement.scrollLeft = this.taskListScrollX); + } + render() { const kupDates: KupDates = new KupDates(); + const scrollableStyle = {}; + + if (this.scrollableTaskList) { + scrollableStyle['width'] = this.rowWidth + } + + const spansToShow = this.tasks.reduce((prev, curr) => { + return prev.valuesToShow.length > curr.valuesToShow.length ? prev : curr; + }).valuesToShow.length + 1; + return ( -
- {this.tasks.map((task) => ( - - {task.type === 'project' ? ( -
{ - this.setSelectedTask(task.id); - this.onclickTaskList(task.id); - }} - onDblClick={() => { - this.setSelectedTask(task.id); - this.ondblclickTaskList(task.id); - }} - onContextMenu={(e) => { - e.preventDefault(); - this.setSelectedTask(task.id); - this.oncontextmenuTaskList(e, task.id); - }} - > - {task.valuesToShow?.map((v, index) => ( - 10 ? v : undefined} - key={`task_${task.id}_valuesToShow_${index}`} - > - {v === '#START#' - ? kupDates.formatToLocaleSimple( - task.start - ) - : v === '#END#' - ? kupDates.formatToLocaleSimple( - task.end - ) - : v} - - ))} -
- ) : task.type === 'task' ? ( -
{ - this.setSelectedTask(task.id); - this.onclickTaskList(task.id); - }} - onDblClick={() => { - this.setSelectedTask(task.id); - this.ondblclickTaskList(task.id); - }} - onContextMenu={(e) => { - e.preventDefault(); - this.setSelectedTask(task.id); - this.oncontextmenuTaskList(e, task.id); - }} - > - +
(this.projectWrapperRef = el)}> + {this.tasks.map((task) => ( + + {task.type === 'project' ? ( +
{ + this.setSelectedTask(task.id); + this.onclickTaskList(task.id); + }} + onDblClick={() => { + this.setSelectedTask(task.id); + this.ondblclickTaskList(task.id); + }} + onContextMenu={(e) => { + e.preventDefault(); + this.setSelectedTask(task.id); + this.oncontextmenuTaskList(e, task.id); + }} + > + {task.valuesToShow?.map((v, index) => ( + 10 ? v : undefined + } + key={`task_${task.id}_valuesToShow_${index}`} + > + {v === '#START#' + ? kupDates.formatToLocaleSimple( + task.start + ) + : v === '#END#' + ? kupDates.formatToLocaleSimple( + task.end + ) + : v} + + ))} + {this.scrollableTaskList && spansToShow > task.valuesToShow.length && ( + (() => { + const spansToIterate = createArrayFromNum(spansToShow - task.valuesToShow.length); + return ( + spansToIterate.map((element) => ( + + )) + ) + })() + )} +
+ ) : task.type === 'task' ? ( +
{ + this.setSelectedTask(task.id); + this.onclickTaskList(task.id); + }} + onDblClick={() => { + this.setSelectedTask(task.id); + this.ondblclickTaskList(task.id); + }} + onContextMenu={(e) => { + e.preventDefault(); + this.setSelectedTask(task.id); + this.oncontextmenuTaskList(e, task.id); }} - /> - {task.valuesToShow?.map((v, index) => ( - 10 ? v : undefined} - key={`phase_${task.id}_valuesToShow_${index}`} - > - {v === '#START#' - ? kupDates.formatToLocaleSimple( - task.start - ) - : v === '#END#' - ? kupDates.formatToLocaleSimple( - task.end - ) - : v} - - ))} -
- ) : ( - (() => { - let str = ''; - for ( - let i = 0; - i < task.valuesToShow.length; - i++ - ) { - str += '1fr '; - } - return ( -
{ - e.preventDefault(); - this.setSelectedTask(task.id); - this.oncontextmenuTaskList( - e, - task.id - ); - }} - > - {task.valuesToShow?.map((v, index) => ( + > + {this.scrollableTaskList ? ( +
10 - ? v - : undefined - } - key={`detail_${task.id}_valuesToShow_${index}`} - > - {v} - - ))} -
- ); - })() - )} - - ))} + key={`phase_${task.id}_valuesToShow_color`} + style={{ + height: '16px', + width: '16px', + display: 'inline-block', + backgroundColor: + task.styles + ?.backgroundColor, + }} + /> +
+ ) : ( + + )} + {task.valuesToShow?.map((v, index) => ( + 10 ? v : undefined + } + key={`phase_${task.id}_valuesToShow_${index}`} + > + {v === '#START#' + ? kupDates.formatToLocaleSimple( + task.start + ) + : v === '#END#' + ? kupDates.formatToLocaleSimple( + task.end + ) + : v} + + ))} + {this.scrollableTaskList && spansToShow > task.valuesToShow.length && ( + (() => { + const spansToIterate = createArrayFromNum(spansToShow - task.valuesToShow.length - 1); + return ( + spansToIterate.map((element) => ( + + )) + ) + })() + )} +
+ ) : ( + (() => { + let str = ''; + for ( + let i = 0; + i < task.valuesToShow.length; + i++ + ) { + str += '1fr '; + } + return ( +
{ + e.preventDefault(); + this.setSelectedTask(task.id); + this.oncontextmenuTaskList( + e, + task.id + ); + }} + > + {task.valuesToShow?.map( + (v, index) => ( + 10 + ? v + : undefined + } + key={`detail_${task.id}_valuesToShow_${index}`} + > + {v} + + ) + )} +
+ ); + })() + )} + + ))} +
); } diff --git a/packages/ketchup/src/components/kup-planner/utils/gantt-table.module.scss b/packages/ketchup/src/components/kup-planner/utils/gantt-table.module.scss index c0949e9fd7..b8d1249a0d 100644 --- a/packages/ketchup/src/components/kup-planner/utils/gantt-table.module.scss +++ b/packages/ketchup/src/components/kup-planner/utils/gantt-table.module.scss @@ -3,6 +3,87 @@ margin-right: 10px; } +.scrollable { + overflow-x: auto; + scrollbar-width: 0; + .project-wrapper { + display: table; + } + .project { + width: 100% !important; + display: table-row; + + & > * { + overflow: unset; + padding-right: 10px; + display: table-cell; + vertical-align: middle; + border-bottom: 1px solid var(--kup-border-color, #acacac); + border-top: 1px solid var(--kup-border-color, #acacac); + padding-left: 12px; + &:first-child { + border-left: 1px solid var(--kup-border-color, #acacac); + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; + } + &:last-child { + border-right: 1px solid var(--kup-border-color, #acacac); + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; + } + } + } + .subrow { + width: 100% !important; + display: table-row; + & > * { + overflow: unset; + padding-right: 10px; + display: table-cell; + vertical-align: middle; + border-bottom: 1px solid #acacac; + border-top: 1px solid #acacac; + padding-left: 12px; + &:first-child { + border-left: 1px solid #acacac; + } + &:last-child { + border-right: 1px solid #acacac; + } + } + } + .timeline { + width: 100% !important; + display: table-row; + & > * { + overflow: unset; + padding-right: 10px; + display: table-cell; + vertical-align: middle; + border-bottom: 1px solid #acacac; + border-top: 1px solid #acacac; + padding-left: 12px; + &:first-child { + border-left: 1px solid #acacac; + } + &:last-child { + border-right: 1px solid #acacac; + } + } + } + .project:has(+ .subrow) { + & > * { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } +} + +.scrollable::-webkit-scrollbar { + width: 0; + height: 0; +} + .project { background: var(--kup-background-color, #ffffff); border: 1px solid var(--kup-border-color, #acacac); @@ -58,8 +139,8 @@ .subrow:has(+ .subrow), .project:has(+ .subrow) { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; } .timeline { diff --git a/packages/ketchup/src/components/kup-planner/utils/helpers/bar.helpers.ts b/packages/ketchup/src/components/kup-planner/utils/helpers/bar.helpers.ts index 8a8d576fc3..977811873a 100644 --- a/packages/ketchup/src/components/kup-planner/utils/helpers/bar.helpers.ts +++ b/packages/ketchup/src/components/kup-planner/utils/helpers/bar.helpers.ts @@ -1,3 +1,4 @@ +import { kupManagerInstance } from '../../../../managers/kup-manager/kup-manager'; import { KupPlannerTask, KupPlannerTimeframe, @@ -149,16 +150,18 @@ function computeTypeAndXs( dates: Date[], columnWidth: number, handleWidth: number, - rtl: boolean + rtl: boolean, + startHour?: string, + endHour?: string ) { let x1: number; let x2: number; if (rtl) { - x2 = taskXCoordinateRTL(start, dates, columnWidth); - x1 = taskXCoordinateRTL(end, dates, columnWidth); + x2 = taskXCoordinateRTL(start, dates, columnWidth, startHour); + x1 = taskXCoordinateRTL(end, dates, columnWidth, endHour); } else { - x1 = taskXCoordinate(start, dates, columnWidth); - x2 = taskXCoordinate(end, dates, columnWidth); + x1 = taskXCoordinate(start, dates, columnWidth, startHour); + x2 = taskXCoordinate(end, dates, columnWidth, endHour); } let typeInternal: KupPlannerTaskTypeInternal = type; if (typeInternal === 'task' && x2 - x1 < handleWidth * 2) { @@ -191,7 +194,9 @@ const convertToBar = ( dates, columnWidth, handleWidth, - rtl + rtl, + task.startHour, + task.endHour ); const { x1: x1secondary, x2: x2secondary } = showSecondaryDates && task.secondaryStart && task.secondaryEnd @@ -202,7 +207,9 @@ const convertToBar = ( dates, columnWidth, handleWidth, - rtl + rtl, + task.secondaryStartHour, + task.secondaryEndHour ) : { x1: undefined, x2: undefined }; @@ -240,6 +247,7 @@ const convertToBar = ( height: taskHeight, barChildren: [], styles, + ySecondary: y }; }; @@ -339,7 +347,13 @@ const convertToTimeline = ( }; }; -const taskXCoordinate = (xDate: Date, dates: Date[], columnWidth: number) => { +const taskXCoordinate = (xDate: Date, dates: Date[], columnWidth: number, hourString?: string) => { + if (hourString) { + const [hours, minutes, seconds] = hourString.split(':').map(Number); + xDate.setHours(hours ?? 0); + xDate.setMinutes(minutes ?? 0); + xDate.setSeconds(seconds ?? 0); + } const index = dates.findIndex((d) => d.getTime() >= xDate.getTime()) - 1; if (index < 0) { @@ -354,9 +368,10 @@ const taskXCoordinate = (xDate: Date, dates: Date[], columnWidth: number) => { const taskXCoordinateRTL = ( xDate: Date, dates: Date[], - columnWidth: number + columnWidth: number, + hourString?: string ) => { - let x = taskXCoordinate(xDate, dates, columnWidth); + let x = taskXCoordinate(xDate, dates, columnWidth, hourString); x += columnWidth; return x; }; @@ -476,6 +491,30 @@ const dateByX = ( return newDate; }; +const hourStringFromDate = ( + date: Date, + withSeconds: boolean +): string => { + + const hours = date.getHours(); + const minutes = date.getMinutes(); + const seconds = date.getSeconds(); + + const formattedHours = hours < 10 ? '0' + hours : hours; + const formattedMinutes = minutes < 10 ? '0' + minutes : minutes; + const formattedSeconds = seconds < 10 ? '0' + seconds : seconds; + + const hourString = withSeconds ? `${formattedHours}:${formattedMinutes}:${formattedSeconds}` : `${formattedHours}:${formattedMinutes}`; + + return hourString; +} + +const hasSeconds = ( + hourString: string +) : boolean => { + return hourString.split(":").length === 3; +} + /** * Method handles event in real time(mousemove) and on finish(mouseup) */ @@ -486,7 +525,8 @@ export const handleTaskBySVGMouseEvent = ( xStep: number, timeStep: number, initEventX1Delta: number, - rtl: boolean + rtl: boolean, + svgY: number ): { isChanged: boolean; changedTask: KupPlannerBarTask } => handleTaskBySVGMouseEventForBar( svgX, @@ -495,7 +535,8 @@ export const handleTaskBySVGMouseEvent = ( xStep, timeStep, initEventX1Delta, - rtl + rtl, + svgY ); const handleTaskBySVGMouseEventForBar = ( @@ -505,7 +546,8 @@ const handleTaskBySVGMouseEventForBar = ( xStep: number, timeStep: number, initEventX1Delta: number, - rtl: boolean + rtl: boolean, + svgY: number ): { isChanged: boolean; changedTask: KupPlannerBarTask } => { const changedTask: KupPlannerBarTask = { ...selectedTask }; let isChanged = false; @@ -541,6 +583,7 @@ const handleTaskBySVGMouseEventForBar = ( xStep, timeStep ); + changedTask.endHour && (changedTask.endHour = hourStringFromDate(changedTask.end, hasSeconds(changedTask.endHour))) } else { changedTask.start = dateByX( newX1, @@ -549,6 +592,7 @@ const handleTaskBySVGMouseEventForBar = ( xStep, timeStep ); + changedTask.startHour && (changedTask.startHour = hourStringFromDate(changedTask.start, hasSeconds(changedTask.startHour))) } const [progressWidth, progressX] = progressWithByParams( changedTask.x1, @@ -574,6 +618,7 @@ const handleTaskBySVGMouseEventForBar = ( xStep, timeStep ); + changedTask.startHour && (changedTask.startHour = hourStringFromDate(changedTask.start, hasSeconds(changedTask.startHour))) } else { changedTask.end = dateByX( newX2, @@ -582,6 +627,7 @@ const handleTaskBySVGMouseEventForBar = ( xStep, timeStep ); + changedTask.endHour && (changedTask.endHour = hourStringFromDate(changedTask.end, hasSeconds(changedTask.endHour))) } const [progressWidth, progressX] = progressWithByParams( changedTask.x1, @@ -616,6 +662,8 @@ const handleTaskBySVGMouseEventForBar = ( xStep, timeStep ); + changedTask.startHour && (changedTask.startHour = hourStringFromDate(changedTask.start, hasSeconds(changedTask.startHour))) + changedTask.endHour && (changedTask.endHour = hourStringFromDate(changedTask.end, hasSeconds(changedTask.endHour))) changedTask.x1 = newMoveX1; changedTask.x2 = newMoveX2; const [progressWidth, progressX] = progressWithByParams( @@ -626,6 +674,9 @@ const handleTaskBySVGMouseEventForBar = ( ); changedTask.progressWidth = progressWidth; changedTask.progressX = progressX; + if (changedTask.type === 'task') { + changedTask.y = svgY + } } break; } diff --git a/packages/ketchup/src/components/kup-planner/utils/helpers/other.helpers.ts b/packages/ketchup/src/components/kup-planner/utils/helpers/other.helpers.ts index 14c7102778..57b9e7b53f 100644 --- a/packages/ketchup/src/components/kup-planner/utils/helpers/other.helpers.ts +++ b/packages/ketchup/src/components/kup-planner/utils/helpers/other.helpers.ts @@ -63,3 +63,7 @@ export const sortTasks = (taskA: KupPlannerTask, taskB: KupPlannerTask) => { return 0; } }; + +export const createArrayFromNum = (number: number) => { + return Array.from({ length: number }, (_, index) => index); +} \ No newline at end of file diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-gantt-calendar/kup-gantt-calendar.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-gantt-calendar/kup-gantt-calendar.tsx index a1f4e297dc..a884773fd7 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-gantt-calendar/kup-gantt-calendar.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-gantt-calendar/kup-gantt-calendar.tsx @@ -3,6 +3,9 @@ import { KupPlannerCalendarProps } from '../../kup-planner-declarations'; import { getDaysInMonth, defaultDateTimeFormatters, + getCachedDateTimeFormat, + getLocalDayOfWeek, + getLocaleMonth, } from '../kup-planner-time-formatter'; @Component({ @@ -266,8 +269,56 @@ export class KupGanttCalendar { return [topValues, bottomValues]; } + getCalendarValuesForHour() { + const topValues: any[] = []; + const bottomValues: JSX.Element[] = []; + const topDefaultHeight = this.headerHeight * 0.5; + const dates = this.dateSetup.dates; + for (let i = 0; i < dates.length; i++) { + const date = dates[i]; + const bottomValue = getCachedDateTimeFormat(this.locale, { + hour: 'numeric', + }).format(date); + + bottomValues.push( + + {bottomValue} + + ); + if (i !== 0 && date.getDate() !== dates[i - 1].getDate()) { + const displayDate = dates[i - 1]; + const topValue = `${getLocalDayOfWeek( + displayDate, + this.locale, + 'long' + )}, ${displayDate.getDate()} ${getLocaleMonth( + displayDate, + this.locale + )}`; + const topPosition = (date.getHours() - 24) / 2; + topValues.push({ + key: (topValue as string) + date.getFullYear(), + value: topValue, + x1Line: this.columnWidth * i, + y1Line: 0, + y2Line: topDefaultHeight, + xText: this.columnWidth * (i + topPosition), + yText: topDefaultHeight * 0.9, + }); + } + } + return [topValues, bottomValues]; + } + getTopAndBottomValues() { switch (this.dateSetup.viewMode) { + case 'hour': + return this.getCalendarValuesForHour(); case 'day': return this.getCalendarValuesForDay(); case 'week': diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.scss b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.scss index d687393fb1..c36c8e7011 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.scss +++ b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.scss @@ -28,6 +28,16 @@ overflow: hidden; } +.horizontalContainerScrollable { + overflow: auto !important; + scrollbar-width: 0; +} + +.horizontalContainerScrollable::-webkit-scrollbar { + width: 0; + height: 0; +} + .task-gantt { overflow: hidden; } diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.tsx index 7a02ae2fb1..58468d77fa 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/kup-gantt.tsx @@ -60,7 +60,7 @@ export class KupGantt { columnWidth: KupPlannerGanttProps['columnWidth'] = 60; @Prop() - listCellWidth: KupPlannerGanttProps['listCellWidth'] = '297px'; + listCellWidth: KupPlannerGanttProps['listCellWidth'] = '300px'; @Prop() rowHeight: KupPlannerGanttProps['rowHeight'] = 50; @@ -207,6 +207,9 @@ export class KupGantt { @Prop() doubleView?: boolean; + @Prop() + scrollableTaskList?: boolean; + @Prop() setDoubleView?: (checked: boolean) => void; @@ -265,6 +268,9 @@ export class KupGantt { @Prop() expanderClick: KupPlannerGanttProps['expanderClick']; + @Prop() + phaseDrop: KupPlannerGanttProps['phaseDrop']; + /*-------------------------------------------------*/ /* S t a t e s */ /*-------------------------------------------------*/ @@ -338,6 +344,13 @@ export class KupGantt { color: string; } | undefined; + + + @State() + taskListScrollWidth: number; + + @State() + taskListScrollX: number = 0; /** * References the root HTML element of the component (). @@ -512,7 +525,7 @@ export class KupGantt { this.showSecondaryDates ); } - + @Watch('viewDate') @Watch('columnWidth') @Watch('dateSetup') @@ -643,6 +656,7 @@ export class KupGantt { newScrollX = this.svgWidth; } this.scrollX = newScrollX; + // this.taskListScrollX = newScrollX; window.dispatchEvent( new CustomEvent( 'gantt-sync-scroll-event', @@ -882,6 +896,15 @@ export class KupGantt { } } + handleTaskListScrollX(event: UIEvent) { + const currentTarget = event.currentTarget as HTMLDivElement; + this.taskListScrollX = currentTarget.scrollLeft + } + + handlePhaseDragScroll(scrollY: number) { + this.scrollY = scrollY + } + setFailedTask(task: KupPlannerBarTask | null) { this.failedTask = task; } @@ -946,6 +969,7 @@ export class KupGantt { barDblClick: this.barDblClick, barContextMenu: this.barContextMenu, delete: this.delete, + phaseDrop: this.phaseDrop }; const tableProps: KupPlannerTaskListProps = { @@ -965,7 +989,7 @@ export class KupGantt { setSelectedTask: this.handleSelectedTask.bind(this), expanderClick: this.handleExpanderClick.bind(this), TaskListHeader: this.TaskListHeader, - TaskListTable: this.TaskListTable, + TaskListTable: this.TaskListTable }; return ( @@ -990,6 +1014,12 @@ export class KupGantt { setDoubleView={this.setDoubleView} {...tableProps} class="tasks" + scrollableTaskList={this.scrollableTaskList} + updateTaskListScrollX={this.ignoreScrollEvent} + ontaskListScrollWidth={(width) => { + this.taskListScrollWidth = width + }} + taskListScrollX={this.taskListScrollX} ref={(el) => (this.taskListTrueRef = el)} /> )} @@ -1001,6 +1031,7 @@ export class KupGantt { taskGanttRef={this.taskGanttRef} scrollY={this.scrollY} scrollX={this.scrollX} + phaseDragScroll={this.handlePhaseDragScroll.bind(this)} class="ganttContainer" /> {this.ganttEvent.changedTask && ( @@ -1038,6 +1069,11 @@ export class KupGantt { scrollNumber={this.scrollX} rtl={this.rtl} horizontalScroll={this.handleScrollX.bind(this)} + horizontalTaskListScroll={this.handleTaskListScrollX.bind(this)} + listCellWidth={this.listCellWidth} + scrollableTaskList={this.scrollableTaskList} + taskListScrollWidth={this.taskListScrollWidth} + taskListScrollNumber={this.taskListScrollX} /> )}
diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/readme.md b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/readme.md index 1fd63c5816..d14b0aff3d 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-gantt/readme.md +++ b/packages/ketchup/src/components/kup-planner/utils/kup-gantt/readme.md @@ -51,8 +51,9 @@ | `initialScrollX` | `initial-scroll-x` | | `number` | `-1` | | `initialScrollY` | `initial-scroll-y` | | `number` | `0` | | `label` | `label` | | `string` | `undefined` | -| `listCellWidth` | `list-cell-width` | | `string` | `'297px'` | +| `listCellWidth` | `list-cell-width` | | `string` | `'300px'` | | `locale` | `locale` | | `string` | `'en-GB'` | +| `phaseDrop` | -- | | `(originalPhaseData: KupPlannerTask, originalTaskData: KupPlannerTask, finalPhaseData: KupPlannerTask, destinationData: KupPlannerTask) => boolean \| void \| Promise \| Promise` | `undefined` | | `preStepsCount` | `pre-steps-count` | | `number` | `1` | | `progressChange` | -- | | `(task: KupPlannerTask, children: KupPlannerTask[]) => boolean \| void \| Promise \| Promise` | `undefined` | | `projectBackgroundColor` | `project-background-color` | | `string` | `'#fac465'` | @@ -66,6 +67,7 @@ | `rtl` | `rtl` | | `boolean` | `false` | | `scrollXChange` | -- | | `(x: number) => void` | `undefined` | | `scrollYChange` | -- | | `(y: number) => void` | `undefined` | +| `scrollableTaskList` | `scrollable-task-list` | | `boolean` | `undefined` | | `select` | -- | | `(task: KupPlannerTask, isSelected: boolean) => void` | `undefined` | | `setDoubleView` | -- | | `(checked: boolean) => void` | `undefined` | | `showSecondaryDates` | `show-secondary-dates` | | `boolean` | `false` | @@ -75,7 +77,7 @@ | `timelineFill` | `timeline-fill` | | `number` | `40` | | `todayColor` | `today-color` | | `string` | `'#ff0000'` | | `viewDate` | -- | | `Date` | `undefined` | -| `viewMode` | `view-mode` | | `"day" \| "month" \| "week" \| "year"` | `'month'` | +| `viewMode` | `view-mode` | | `"day" \| "hour" \| "month" \| "week" \| "year"` | `'month'` | ## Methods diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.scss b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.scss index a8d12cc01f..5fb4541d46 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.scss +++ b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.scss @@ -58,3 +58,7 @@ user-select: none; pointer-events: none; } + +.ghost-preview { + opacity: 0.5; +} \ No newline at end of file diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.tsx index 3f7da20d73..d727ceb937 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/kup-grid-renderer.tsx @@ -11,6 +11,7 @@ import { KupPlannerTaskGanttProps, KupPlannerTaskItemProps, KupPlannerTaskIconProps, + defaultStylingOptions, } from '../../kup-planner-declarations'; import { addToDate } from '../kup-planner-renderer-helper'; import { @@ -121,9 +122,15 @@ export class KupGridRenderer { @Prop() eMouseDown: KupPlannerBarDisplayProps['onMouseDown']; + @Prop() + phaseDrop: KupPlannerEventOption['phaseDrop']; + @Prop({ mutable: true }) setGanttEvent: (gantt: KupPlannerGanttEvent) => void; + @Prop() + phaseDragScroll: (scrollY: number) => void; + /*-------------------------------------------------*/ /* S t a t e s */ /*-------------------------------------------------*/ @@ -145,6 +152,15 @@ export class KupGridRenderer { @State() svg: SVGSVGElement; + @State() + currentTarget: HTMLElement | null; + + @State() + dragScrollInterval: NodeJS.Timeout; + + @State() + dropZoneTask: KupPlannerBarTask | null; + //---- Lifecycle hooks ---- componentDidLoad() { @@ -192,6 +208,7 @@ export class KupGridRenderer { return; event.preventDefault(); this.point.x = event.clientX; + this.point.y = event.clientY; const cursor = this.point.matrixTransform( this.svg?.getScreenCTM()?.inverse() ); @@ -202,8 +219,16 @@ export class KupGridRenderer { this.xStep, this.timeStep, this.initEventX1Delta, - this.rtl + this.rtl, + cursor.y ); + + if (this.currentTarget) { + this.addGhostPreview(event); + this.handleAutoScrollForPhaseDrag(event); + this.addDropzoneVisualization(); + } + if (isChanged) { this.setGanttEvent({ ...this.ganttEvent, @@ -214,6 +239,8 @@ export class KupGridRenderer { }; const handleMouseUp = async (event: MouseEvent) => { + clearInterval(this.dragScrollInterval); + this.resetDropzoneVisualization(); const { action, originalSelectedTask, changedTask } = this.ganttEvent; if ( @@ -229,6 +256,7 @@ export class KupGridRenderer { const cursor = this.point.matrixTransform( this.svg?.getScreenCTM()?.inverse() ); + this.currentTarget = null; const { changedTask: newChangedTask } = handleTaskBySVGMouseEvent( cursor.x, action as KupPlannerBarMoveAction, @@ -236,23 +264,53 @@ export class KupGridRenderer { this.xStep, this.timeStep, this.initEventX1Delta, - this.rtl + this.rtl, + cursor.y ); const isNotLikeOriginal = originalSelectedTask.start !== newChangedTask.start || originalSelectedTask.end !== newChangedTask.end || - originalSelectedTask.progress !== newChangedTask.progress; + originalSelectedTask.progress !== newChangedTask.progress || + originalSelectedTask.y !== newChangedTask.y; // remove listeners this.svg.removeEventListener('mousemove', handleMouseMove); this.svg.removeEventListener('mouseup', handleMouseUp); + this.svg.querySelector('.ghost-preview')?.remove(); this.setGanttEvent({ action: '' }); this.isMoving = false; // custom operation start let operationSuccess: any = true; + + let droppedOn = undefined; + let originalTaskData = undefined; + if ( + action === 'move' && + isNotLikeOriginal && + newChangedTask.type === 'task' + ) { + droppedOn = this.tasks.find( + (task) => + this.isPhaseWithinTaskArea(changedTask, task) && + task.type === 'project' + ); + originalTaskData = this.tasks.find( + (task) => + task.id == originalSelectedTask.id.split('_').shift() + ); + } + + if (droppedOn?.id && originalTaskData?.id !== droppedOn?.id) { + this.phaseDrop( + originalSelectedTask, + originalTaskData, + newChangedTask, + droppedOn + ); + } else if ( (action === 'move' || action === 'end' || action === 'start') && this.dateChange && isNotLikeOriginal @@ -309,6 +367,141 @@ export class KupGridRenderer { return this.initEventXClick !== event.clientX; } + addGhostPreview(event: MouseEvent) { + this.svg.querySelector('.ghost-preview')?.remove(); + const mockEvent = { + ...event, + dataTransfer: new DataTransfer(), + } as DragEvent; + + const dragEle = this.currentTarget; + dragEle.classList.add('ghost-preview'); + this.svg.appendChild(dragEle.cloneNode(true)); + + const nodeRect = dragEle.getBoundingClientRect(); + mockEvent.dataTransfer.setDragImage( + dragEle, + mockEvent.clientX - nodeRect.left, + mockEvent.clientY - nodeRect.top + ); + } + + handleAutoScrollForPhaseDrag(event: MouseEvent) { + const list = this.svg?.parentElement?.parentElement; + if (!list) return; + clearInterval(this.dragScrollInterval); + const isOverFlowing = list.clientHeight < list.scrollHeight; + + if (isOverFlowing) { + // if container is overflowing we need to scroll within the container + const containerRect = list.getBoundingClientRect(); + const offsetY = event.clientY - containerRect.top; + const diff = 5; + if (offsetY - 20 < diff) { + this.dragScrollInterval = setInterval(() => { + this.phaseDragScroll((list.scrollTop -= diff)); + }, 1); + } else if (offsetY + 20 > containerRect.height - diff) { + this.dragScrollInterval = setInterval(() => { + this.phaseDragScroll((list.scrollTop += diff)); + }, 1); + } + } else { + // else we need to scroll the window when viewport exceeds + const scrollOffset = 20; + const windowHeight = window.innerHeight; + const y = event.clientY; + + if (y < scrollOffset) { + window.scrollBy(0, -scrollOffset); + } else if (y > windowHeight - scrollOffset) { + window.scrollBy(0, scrollOffset); + } + } + } + + isPhaseWithinTaskArea(phase: KupPlannerBarTask, task: KupPlannerBarTask) { + return ( + phase.y + phase.height >= task.ySecondary && + phase.y <= task.ySecondary + task.height && + phase.x2 >= task.x1 && + phase.x1 <= task.x2 + ); + } + + addDropzoneVisualization() { + this.resetDropzoneVisualization(); + // find the tasks where drop is allowed, includes all projects except parent project also includes current phase + const dropAllowedOn = this.tasks.filter( + (task) => + task.type == 'project' && + this.ganttEvent.originalSelectedTask?.id?.split('_')?.shift() != + task.id + ); + + const changedTask = this.ganttEvent.changedTask; + + // to determine whether the phase is in some another project y and x area + this.dropZoneTask = dropAllowedOn.find((task) => + this.isPhaseWithinTaskArea(changedTask, task) + ); + + if (this.dropZoneTask?.ySecondary) { + const rects = this.getBarRectsForDropzoneVisualization(); + rects.forEach((rect: Element) => { + rect.setAttribute( + 'fill', + defaultStylingOptions.barDropZoneColor + ); + }); + } + } + + resetDropzoneVisualization() { + if (!this.dropZoneTask) return; + const rects = this.getBarRectsForDropzoneVisualization(); + + const isSelected = + !!this.selectedTask && + this.dropZoneTask.id === this.selectedTask.id; + rects.forEach((rect: Element) => { + rect.setAttribute( + 'fill', + this.getBarColor(isSelected, this.dropZoneTask.styles) + ); + }); + } + + getBarRectsForDropzoneVisualization(): Element[] | NodeListOf { + let rects: Element[] | NodeListOf; + + if (!this.showSecondaryDates) { + rects = this.svg.querySelectorAll( + `.barWrapper[data-type="${this.dropZoneTask.type}"] rect[y='${this.dropZoneTask.ySecondary}']` + ); + } else { + const rect = this.svg.querySelector( + `.barWrapper[data-type="${this.dropZoneTask.type}"] rect[y='${this.dropZoneTask.ySecondary}']` + ); + const siblings = [rect]; + let nextSibling = rect.nextElementSibling; + while (nextSibling !== null) { + siblings.push(nextSibling); + nextSibling = nextSibling.nextElementSibling; + } + + let prevSibling = rect.previousElementSibling; + while (prevSibling !== null) { + siblings.unshift(prevSibling); + prevSibling = prevSibling.previousElementSibling; + } + + rects = siblings; + } + + return rects; + } + handleBarEventStart( action: KupPlannerGanttContentMoveAction, task: KupPlannerBarTask, @@ -360,7 +553,15 @@ export class KupGridRenderer { const cursor = this.point.matrixTransform( this.svg.getScreenCTM()?.inverse() ); + if (task.type === 'task') { + this.currentTarget = ( + event.currentTarget as HTMLElement + ).cloneNode(true) as HTMLElement; + } else { + this.currentTarget = null; + } this.initEventX1Delta = cursor.x - task.x1; + this.point.y = event.clientY; this.initEventXClick = event.clientX; this.setGanttEvent({ action, @@ -397,7 +598,7 @@ export class KupGridRenderer { isProgressChangeable: boolean ) { return ( - + {this.renderKupBarDisplay( task.x1, task.y, @@ -411,7 +612,8 @@ export class KupGridRenderer { !this.readOnly && !!this.dateChange && !task.isDisabled, task, task.x1secondary, - (task.x2secondary ?? 0) - (task.x1secondary ?? 0) + (task.x2secondary ?? 0) - (task.x1secondary ?? 0), + task.ySecondary )} {isDateResizable && ( @@ -478,7 +680,8 @@ export class KupGridRenderer { isDateMovable: KupPlannerTaskItemProps['isDateMovable'], task: KupPlannerBarTask, xSecondary?: KupPlannerBarDisplayProps['xSecondary'], - widthSecondary?: KupPlannerBarDisplayProps['widthSecondary'] + widthSecondary?: KupPlannerBarDisplayProps['widthSecondary'], + ySecondary?: KupPlannerBarDisplayProps['ySecondary'] ) { if (this.showSecondaryDates && typeof xSecondary !== 'undefined') { const halfHeight = height / 2; @@ -493,7 +696,7 @@ export class KupGridRenderer { key="top semi-transparent bar" x={xSecondary} width={widthSecondary} - y={y} + y={ySecondary ?? y} height={halfHeight} ry={barCornerRadius} rx={barCornerRadius} @@ -807,7 +1010,7 @@ export class KupGridRenderer { y += this.rowHeight; } - const now = new Date(); + // const now = new Date(); let tickX = 0; const ticks = []; for (let i = 0; i < this.dates.length; i++) { @@ -822,22 +1025,22 @@ export class KupGridRenderer { class="gridTick" /> ); - if ( - (i + 1 !== this.dates.length && - date.getTime() < now.getTime() && - this.dates[i + 1].getTime() >= now.getTime()) || - // if current date is last - (i !== 0 && - i + 1 === this.dates.length && - date.getTime() < now.getTime() && - addToDate( - date, - date.getTime() - this.dates[i - 1].getTime(), - 'millisecond' - ).getTime() >= now.getTime()) - ) { - // Add custom logic here if needed - } + // if ( + // (i + 1 !== this.dates.length && + // date.getTime() < now.getTime() && + // this.dates[i + 1].getTime() >= now.getTime()) || + // // if current date is last + // (i !== 0 && + // i + 1 === this.dates.length && + // date.getTime() < now.getTime() && + // addToDate( + // date, + // date.getTime() - this.dates[i - 1].getTime(), + // 'millisecond' + // ).getTime() >= now.getTime()) + // ) { + // // Add custom logic here if needed + // } tickX += this.columnWidth; } return ( @@ -1010,6 +1213,16 @@ export class KupGridRenderer { ); })} + {this.currentTarget && this.ganttEvent.changedTask && ( + + {this.renderKupBar( + this.ganttEvent.changedTask, + false, + false, + false + )} + + )} diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/readme.md b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/readme.md index 17eb90ef68..b15b36c7fb 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/readme.md +++ b/packages/ketchup/src/components/kup-planner/utils/kup-grid-renderer/readme.md @@ -7,39 +7,41 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ---------------------- | ---------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| `arrowColor` | `arrow-color` | | `string` | `''` | -| `arrowIndent` | `arrow-indent` | | `number` | `0` | -| `barClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | -| `barContextMenu` | -- | | `(event: UIEvent, task: KupPlannerTask) => void` | `undefined` | -| `barDblClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | -| `columnWidth` | `column-width` | | `number` | `0` | -| `currentDateIndicator` | -- | | `KupPlannerCurrentDateIndicator` | `undefined` | -| `dateChange` | -- | | `(task: KupPlannerTask, children: KupPlannerTask[]) => boolean \| void \| Promise \| Promise` | `undefined` | -| `dates` | -- | | `Date[]` | `undefined` | -| `delete` | -- | | `(task: KupPlannerTask) => boolean \| void \| Promise \| Promise` | `undefined` | -| `doubleClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | -| `eMouseDown` | -- | | `(event: MouseEvent) => void` | `undefined` | -| `eventStart` | -- | | `(action: KupPlannerGanttContentMoveAction, selectedTask: KupPlannerBarTask, event?: KeyboardEvent \| MouseEvent) => any` | `undefined` | -| `fontFamily` | `font-family` | | `string` | `''` | -| `fontSize` | `font-size` | | `string` | `''` | -| `ganttEvent` | -- | | `{ changedTask?: KupPlannerBarTask; originalSelectedTask?: KupPlannerBarTask; action: KupPlannerGanttContentMoveAction; }` | `undefined` | -| `gridProps` | -- | | `{ tasks: KupPlannerTask[]; dates: Date[]; svgWidth: number; rowHeight: number; columnWidth: number; todayColor: string; rtl: boolean; }` | `undefined` | -| `hideLabel` | `hide-label` | | `boolean` | `false` | -| `progressChange` | -- | | `(task: KupPlannerTask, children: KupPlannerTask[]) => boolean \| void \| Promise \| Promise` | `undefined` | -| `projection` | -- | | `{ x0: number; xf: number; color: string; }` | `undefined` | -| `readOnly` | `read-only` | | `boolean` | `false` | -| `rowHeight` | `row-height` | | `number` | `0` | -| `rtl` | `rtl` | | `boolean` | `false` | -| `selectedTask` | -- | | `KupPlannerBarTask` | `undefined` | -| `setFailedTask` | -- | | `(value: KupPlannerBarTask) => void` | `undefined` | -| `setGanttEvent` | -- | | `(gantt: KupPlannerGanttEvent) => void` | `undefined` | -| `setSelectedTask` | -- | | `(taskId: string) => void` | `undefined` | -| `showSecondaryDates` | `show-secondary-dates` | | `boolean` | `false` | -| `taskHeight` | `task-height` | | `number` | `0` | -| `tasks` | -- | | `KupPlannerBarTask[]` | `undefined` | -| `timeStep` | `time-step` | | `number` | `0` | +| Property | Attribute | Description | Type | Default | +| ---------------------- | ---------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| `arrowColor` | `arrow-color` | | `string` | `''` | +| `arrowIndent` | `arrow-indent` | | `number` | `0` | +| `barClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | +| `barContextMenu` | -- | | `(event: UIEvent, task: KupPlannerTask) => void` | `undefined` | +| `barDblClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | +| `columnWidth` | `column-width` | | `number` | `0` | +| `currentDateIndicator` | -- | | `KupPlannerCurrentDateIndicator` | `undefined` | +| `dateChange` | -- | | `(task: KupPlannerTask, children: KupPlannerTask[]) => boolean \| void \| Promise \| Promise` | `undefined` | +| `dates` | -- | | `Date[]` | `undefined` | +| `delete` | -- | | `(task: KupPlannerTask) => boolean \| void \| Promise \| Promise` | `undefined` | +| `doubleClick` | -- | | `(task: KupPlannerTask) => void` | `undefined` | +| `eMouseDown` | -- | | `(event: MouseEvent) => void` | `undefined` | +| `eventStart` | -- | | `(action: KupPlannerGanttContentMoveAction, selectedTask: KupPlannerBarTask, event?: KeyboardEvent \| MouseEvent) => any` | `undefined` | +| `fontFamily` | `font-family` | | `string` | `''` | +| `fontSize` | `font-size` | | `string` | `''` | +| `ganttEvent` | -- | | `{ changedTask?: KupPlannerBarTask; originalSelectedTask?: KupPlannerBarTask; action: KupPlannerGanttContentMoveAction; }` | `undefined` | +| `gridProps` | -- | | `{ tasks: KupPlannerTask[]; dates: Date[]; svgWidth: number; rowHeight: number; columnWidth: number; todayColor: string; rtl: boolean; }` | `undefined` | +| `hideLabel` | `hide-label` | | `boolean` | `false` | +| `phaseDragScroll` | -- | | `(scrollY: number) => void` | `undefined` | +| `phaseDrop` | -- | | `(originalPhaseData: KupPlannerTask, originalTaskData: KupPlannerTask, finalPhaseData: KupPlannerTask, destinationData: KupPlannerTask) => boolean \| void \| Promise \| Promise` | `undefined` | +| `progressChange` | -- | | `(task: KupPlannerTask, children: KupPlannerTask[]) => boolean \| void \| Promise \| Promise` | `undefined` | +| `projection` | -- | | `{ x0: number; xf: number; color: string; }` | `undefined` | +| `readOnly` | `read-only` | | `boolean` | `false` | +| `rowHeight` | `row-height` | | `number` | `0` | +| `rtl` | `rtl` | | `boolean` | `false` | +| `selectedTask` | -- | | `KupPlannerBarTask` | `undefined` | +| `setFailedTask` | -- | | `(value: KupPlannerBarTask) => void` | `undefined` | +| `setGanttEvent` | -- | | `(gantt: KupPlannerGanttEvent) => void` | `undefined` | +| `setSelectedTask` | -- | | `(taskId: string) => void` | `undefined` | +| `showSecondaryDates` | `show-secondary-dates` | | `boolean` | `false` | +| `taskHeight` | `task-height` | | `number` | `0` | +| `tasks` | -- | | `KupPlannerBarTask[]` | `undefined` | +| `timeStep` | `time-step` | | `number` | `0` | ## Dependencies diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.scss b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.scss index d853712ca0..29331519b3 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.scss +++ b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.scss @@ -35,3 +35,6 @@ .scroll { height: 1px; } +.scroll-container { + display: flex; +} \ No newline at end of file diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.tsx index 9b0f6e21c9..1271267d5c 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/kup-horizontal-scroll.tsx @@ -1,4 +1,12 @@ -import { Component, h, Element, Prop, State, Watch } from '@stencil/core'; +import { + Component, + h, + Element, + Prop, + State, + Watch, + Fragment, +} from '@stencil/core'; @Component({ tag: 'kup-horizontal-scroll', @@ -24,9 +32,24 @@ export class HorizontalScroll { @Prop() taskListWidth: number; + @Prop() + scrollableTaskList: boolean = false; + + @Prop() + listCellWidth: string = '300px'; + + @Prop() + taskListScrollWidth: number; + + @Prop() + taskListScrollNumber: number; + @Prop() horizontalScroll: (event: UIEvent) => void; + @Prop() + horizontalTaskListScroll: (event: UIEvent) => void; + /** * References the root HTML element of the component (). */ @@ -54,31 +77,84 @@ export class HorizontalScroll { }, 50); } + @Watch('taskListScrollNumber') + listScrollLeft() { + clearTimeout(this.timeoutId); + this.timeoutId = setTimeout(() => { + this.setTaskListScrollLeft(); + }, 50); + } + private setScrollLeft() { if (this.rootElement) { - this.rootElement.shadowRoot.querySelector('div').scrollLeft = - this.scrollNumber; + const shadowElement = + this.rootElement.shadowRoot.querySelector('div'); + const element = + shadowElement.children.length == 2 + ? shadowElement.children[1] + : shadowElement.children[0]; + element && (element.scrollLeft = this.scrollNumber); + } + } + + private setTaskListScrollLeft() { + if (this.rootElement) { + const shadowElement = this.rootElement.shadowRoot.querySelector('div'); + const taskListScrollBar = shadowElement.children.length == 2 ? shadowElement.children[0] : null; + taskListScrollBar && (taskListScrollBar.scrollLeft = this.taskListScrollNumber); } } render() { const w = - this.taskListTrueRef?.getBoundingClientRect().width + 24 * 1.5 ?? 0; // 24 * 2 is the sum of padding and margin for both list and gantt, multiplied by 1.5 cause we need to add the other half to the right - + this.taskListTrueRef?.getBoundingClientRect().width + 24 * 1.5 ?? 0; // 24 * 2 is the sum of padding and margin for both list and gantt, multiplied by 1.5 cause we need to add the other half to the right + + const width = +this.listCellWidth.replace('px', ''); + return ( -
-
-
+ +
+ {this.scrollableTaskList && + this.taskListScrollWidth > width && ( +
+
+
+ )} +
width ? 40 : w}px 0px 12px` + : `0px 12px 0px ${this.scrollableTaskList && this.taskListScrollWidth > width ? 40 : w}px`, + }} + class="scrollWrapper" + data-scrollx="true" + onScroll={this.horizontalScroll} + > +
+
+
+ ); } } diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/readme.md b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/readme.md index 21eff1d6aa..4e4d6bb08b 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/readme.md +++ b/packages/ketchup/src/components/kup-planner/utils/kup-horizontal-scroll/readme.md @@ -7,14 +7,19 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------ | ----------------- | ----------- | -------------------------- | ----------- | -| `horizontalScroll` | -- | | `(event: UIEvent) => void` | `undefined` | -| `rtl` | `rtl` | | `boolean` | `undefined` | -| `scrollNumber` | `scroll-number` | | `number` | `undefined` | -| `svgWidth` | `svg-width` | | `number` | `undefined` | -| `taskListTrueRef` | -- | | `HTMLKupTaskListElement` | `undefined` | -| `taskListWidth` | `task-list-width` | | `number` | `undefined` | +| Property | Attribute | Description | Type | Default | +| -------------------------- | ------------------------- | ----------- | -------------------------- | ----------- | +| `horizontalScroll` | -- | | `(event: UIEvent) => void` | `undefined` | +| `horizontalTaskListScroll` | -- | | `(event: UIEvent) => void` | `undefined` | +| `listCellWidth` | `list-cell-width` | | `string` | `'300px'` | +| `rtl` | `rtl` | | `boolean` | `undefined` | +| `scrollNumber` | `scroll-number` | | `number` | `undefined` | +| `scrollableTaskList` | `scrollable-task-list` | | `boolean` | `false` | +| `svgWidth` | `svg-width` | | `number` | `undefined` | +| `taskListScrollNumber` | `task-list-scroll-number` | | `number` | `undefined` | +| `taskListScrollWidth` | `task-list-scroll-width` | | `number` | `undefined` | +| `taskListTrueRef` | -- | | `HTMLKupTaskListElement` | `undefined` | +| `taskListWidth` | `task-list-width` | | `number` | `undefined` | ## Dependencies diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer-helper.ts b/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer-helper.ts index 133d38da00..031b11a593 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer-helper.ts +++ b/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer-helper.ts @@ -76,19 +76,19 @@ export const isDetail = ( export const mergeTaskIntoProjects = ( projects: KupPlannerGanttTask[], - { id, start, end }: KupPlannerTask + { id, start, end, startHour, endHour }: KupPlannerTask ): KupPlannerGanttTask[] => projects.map((project) => - project.id === id ? withNewDates(project, start, end) : project + project.id === id ? withNewDates(project, start, end, startHour, endHour) : project ); export const mergeTaskIntoPhases = ( phases: KupPlannerPhaseGantt[] | undefined, - { id, start, end }: KupPlannerTask + { id, start, end, startHour, endHour }: KupPlannerTask ): KupPlannerPhaseGantt[] | undefined => { if (phases) { return phases.map((phase) => - phase.id === id ? withNewDates(phase, start, end) : phase + phase.id === id ? withNewDates(phase, start, end, startHour, endHour) : phase ); } return undefined; @@ -139,6 +139,10 @@ export const convertProjectToTasks = ( isDisabled: false, hideChildren: false, icon: row.icon, + startHour: item.startHour, + endHour: item.endHour, + secondaryStartHour: item.secondaryStartHour, + secondaryEndHour: item.secondaryEndHour }; const children1 = (row.phases ?? []).map(convertPhaseToTask); return [mainTask, ...children1]; @@ -168,6 +172,10 @@ export const convertPhaseToTask = (item: KupPlannerPhase): KupPlannerTask => { selectedColor, dependencies, icon, + startHour, + endHour, + secondaryStartHour, + secondaryEndHour, }: KupPlannerPhase): KupPlannerTask => { const kupDates: KupDates = new KupDates(); const { start, end } = kupDates.validDates( @@ -203,6 +211,10 @@ export const convertPhaseToTask = (item: KupPlannerPhase): KupPlannerTask => { } : {}, icon, + startHour, + endHour, + secondaryStartHour, + secondaryEndHour, }; }; @@ -278,12 +290,14 @@ const convertDetailToTimeline = ( const withNewDates =

( p: P, start: Date, - end: Date + end: Date, + startHour: string, + endHour: string ): P => { const kupDates: KupDates = new KupDates(); const startDate = kupDates.formatToIsoDate(start); const endDate = kupDates.formatToIsoDate(end); - const extra = { startDate, endDate }; + const extra = { startDate, endDate, startHour, endHour }; return { ...p, ...extra }; }; @@ -340,6 +354,10 @@ export const ganttDateRangeFromGanttTask = ( end: Date; secondaryStart?: Date; secondaryEnd?: Date; + startHour?: string, + endHour?: string, + secondaryStartHour?: string, + secondaryEndHour?: string }[] = []; const kupDates: KupDates = new KupDates(); tasks.forEach((item) => { @@ -348,6 +366,10 @@ export const ganttDateRangeFromGanttTask = ( end: kupDates.parseToDayEnd(item.endDate), secondaryStart: kupDates.parseToDayStart(item.secondaryStartDate), secondaryEnd: kupDates.parseToDayEnd(item.secondaryEndDate), + startHour: item.startHour, + endHour: item.endHour, + secondaryStartHour: item.secondaryStartHour, + secondaryEndHour: item.secondaryEndHour }); item.phases?.forEach((phase) => { dates.push({ @@ -357,6 +379,10 @@ export const ganttDateRangeFromGanttTask = ( phase.secondaryStartDate ), secondaryEnd: kupDates.parseToDayEnd(phase.secondaryEndDate), + startHour: item.startHour, + endHour: item.endHour, + secondaryStartHour: item.secondaryStartHour, + secondaryEndHour: item.secondaryEndHour }); }); }); @@ -375,6 +401,10 @@ export const ganttDateRangeGeneric = ( end: Date; secondaryStart?: Date; secondaryEnd?: Date; + startHour?: string, + endHour?: string, + secondaryStartHour?: string, + secondaryEndHour?: string }[], viewMode: KupPlannerViewMode, preStepsCount: number, @@ -431,6 +461,32 @@ export const ganttDateRangeGeneric = ( newEndDate = startOfDate(newEndDate, 'day'); newEndDate = addToDate(newEndDate, 19, 'day'); break; + case 'hour': + newStartDate = startOfDate(newStartDate, "hour"); + newStartDate = addToDate(newStartDate, -1 * preStepsCount, "hour"); + newEndDate = startOfDate(newEndDate, "day"); + newEndDate = addToDate(newEndDate, 1, "day"); + break; + /* + case ViewMode.QuarterDay: + newStartDate = startOfDate(newStartDate, "day"); + newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day"); + newEndDate = startOfDate(newEndDate, "day"); + newEndDate = addToDate(newEndDate, 66, "hour"); // 24(1 day)*3 - 6 + break; + case ViewMode.HalfDay: + newStartDate = startOfDate(newStartDate, "day"); + newStartDate = addToDate(newStartDate, -1 * preStepsCount, "day"); + newEndDate = startOfDate(newEndDate, "day"); + newEndDate = addToDate(newEndDate, 108, "hour"); // 24(1 day)*5 - 12 + break; + case ViewMode.Hour: + newStartDate = startOfDate(newStartDate, "hour"); + newStartDate = addToDate(newStartDate, -1 * preStepsCount, "hour"); + newEndDate = startOfDate(newEndDate, "day"); + newEndDate = addToDate(newEndDate, 1, "day"); + break; + */ } return [newStartDate, newEndDate]; }; @@ -446,6 +502,10 @@ export const ganttDateRangeFromDetail = ( end: Date; secondaryStart?: Date; secondaryEnd?: Date; + startHour?: string, + endHour?: string, + secondaryStartHour?: string, + secondaryEndHour?: string }[] = []; const kupDates: KupDates = new KupDates(); details.forEach((item) => { @@ -537,6 +597,10 @@ export const ganttDateRangeFromTask = ( end: Date; secondaryStart?: Date; secondaryEnd?: Date; + startHour?: string, + endHour?: string, + secondaryStartHour?: string, + secondaryEndHour?: string }[] = []; tasks.forEach((item) => { @@ -545,6 +609,10 @@ export const ganttDateRangeFromTask = ( end: item.end, secondaryStart: item.secondaryStart, secondaryEnd: item.secondaryEnd, + startHour:item.startHour, + endHour: item.endHour, + secondaryStartHour: item.secondaryStartHour, + secondaryEndHour: item.secondaryEndHour }); }); if (mainGanttStartDate && mainGanttEndDate) { @@ -584,6 +652,9 @@ export const seedDates = ( case 'day': currentDate = addToDate(currentDate, 1, 'day'); break; + case 'hour': + currentDate = addToDate(currentDate, 1, "hour"); + break; /* case ViewMode.HalfDay: currentDate = addToDate(currentDate, 12, "hour"); diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer.tsx index fc6dcc6dca..68e68d544e 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-planner-renderer.tsx @@ -166,7 +166,7 @@ export class KupPlannerRenderer { this.timeUnit = this.props?.viewMode; this.currentTasks = this.props?.mainGantt.items || []; this.currentDetails = this.props?.secondaryGantt?.items; - this.scrollX = this.props?.mainGantt?.initialScrollX || -1; + this.scrollX = this.props?.mainGantt?.initialScrollX ?? -1; this.mainGanttDoubleView = this.props?.mainGantt?.showSecondaryDates ?? false; this.displayedDates = calculateDisplayedDateRange( @@ -330,6 +330,50 @@ export class KupPlannerRenderer { setTimeout(this.getScrollX, 500); } + // Handle phase drop + handlePhaseDrop( + originalPhaseData: KupPlannerGanttTaskN, + // originalTaskData: KupPlannerGanttTaskN | KupPlannerItemDetail, + finalPhaseData: KupPlannerTask, + destinationData: KupPlannerGanttTaskN | KupPlannerItemDetail, + onPhaseDrop: any + ) { + // Invoke callback + + let row = undefined; + + const currentProjects = this.currentTasks as KupPlannerGanttTask[]; + + const parentOfClickedPhase: KupPlannerGanttTaskN | undefined = ( + currentProjects as KupPlannerGanttTaskN[] + ).find((p) => p.phases?.some((ph) => ph?.id === finalPhaseData.id)); + if (parentOfClickedPhase) { + const phases = mergeTaskIntoPhases( + parentOfClickedPhase.phases, + finalPhaseData + ); + const updatedProjects = ( + currentProjects as KupPlannerGanttTaskN[] + ).map((p) => + p.id === parentOfClickedPhase.id ? { ...p, phases } : p + ); + row = getPhaseById(finalPhaseData.id, updatedProjects); + } + + delete row?.['taskRow']; + onPhaseDrop?.({ + originalPhaseData, + // originalTaskData, + finalPhaseData: row, + destinationData, + }); + + // to move the phase back to its original position + this.currentTasks = JSON.parse(JSON.stringify(this.currentTasks)); + // Use setTimeout to ensure DOM updates + setTimeout(this.getScrollX, 500); + } + // Get scrollX getScrollX() { if (this.rootElement) { @@ -475,6 +519,37 @@ export class KupPlannerRenderer { label={this.props.mainGantt.title} doubleView={this.mainGanttDoubleView ?? false} setDoubleView={this.handleSetDoubleView.bind(this)} + scrollableTaskList={this.props.scrollableTaskList} + phaseDrop={( + originalPhaseData, + originalTaskData, + finalPhaseData, + destinationData + ) => { + const originalPhase = getPhaseById( + originalPhaseData.id, + this.currentTasks + ); + const originalTask = getProjectById( + originalTaskData.id, + this.currentTasks + ); + const finalPhase = getPhaseById( + finalPhaseData.id, + this.currentTasks + ); + const destinationTask = getProjectById( + destinationData.id, + this.currentTasks + ); + this.handlePhaseDrop( + originalPhase, + // originalTask, + finalPhaseData, + destinationTask, + this.props.mainGantt.onPhaseDrop + ); + }} /> {this.props.secondaryGantt && ( )}

diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.scss b/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.scss index 76af7e5b34..9213fbef5a 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.scss +++ b/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.scss @@ -2,31 +2,32 @@ display: grid; grid-auto-flow: column; grid-gap: 8px; - margin-left: 12px; width: max-content; + margin-bottom: var(--kup-space-05); + margin-left: var(--kup-space-04); } .button { - background: transparent; - border-color: var(--kup-primary-color, #003b77); - border-radius: 4px; - border-width: 1px; - box-shadow: 0 3px 1px -2px rgba(var(--kup-text-color-rgb, 51 51 51), 0.2), - 0 2px 2px 0 rgba(var(--kup-text-color-rgb, 51 51 51), 0.14), - 0 1px 5px 0 rgba(var(--kup-text-color-rgb, 51 51 51), 0.12); + background-color: var(--kup-gray-color-70); + border: none; + text-align: left; box-sizing: border-box; - color: var(--kup-primary-color, #003b77); + color: var(--kup-gray-color-0); cursor: pointer; - font-size: 11px; - height: 32px; - min-width: 64px; + padding: var(--kup-space-03) var(--kup-space-05); + &:hover { + background-color: var(--kup-gray-color-90); + } + &:focus{ + background-color: var(--kup-primary-color-60); + } } .label { - font-family: var(--kup-font-family, inherit); - font-size: 11px; - letter-spacing: 0.0892857143em; text-decoration: none; - text-transform: uppercase; - padding: 0 6px; + @include kup-body-compact-01; +} + +.buttonActive { + background-color: var(--kup-primary-color-60); } diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.tsx index 63004f3da7..56a0eed0d4 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-switcher/kup-switcher.tsx @@ -1,5 +1,9 @@ -import { Component, h, Prop } from '@stencil/core'; -import { KupPlannerSwitcherProps } from '../../kup-planner-declarations'; +import { Component, h, Prop, State } from '@stencil/core'; +import { + KupPlannerSwitcherProps, + KupPlannerViewMode, +} from '../../kup-planner-declarations'; + @Component({ tag: 'kup-switcher', styleUrl: 'kup-switcher.scss', @@ -9,29 +13,43 @@ export class KupSwitcher { /*-------------------------------------------------*/ /* P r o p s */ /*-------------------------------------------------*/ + @Prop() timeUnitChange: KupPlannerSwitcherProps['onTimeUnitChange']; - @Prop() - timeUnitChange: KupPlannerSwitcherProps['onTimeUnitChange']; + /*-------------------------------------------------*/ + /* S t a t e s */ + /*-------------------------------------------------*/ + @State() activeButton: KupPlannerViewMode = 'day'; // Impostato su 'day' inizialmente + + private buttonLabels: KupPlannerViewMode[] = [ + 'hour', + 'day', + 'week', + 'month', + 'year', + ]; render() { - const day = () => this.timeUnitChange('day'); - const week = () => this.timeUnitChange('week'); - const month = () => this.timeUnitChange('month'); - const year = () => this.timeUnitChange('year'); + const handleButtonClick = (mode: KupPlannerViewMode) => { + this.activeButton = mode; + this.timeUnitChange(mode); + }; + return (
- - - - + {this.buttonLabels.map((label) => ( + + ))}
); } diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-task-gantt/kup-task-gantt.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-task-gantt/kup-task-gantt.tsx index 3da6c3e37d..304104d767 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-task-gantt/kup-task-gantt.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-task-gantt/kup-task-gantt.tsx @@ -30,6 +30,9 @@ export class TaskGantt { @Prop({ mutable: true }) scrollX: KupPlannerTaskGanttProps['scrollX']; + @Prop() + phaseDragScroll: (scrollY: number) => void; + /** * References the root HTML element of the component (). */ @@ -74,7 +77,7 @@ export class TaskGantt { } render() { - const newBarProps = { ...this.barProps, gridProps: this.gridProps }; + const newBarProps = { ...this.barProps, gridProps: this.gridProps, phaseDragScroll: this.phaseDragScroll }; return (
void; setFailedTask: (value: KupPlannerBarTask) => void; setSelectedTask: (taskId: string) => void; } & KupPlannerEventOption` | `undefined` | -| `calendarProps` | -- | | `{ dateSetup: KupPlannerDateSetup; locale: string; viewMode: KupPlannerViewMode; rtl: boolean; headerHeight: number; columnWidth: number; fontFamily: string; fontSize: string; dateTimeFormatters?: KupPlannerDateTimeFormatters; singleLineHeader: boolean; currentDateIndicator?: KupPlannerCurrentDateIndicator; }` | `undefined` | -| `ganttHeight` | `gantt-height` | | `number` | `undefined` | -| `gridProps` | -- | | `{ tasks: KupPlannerTask[]; dates: Date[]; svgWidth: number; rowHeight: number; columnWidth: number; todayColor: string; rtl: boolean; }` | `undefined` | -| `scrollX` | `scroll-x` | | `number` | `undefined` | -| `scrollY` | `scroll-y` | | `number` | `undefined` | -| `taskGanttRef` | -- | | `HTMLDivElement` | `undefined` | +| Property | Attribute | Description | Type | Default | +| ----------------- | -------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `barProps` | -- | | `{ tasks: KupPlannerBarTask[]; dates: Date[]; ganttEvent: KupPlannerGanttEvent; selectedTask: KupPlannerBarTask; rowHeight: number; columnWidth: number; timeStep: number; svg?: SVGSVGElement; svgWidth: number; taskHeight: number; arrowColor: string; arrowIndent: number; fontSize: string; fontFamily: string; rtl: boolean; ganttHeight: number; hideLabel?: boolean; showSecondaryDates?: boolean; currentDateIndicator?: KupPlannerCurrentDateIndicator; projection?: { x0: number; xf: number; color: string; }; readOnly: boolean; setGanttEvent: (value: KupPlannerGanttEvent) => void; setFailedTask: (value: KupPlannerBarTask) => void; setSelectedTask: (taskId: string) => void; } & KupPlannerEventOption` | `undefined` | +| `calendarProps` | -- | | `{ dateSetup: KupPlannerDateSetup; locale: string; viewMode: KupPlannerViewMode; rtl: boolean; headerHeight: number; columnWidth: number; fontFamily: string; fontSize: string; dateTimeFormatters?: KupPlannerDateTimeFormatters; singleLineHeader: boolean; currentDateIndicator?: KupPlannerCurrentDateIndicator; }` | `undefined` | +| `ganttHeight` | `gantt-height` | | `number` | `undefined` | +| `gridProps` | -- | | `{ tasks: KupPlannerTask[]; dates: Date[]; svgWidth: number; rowHeight: number; columnWidth: number; todayColor: string; rtl: boolean; }` | `undefined` | +| `phaseDragScroll` | -- | | `(scrollY: number) => void` | `undefined` | +| `scrollX` | `scroll-x` | | `number` | `undefined` | +| `scrollY` | `scroll-y` | | `number` | `undefined` | +| `taskGanttRef` | -- | | `HTMLDivElement` | `undefined` | ## Dependencies diff --git a/packages/ketchup/src/components/kup-planner/utils/kup-task-list/kup-task-list.tsx b/packages/ketchup/src/components/kup-planner/utils/kup-task-list/kup-task-list.tsx index 86e031cb1d..a6f4d670e9 100644 --- a/packages/ketchup/src/components/kup-planner/utils/kup-task-list/kup-task-list.tsx +++ b/packages/ketchup/src/components/kup-planner/utils/kup-task-list/kup-task-list.tsx @@ -17,6 +17,7 @@ import { getPhaseById, getProjectById } from '../kup-planner-renderer-helper'; shadow: false, }) export class TaskList { + /*-------------------------------------------------*/ /* P r o p s */ /*-------------------------------------------------*/ @@ -71,6 +72,15 @@ export class TaskList { @Prop() doubleView?: boolean; + @Prop() + scrollableTaskList?: boolean; + + @Prop() + updateTaskListScrollX: boolean = false; + + @Prop() + taskListScrollX: number; + @Prop() setDoubleView?: (checked: boolean) => void; @@ -102,6 +112,9 @@ export class TaskList { @Prop() expanderClick: KupPlannerTaskListProps['expanderClick']; + @Prop() + ontaskListScrollWidth: (width: number) => void; + /** * References the root HTML element of the component (). */ @@ -165,6 +178,7 @@ export class TaskList { tasks: this.tasks, locale: this.locale, selectedTaskId: this.selectedTaskId, + scrollableTaskList: this.scrollableTaskList, setSelectedTask: this.setSelectedTask.bind(this), onExpanderClick: this.expanderClick, }; @@ -192,7 +206,7 @@ export class TaskList { /> )}
{ + this.ontaskListScrollWidth(width) + }} + taskListScrollX={this.taskListScrollX} ganttId={KUP_PLANNER_MAIN_GANTT_ID} /> )} diff --git a/packages/ketchup/src/f-components/f-image/f-image.tsx b/packages/ketchup/src/f-components/f-image/f-image.tsx index 938375bb9a..cd93272629 100644 --- a/packages/ketchup/src/f-components/f-image/f-image.tsx +++ b/packages/ketchup/src/f-components/f-image/f-image.tsx @@ -52,9 +52,7 @@ export const FImage: FunctionalComponent = ( return (
-1) { let themeIcon: string = props.resource.replace('--', ''); diff --git a/packages/ketchup/src/image-list.html b/packages/ketchup/src/image-list.html index e93f7b7ceb..7c2f42effe 100644 --- a/packages/ketchup/src/image-list.html +++ b/packages/ketchup/src/image-list.html @@ -27,5 +27,11 @@ + diff --git a/packages/ketchup/src/managers/kup-theme/themes.json b/packages/ketchup/src/managers/kup-theme/themes.json index c0f4070a44..b815209b19 100644 --- a/packages/ketchup/src/managers/kup-theme/themes.json +++ b/packages/ketchup/src/managers/kup-theme/themes.json @@ -12,7 +12,7 @@ "--kup-primary-color-70": "#006574", "--kup-primary-color-80": "#005160", "--kup-primary-color-90": "#02292f", - "--kup-secondary-color-2": "#003C49", + "--kup-secondary-color": "#003C49", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -23,7 +23,6 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", @@ -33,18 +32,16 @@ "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-secondary-color": "#f4a22e", "--kup-background-color": "#ffffff", - "--kup-navbar-background-color": "#068a9c", - "--kup-navbar-color": "#ffffff", - "--kup-drawer-background-color": "#ffffff", + "--kup-navbar-background-color": "#161616", + "--kup-drawer-background-color": "#f4f4f4", "--kup-drawer-color": "#535353", "--kup-navbar-height": "64px", "--kup-drawer-width": "300px", "--kup-font-family": "IBM Plex Sans, sans-serif", - "--kup-font-family-monospace": "IBM Plex Sans, sans-serif", + "--kup-font-family-monospace": "IBM Plex Mono, monospace", "--kup-font-size": "14px", - "--kup-text-color": "#474747", + "--kup-text-color": "#525252", "--kup-text-on-primary-color": "#e8e8e8", "--kup-text-on-secondary-color": "#312c2c", "--kup-disabled-background-color": "#d1d1d1", @@ -53,13 +50,9 @@ "--kup-hover-color": "#303030", "--kup-title-background-color": "#068a9c", "--kup-title-color": "#fff", - "--kup-icon-color": "#e8e8e8", + "--kup-icon-color": "#636363", "--kup-border-color": "#d8d8d8", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", - "--kup-info-color": "#2592df", - "--kup-success-color": "#a4ba4c", - "--kup-warning-color": "#de8906", - "--kup-danger-color": "#a6192e", "--kup-spinner-color": "#fddc69", "--kup-chart-color-1": "#60c3fc", "--kup-chart-color-2": "#e268d8", @@ -84,6 +77,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -103,10 +97,22 @@ ], "customStyles": {} }, - "bubbles": { + "octaneGrey": { "cssVariables": { - "--kup-gray-color-0": "#ffffff", - "--kup-gray-color-10": "#F4F4F4", + "--kup-primary-color": "#068a9c", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-10": "#A5E6F0", + "--kup-primary-color-20": "#83CBD8", + "--kup-primary-color-30": "#5CB0C0", + "--kup-primary-color-40": "#3E9EAF", + "--kup-primary-color-50": "#068A9C", + "--kup-primary-color-60": "#007A8B", + "--kup-primary-color-70": "#006574", + "--kup-primary-color-80": "#005160", + "--kup-primary-color-90": "#02292f", + "--kup-secondary-color": "#003C49", + "--kup-gray-color-0": "#F4F4F4", + "--kup-gray-color-10": "#ffffff", "--kup-gray-color-20": "#E0E0E0", "--kup-gray-color-30": "#C6C6C6", "--kup-gray-color-40": "#A8A8A8", @@ -115,18 +121,330 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", + "--kup-info-color-50": "#4589ff", + "--kup-info-color-70": "#0043ce", + "--kup-warning-color-40": "#f1c21b", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", + "--kup-background-color": "#F4F4F4", + "--kup-navbar-background-color": "#161616", + "--kup-drawer-background-color": "#ffffff", + "--kup-drawer-color": "#535353", + "--kup-navbar-height": "64px", + "--kup-drawer-width": "300px", + "--kup-font-family": "IBM Plex Sans, sans-serif", + "--kup-font-family-monospace": "IBM Plex Mono, monospace", + "--kup-font-size": "14px", + "--kup-text-color": "#292929", + "--kup-text-on-primary-color": "#e8e8e8", + "--kup-text-on-secondary-color": "#312c2c", + "--kup-disabled-background-color": "#d1d1d1", + "--kup-disabled-color": "#636363", + "--kup-hover-background-color": "#e8e8e8", + "--kup-hover-color": "#303030", + "--kup-title-background-color": "#068a9c", + "--kup-title-color": "#fff", + "--kup-icon-color": "#636363", + "--kup-border-color": "#d8d8d8", + "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", + "--kup-info-color": "#2592df", + "--kup-success-color-40": "#42be65", + "--kup-success-color-60": "#198038", + "--kup-rating-color": "#ffa000", + "--kup-warning-color": "#de8906", + "--kup-danger-color-50": "#fa4d56", + "--kup-danger-color-60": "#da1e28", + "--kup-danger-color-70": "#ba1b23", + "--kup-danger-color-80": "#750e13", + "--kup-spinner-color": "#fddc69", + "--kup-chart-color-1": "#60c3fc", + "--kup-chart-color-2": "#e268d8", + "--kup-chart-color-3": "#860bb5", + "--kup-chart-color-4": "#1a83e4", + "--kup-obj-cursor": "inherit", + "--kup-card-zindex": "900", + "--kup-drawer-zindex": "900", + "--kup-navbar-zindex": "900", + "--kup-space-00": "0px", + "--kup-space-01": "2px", + "--kup-space-02": "4px", + "--kup-space-03": "8px", + "--kup-space-04": "12px", + "--kup-space-05": "16px", + "--kup-space-06": "24px", + "--kup-space-07": "32px", + "--kup-space-08": "40px", + "--kup-space-09": "48px", + "--kup-space-10": "64px", + "--kup-space-11": "80px", + "--kup-space-12": "96px", + "--kup-space-13": "160px", + "--kup-radius-00": "0px", + "--kup-radius-01": "2px", + "--kup-radius-100": "100px" + }, + "icons": { + "--kup-ascending-icon": "arrow_drop_up", + "--kup-descending-icon": "arrow_drop_down", + "--kup-expanded-icon": "arrow_drop_down", + "--kup-collapsed-icon": "menu-right", + "--kup-dropdown-icon": "arrow_drop_down", + "--kup-clear-icon": "cancel", + "--kup-filter-remove-icon": "filter-remove", + "--kup-key-icon": "key-variant", + "--kup-search-icon": "search" + }, + "imports": [ + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')", + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')" + ], + "customStyles": {} + }, + "darkOctane": { + "cssVariables": { + "--kup-primary-color": "#068a9c", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-10": "#A5E6F0", + "--kup-primary-color-20": "#83CBD8", + "--kup-primary-color-30": "#5CB0C0", + "--kup-primary-color-40": "#3E9EAF", + "--kup-primary-color-50": "#068A9C", + "--kup-primary-color-60": "#007A8B", + "--kup-primary-color-70": "#006574", + "--kup-primary-color-80": "#005160", + "--kup-primary-color-90": "#02292f", + "--kup-secondary-color": "#003C49", + "--kup-gray-color-0": "#161616", + "--kup-gray-color-10": "#262626", + "--kup-gray-color-20": "#393939", + "--kup-gray-color-30": "#525252", + "--kup-gray-color-40": "#6f6f6f", + "--kup-gray-color-50": "#8d8d8d", + "--kup-gray-color-60": "#A8A8A8", + "--kup-gray-color-70": "#C6C6C6", + "--kup-gray-color-80": "#E0E0E0", + "--kup-gray-color-90": "#f4f4f4", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", + "--kup-background-color": "#161616", + "--kup-navbar-background-color": "#161616", + "--kup-drawer-background-color": "#ffffff", + "--kup-drawer-color": "#535353", + "--kup-navbar-height": "64px", + "--kup-drawer-width": "300px", + "--kup-font-family": "IBM Plex Sans, sans-serif", + "--kup-font-family-monospace": "IBM Plex Mono, monospace", + "--kup-font-size": "14px", + "--kup-text-color": "#e8e8e8", + "--kup-text-on-primary-color": "#e8e8e8", + "--kup-text-on-secondary-color": "#312c2c", + "--kup-disabled-background-color": "#d1d1d1", + "--kup-disabled-color": "#636363", + "--kup-hover-background-color": "#e8e8e8", + "--kup-hover-color": "#303030", + "--kup-title-background-color": "#068a9c", + "--kup-title-color": "#fff", + "--kup-icon-color": "#636363", + "--kup-border-color": "#d8d8d8", + "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", + "--kup-info-color": "#2592df", + "--kup-success-color-60": "#42be65", + "--kup-success-color-40": "#198038", + "--kup-rating-color": "#ffa000", + "--kup-warning-color": "#de8906", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", + "--kup-spinner-color": "#fddc69", + "--kup-chart-color-1": "#60c3fc", + "--kup-chart-color-2": "#e268d8", + "--kup-chart-color-3": "#860bb5", + "--kup-chart-color-4": "#1a83e4", + "--kup-obj-cursor": "inherit", + "--kup-card-zindex": "900", + "--kup-drawer-zindex": "900", + "--kup-navbar-zindex": "900", + "--kup-space-00": "0px", + "--kup-space-01": "2px", + "--kup-space-02": "4px", + "--kup-space-03": "8px", + "--kup-space-04": "12px", + "--kup-space-05": "16px", + "--kup-space-06": "24px", + "--kup-space-07": "32px", + "--kup-space-08": "40px", + "--kup-space-09": "48px", + "--kup-space-10": "64px", + "--kup-space-11": "80px", + "--kup-space-12": "96px", + "--kup-space-13": "160px", + "--kup-radius-00": "0px", + "--kup-radius-01": "2px", + "--kup-radius-100": "100px" + }, + "icons": { + "--kup-ascending-icon": "arrow_drop_up", + "--kup-descending-icon": "arrow_drop_down", + "--kup-expanded-icon": "arrow_drop_down", + "--kup-collapsed-icon": "menu-right", + "--kup-dropdown-icon": "arrow_drop_down", + "--kup-clear-icon": "cancel", + "--kup-filter-remove-icon": "filter-remove", + "--kup-key-icon": "key-variant", + "--kup-search-icon": "search" + }, + "imports": [ + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')", + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')" + ], + "customStyles": {} + }, + "darkOctaneGray": { + "cssVariables": { + "--kup-primary-color": "#068a9c", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-10": "#A5E6F0", + "--kup-primary-color-20": "#83CBD8", + "--kup-primary-color-30": "#5CB0C0", + "--kup-primary-color-40": "#3E9EAF", + "--kup-primary-color-50": "#068A9C", + "--kup-primary-color-60": "#007A8B", + "--kup-primary-color-70": "#006574", + "--kup-primary-color-80": "#005160", + "--kup-primary-color-90": "#02292f", + "--kup-secondary-color": "#003C49", + "--kup-gray-color-0": "#262626", + "--kup-gray-color-10": "#393939", + "--kup-gray-color-20": "#525252", + "--kup-gray-color-30": "#6f6f6f", + "--kup-gray-color-40": "#8d8d8d", + "--kup-gray-color-50": "#A8A8A8", + "--kup-gray-color-60": "#C6C6C6", + "--kup-gray-color-70": "#E0E0E0", + "--kup-gray-color-80": "#f4f4f4", + "--kup-gray-color-90": "#ffffff", + "--kup-accent-red-color": "#da1e28", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", + "--kup-background-color": "#262626", + "--kup-navbar-background-color": "#161616", + "--kup-drawer-background-color": "#161616", + "--kup-drawer-color": "#535353", + "--kup-navbar-height": "64px", + "--kup-drawer-width": "300px", + "--kup-font-family": "IBM Plex Sans, sans-serif", + "--kup-font-family-monospace": "IBM Plex Mono, monospace", + "--kup-font-size": "14px", + "--kup-text-color": "#e8e8e8", + "--kup-text-on-primary-color": "#e8e8e8", + "--kup-text-on-secondary-color": "#312c2c", + "--kup-disabled-background-color": "#d1d1d1", + "--kup-disabled-color": "#636363", + "--kup-hover-background-color": "#e8e8e8", + "--kup-hover-color": "#303030", + "--kup-title-background-color": "#068a9c", + "--kup-title-color": "#fff", + "--kup-icon-color": "#636363", + "--kup-border-color": "#d8d8d8", + "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", + "--kup-info-color": "#2592df", + "--kup-success-color-60": "#42be65", + "--kup-success-color-40": "#198038", + "--kup-rating-color": "#ffa000", + "--kup-warning-color": "#de8906", + "--kup-danger-color-50": "#fa4d56", + "--kup-danger-color-60": "#da1e28", + "--kup-danger-color-70": "#ba1b23", + "--kup-danger-color-80": "#750e13", + "--kup-info-color-50": "#4589ff", + "--kup-info-color-70": "#0043ce", + "--kup-warning-color-40": "#f1c21b", + "--kup-spinner-color": "#fddc69", + "--kup-chart-color-1": "#60c3fc", + "--kup-chart-color-2": "#e268d8", + "--kup-chart-color-3": "#860bb5", + "--kup-chart-color-4": "#1a83e4", + "--kup-obj-cursor": "inherit", + "--kup-card-zindex": "900", + "--kup-drawer-zindex": "900", + "--kup-navbar-zindex": "900", + "--kup-space-00": "0px", + "--kup-space-01": "2px", + "--kup-space-02": "4px", + "--kup-space-03": "8px", + "--kup-space-04": "12px", + "--kup-space-05": "16px", + "--kup-space-06": "24px", + "--kup-space-07": "32px", + "--kup-space-08": "40px", + "--kup-space-09": "48px", + "--kup-space-10": "64px", + "--kup-space-11": "80px", + "--kup-space-12": "96px", + "--kup-space-13": "160px", + "--kup-radius-00": "0px", + "--kup-radius-01": "2px", + "--kup-radius-100": "100px" + }, + "icons": { + "--kup-ascending-icon": "arrow_drop_up", + "--kup-descending-icon": "arrow_drop_down", + "--kup-expanded-icon": "arrow_drop_down", + "--kup-collapsed-icon": "menu-right", + "--kup-dropdown-icon": "arrow_drop_down", + "--kup-clear-icon": "cancel", + "--kup-filter-remove-icon": "filter-remove", + "--kup-key-icon": "key-variant", + "--kup-search-icon": "search" + }, + "imports": [ + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')", + "url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700')" + ], + "customStyles": {} + }, + "bubbles": { + "cssVariables": { "--kup-primary-color": "#c18f00", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#e0c780", + "--kup-primary-color-10": "#dabc66", + "--kup-primary-color-20": "#d4b14d", + "--kup-primary-color-30": "#cda533", + "--kup-primary-color-40": "#c79a1a", + "--kup-primary-color-50": "#c18f00", + "--kup-primary-color-60": "#9a7200", + "--kup-primary-color-70": "#876400", + "--kup-primary-color-80": "#614800", + "--kup-primary-color-90": "#3a2b00", "--kup-secondary-color": "#1d1d1d", + "--kup-gray-color-0": "#ffffff", + "--kup-gray-color-10": "#F4F4F4", + "--kup-gray-color-20": "#E0E0E0", + "--kup-gray-color-30": "#C6C6C6", + "--kup-gray-color-40": "#A8A8A8", + "--kup-gray-color-50": "#8d8d8d", + "--kup-gray-color-60": "#6f6f6f", + "--kup-gray-color-70": "#525252", + "--kup-gray-color-80": "#393939", + "--kup-gray-color-90": "#262626", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#beb08d", "--kup-navbar-color": "#ffffff", @@ -146,13 +464,19 @@ "--kup-hover-color": "#545454", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#2e2e2e", - "--kup-icon-color": "#505050", + "--kup-icon-color": "#636363", "--kup-border-color": "#e0e0e0", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", "--kup-success-color": "#4d9f02", "--kup-warning-color": "#ffc107", - "--kup-danger-color": "#d91e18", + "--kup-danger-color-50": "#fa4d56", + "--kup-danger-color-60": "#da1e28", + "--kup-danger-color-70": "#ba1b23", + "--kup-danger-color-80": "#750e13", + "--kup-info-color-50": "#4589ff", + "--kup-info-color-70": "#0043ce", + "--kup-warning-color-40": "#f1c21b", "--kup-spinner-color": "#1D1D1B", "--kup-chart-color-1": "#ff5959", "--kup-chart-color-2": "#e0a0a0", @@ -177,6 +501,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -197,6 +522,19 @@ }, "cobalt": { "cssVariables": { + "--kup-primary-color": "#248aff", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#92c5ff", + "--kup-primary-color-10": "#7cb9ff", + "--kup-primary-color-20": "#66adff", + "--kup-primary-color-30": "#50a1ff", + "--kup-primary-color-40": "#3a96ff", + "--kup-primary-color-50": "#248aff", + "--kup-primary-color-60": "#1d6ecc", + "--kup-primary-color-70": "#1961b3", + "--kup-primary-color-80": "#124580", + "--kup-primary-color-90": "#0b294c", + "--kup-secondary-color": "#65cbe9", "--kup-gray-color-0": "#161616", "--kup-gray-color-10": "#262626", "--kup-gray-color-20": "#393939", @@ -207,18 +545,15 @@ "--kup-gray-color-70": "#C6C6C6", "--kup-gray-color-80": "#E0E0E0", "--kup-gray-color-90": "#f4f4f4", - "--kup-gray-color-100": "#ffffff", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", - "--kup-info-color-50": "#4589ff", - "--kup-info-color-70": "#0043ce", - "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#248aff", - "--kup-secondary-color": "#65cbe9", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#222222", "--kup-navbar-background-color": "#131313", "--kup-navbar-color": "#65cbe9", @@ -238,13 +573,16 @@ "--kup-hover-color": "#96e7ff", "--kup-title-background-color": "#2e2e2e", "--kup-title-color": "#f5f5f5", - "--kup-icon-color": "#65cbe9", + "--kup-icon-color": "#636363", "--kup-border-color": "#535353", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", "--kup-success-color": "#4d9f02", "--kup-warning-color": "#ffc107", "--kup-danger-color": "#d91e18", + "--kup-info-color-50": "#4589ff", + "--kup-info-color-70": "#0043ce", + "--kup-warning-color-40": "#f1c21b", "--kup-spinner-color": "#a4d9f7", "--kup-chart-color-1": "#308aff", "--kup-chart-color-2": "#5eb6d1", @@ -269,6 +607,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -288,6 +627,19 @@ }, "dark": { "cssVariables": { + "--kup-primary-color": "#82f0e2", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#dafbf6", + "--kup-primary-color-10": "#cdf9f3", + "--kup-primary-color-20": "#c1f8f1", + "--kup-primary-color-30": "#b4f6ee", + "--kup-primary-color-40": "#9bf3e8", + "--kup-primary-color-50": "#82f0e2", + "--kup-primary-color-60": "#68c0b5", + "--kup-primary-color-70": "#5ba89e", + "--kup-primary-color-80": "#417871", + "--kup-primary-color-90": "#274844", + "--kup-secondary-color": "#f9ff00", "--kup-gray-color-0": "#161616", "--kup-gray-color-10": "#262626", "--kup-gray-color-20": "#393939", @@ -298,18 +650,18 @@ "--kup-gray-color-70": "#C6C6C6", "--kup-gray-color-80": "#E0E0E0", "--kup-gray-color-90": "#f4f4f4", - "--kup-gray-color-100": "#ffffff", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#82f0e2", - "--kup-secondary-color": "#f9ff00", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#2d2d2d", "--kup-navbar-background-color": "#2d2d2d", "--kup-navbar-color": "#ffffff", @@ -329,7 +681,7 @@ "--kup-hover-color": "#dddddd", "--kup-title-background-color": "#111111", "--kup-title-color": "#f5f5f5", - "--kup-icon-color": "#e0e0e0", + "--kup-icon-color": "#636363", "--kup-border-color": "#535353", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -360,6 +712,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -379,6 +732,19 @@ }, "flamingo": { "cssVariables": { + "--kup-primary-color": "#e88aab", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#f8dce6", + "--kup-primary-color-10": "#f4c5d5", + "--kup-primary-color-20": "#f1b9cd", + "--kup-primary-color-30": "#efadc4", + "--kup-primary-color-40": "#eda1bc", + "--kup-primary-color-50": "#e88aab", + "--kup-primary-color-60": "#ba6e89", + "--kup-primary-color-70": "#a26178", + "--kup-primary-color-80": "#744556", + "--kup-primary-color-90": "#462933", + "--kup-secondary-color": "#7f00e7", "--kup-gray-color-0": "#161616", "--kup-gray-color-10": "#262626", "--kup-gray-color-20": "#393939", @@ -389,18 +755,18 @@ "--kup-gray-color-70": "#C6C6C6", "--kup-gray-color-80": "#E0E0E0", "--kup-gray-color-90": "#f4f4f4", - "--kup-gray-color-100": "#ffffff", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#e88aab", - "--kup-secondary-color": "#7f00e7", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#222222", "--kup-navbar-background-color": "#2d2d2d", "--kup-navbar-color": "#ffffff", @@ -420,7 +786,7 @@ "--kup-hover-color": "#dddddd", "--kup-title-background-color": "#111111", "--kup-title-color": "#f5f5f5", - "--kup-icon-color": "#e0e0e0", + "--kup-icon-color": "#636363", "--kup-border-color": "#535353", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -451,6 +817,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -470,6 +837,19 @@ }, "graphite": { "cssVariables": { + "--kup-primary-color": "#888888", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#e7e7e7", + "--kup-primary-color-10": "#cfcfcf", + "--kup-primary-color-20": "#b8b8b8", + "--kup-primary-color-30": "#a0a0a0", + "--kup-primary-color-40": "#949494", + "--kup-primary-color-50": "#888888", + "--kup-primary-color-60": "#6d6d6d", + "--kup-primary-color-70": "#5f5f5f", + "--kup-primary-color-80": "#444444", + "--kup-primary-color-90": "#292929", + "--kup-secondary-color": "#d91e18", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -480,18 +860,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#888888", - "--kup-secondary-color": "#d91e18", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#535353", "--kup-navbar-color": "#ffffff", @@ -501,7 +881,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Roboto, sans-serif", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "13px", + "--kup-font-size": "14px", "--kup-text-color": "#545454", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#ffffff", @@ -511,7 +891,7 @@ "--kup-hover-color": "#545454", "--kup-title-background-color": "#f0f0f0", "--kup-title-color": "#545454", - "--kup-icon-color": "#808080", + "--kup-icon-color": "#636363", "--kup-border-color": "#e0e0e0", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -548,6 +928,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "customStyles": { @@ -567,6 +948,19 @@ }, "ketchup": { "cssVariables": { + "--kup-primary-color": "#d64325", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#e68e7c", + "--kup-primary-color-10": "#e68e7c", + "--kup-primary-color-20": "#e27b66", + "--kup-primary-color-30": "#de6951", + "--kup-primary-color-40": "#da563b", + "--kup-primary-color-50": "#d64325", + "--kup-primary-color-60": "#ab361e", + "--kup-primary-color-70": "#962f1a", + "--kup-primary-color-80": "#6b2213", + "--kup-primary-color-90": "#40140b", + "--kup-secondary-color": "#a6192e", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -577,18 +971,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#d64325", - "--kup-secondary-color": "#a6192e", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#2e2e2e", "--kup-navbar-color": "#ffffff", @@ -608,7 +1002,7 @@ "--kup-hover-color": "#545454", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#2e2e2e", - "--kup-icon-color": "#505050", + "--kup-icon-color": "#636363", "--kup-border-color": "#e0e0e0", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -639,6 +1033,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -658,6 +1053,19 @@ }, "obsidian": { "cssVariables": { + "--kup-primary-color": "#a6192e", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#dba3ab", + "--kup-primary-color-10": "#ca7582", + "--kup-primary-color-20": "#c15e6d", + "--kup-primary-color-30": "#b84758", + "--kup-primary-color-40": "#af3043", + "--kup-primary-color-50": "#a6192e", + "--kup-primary-color-60": "#851425", + "--kup-primary-color-70": "#741220", + "--kup-primary-color-80": "#530d17", + "--kup-primary-color-90": "#32070e", + "--kup-secondary-color": "#f5f4f4", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -668,18 +1076,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#a6192e", - "--kup-secondary-color": "#f5f4f4", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#000000", "--kup-navbar-color": "#ffffff", @@ -689,7 +1097,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Open Sans, arial, helvatica", "--kup-font-family-monospace": "Courier New, Courier, monospace", - "--kup-font-size": "13px", + "--kup-font-size": "14px", "--kup-text-color": "#4c4c4d", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#a6192e", @@ -699,7 +1107,7 @@ "--kup-hover-color": "#000000", "--kup-title-background-color": "#068a9c", "--kup-title-color": "#ffffff", - "--kup-icon-color": "#9d9d9d", + "--kup-icon-color": "#636363", "--kup-border-color": "#ededed", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -736,6 +1144,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -755,6 +1164,19 @@ }, "ocean": { "cssVariables": { + "--kup-primary-color": "#0081c5", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#99cde8", + "--kup-primary-color-10": "#66b3dc", + "--kup-primary-color-20": "#4da7d6", + "--kup-primary-color-30": "#339ad1", + "--kup-primary-color-40": "#1a8ecb", + "--kup-primary-color-50": "#0081c5", + "--kup-primary-color-60": "#00679e", + "--kup-primary-color-70": "#005a8a", + "--kup-primary-color-80": "#004163", + "--kup-primary-color-90": "#00273b", + "--kup-secondary-color": "#3a8ede", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -765,18 +1187,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#0081c5", - "--kup-secondary-color": "#3a8ede", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#001d3e", "--kup-navbar-color": "#ffffff", @@ -786,7 +1208,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Open Sans Condensed, sans-serif", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "16px", + "--kup-font-size": "14px", "--kup-text-color": "#1b1b1b", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#ffffff", @@ -796,7 +1218,7 @@ "--kup-hover-color": "#545454", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#1b1b1b", - "--kup-icon-color": "#505050", + "--kup-icon-color": "#636363", "--kup-border-color": "#e0e0e0", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -827,6 +1249,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -846,6 +1269,19 @@ }, "print": { "cssVariables": { + "--kup-primary-color": "#000000", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#000000", + "--kup-primary-color-10": "#000000", + "--kup-primary-color-20": "#000000", + "--kup-primary-color-30": "#000000", + "--kup-primary-color-40": "#000000", + "--kup-primary-color-50": "#000000", + "--kup-primary-color-60": "#000000", + "--kup-primary-color-70": "#000000", + "--kup-primary-color-80": "#000000", + "--kup-primary-color-90": "#000000", + "--kup-secondary-color": "#cccccc", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -856,18 +1292,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#000000", - "--kup-secondary-color": "#cccccc", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#000000", "--kup-navbar-color": "#ffffff", @@ -877,7 +1313,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Arial, Helvetica, sans-serif", "--kup-font-family-monospace": "Courier New, Courier, monospace", - "--kup-font-size": "13px", + "--kup-font-size": "14px", "--kup-text-color": "#000000", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#000000", @@ -887,7 +1323,7 @@ "--kup-hover-color": "#000000", "--kup-title-background-color": "#f1f1f1", "--kup-title-color": "#000000", - "--kup-icon-color": "#9d9d9d", + "--kup-icon-color": "#636363", "--kup-border-color": "#ededed", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -924,6 +1360,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "customStyles": { @@ -950,6 +1387,19 @@ }, "raj": { "cssVariables": { + "--kup-primary-color": "rgb(187, 198, 5)", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#ebeeb4", + "--kup-primary-color-10": "#e4e89b", + "--kup-primary-color-20": "#dde382", + "--kup-primary-color-30": "#d6dd69", + "--kup-primary-color-40": "#c9d137", + "--kup-primary-color-50": "#bbc605", + "--kup-primary-color-60": "#969e04", + "--kup-primary-color-70": "#707703", + "--kup-primary-color-80": "#4b4f02", + "--kup-primary-color-90": "#252801", + "--kup-secondary-color": "#ffe600", "--kup-gray-color-0": "#161616", "--kup-gray-color-10": "#262626", "--kup-gray-color-20": "#393939", @@ -960,18 +1410,18 @@ "--kup-gray-color-70": "#C6C6C6", "--kup-gray-color-80": "#E0E0E0", "--kup-gray-color-90": "#f4f4f4", - "--kup-gray-color-100": "#ffffff", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "rgb(187, 198, 5)", - "--kup-secondary-color": "#ffe600", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#000000", "--kup-navbar-background-color": "#000000", "--kup-navbar-color": "#ffffff", @@ -981,7 +1431,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "'Rajdhani', sans-serif", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "15px", + "--kup-font-size": "14px", "--kup-text-color": "#ffffff", "--kup-text-on-primary-color": "#000000", "--kup-text-on-secondary-color": "#000000", @@ -991,7 +1441,7 @@ "--kup-hover-color": "#ffffff", "--kup-title-background-color": "#ffe600", "--kup-title-color": "#000000", - "--kup-icon-color": "#9d9d9d", + "--kup-icon-color": "#636363", "--kup-border-color": "#9d9d9d", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -1022,6 +1472,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -1041,6 +1492,19 @@ }, "red": { "cssVariables": { + "--kup-primary-color": "#a6192e", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#e4bac0", + "--kup-primary-color-10": "#dba3ab", + "--kup-primary-color-20": "#d38c97", + "--kup-primary-color-30": "#c15e6d", + "--kup-primary-color-40": "#b84758", + "--kup-primary-color-50": "#a6192e", + "--kup-primary-color-60": "#851425", + "--kup-primary-color-70": "#640f1c", + "--kup-primary-color-80": "#420a12", + "--kup-primary-color-90": "#32070e", + "--kup-secondary-color": "#ffc107", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -1051,18 +1515,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#a6192e", - "--kup-secondary-color": "#ffc107", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#a6192e", "--kup-navbar-color": "#ffffff", @@ -1072,7 +1536,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Open Sans, arial, helvatica", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "13px", + "--kup-font-size": "14px", "--kup-text-color": "#000000", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#ffffff", @@ -1082,7 +1546,7 @@ "--kup-hover-color": "#000000", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#2e2e2e", - "--kup-icon-color": "#808080", + "--kup-icon-color": "#636363", "--kup-border-color": "#ededed", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -1119,6 +1583,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -1139,6 +1604,19 @@ }, "sapphire": { "cssVariables": { + "--kup-primary-color": "#003b77", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#b3c4d6", + "--kup-primary-color-10": "#809dbb", + "--kup-primary-color-20": "#6689ad", + "--kup-primary-color-30": "#336292", + "--kup-primary-color-40": "#1a4f85", + "--kup-primary-color-50": "#003b77", + "--kup-primary-color-60": "#002f5f", + "--kup-primary-color-70": "#002347", + "--kup-primary-color-80": "#001830", + "--kup-primary-color-90": "#001224", + "--kup-secondary-color": "#ff1414", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -1149,18 +1627,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#003b77", - "--kup-secondary-color": "#ff1414", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#003b77", "--kup-navbar-color": "#ffffff", @@ -1168,9 +1646,9 @@ "--kup-drawer-color": "#ffffff", "--kup-navbar-height": "64px", "--kup-drawer-width": "20em", - "--kup-font-family": "Arial", - "--kup-font-family-monospace": "Arial", - "--kup-font-size": "13px", + "--kup-font-family": "IBM Plex Sans, sans-serif", + "--kup-font-family-monospace": "IBM Plex Mono, monospace", + "--kup-font-size": "14px", "--kup-text-color": "#333333", "--kup-text-on-primary-color": "#fafafa", "--kup-text-on-secondary-color": "#ffffff", @@ -1180,7 +1658,7 @@ "--kup-hover-color": "#333333", "--kup-title-background-color": "#003b77", "--kup-title-color": "#ffffff", - "--kup-icon-color": "#808080", + "--kup-icon-color": "#636363", "--kup-border-color": "#93c4ec", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -1217,6 +1695,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -1236,6 +1715,19 @@ }, "silver": { "cssVariables": { + "--kup-primary-color": "#c0c0c0", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#f2f2f2", + "--kup-primary-color-10": "#ececec", + "--kup-primary-color-20": "#e6e6e6", + "--kup-primary-color-30": "#d9d9d9", + "--kup-primary-color-40": "#cdcdcd", + "--kup-primary-color-50": "#c0c0c0", + "--kup-primary-color-60": "#9a9a9a", + "--kup-primary-color-70": "#737373", + "--kup-primary-color-80": "#4d4d4d", + "--kup-primary-color-90": "#262626", + "--kup-secondary-color": "#c0c0c0", "--kup-gray-color-0": "#161616", "--kup-gray-color-10": "#262626", "--kup-gray-color-20": "#393939", @@ -1246,18 +1738,18 @@ "--kup-gray-color-70": "#C6C6C6", "--kup-gray-color-80": "#E0E0E0", "--kup-gray-color-90": "#f4f4f4", - "--kup-gray-color-100": "#ffffff", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#c0c0c0", - "--kup-secondary-color": "#c0c0c0", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#000000", "--kup-navbar-background-color": "#ffffff", "--kup-navbar-color": "#000000", @@ -1267,7 +1759,7 @@ "--kup-drawer-width": "320px", "--kup-font-family": "Oswald, sans-serif", "--kup-font-family-monospace": "Xanh Mono, monospace", - "--kup-font-size": "16px", + "--kup-font-size": "14px", "--kup-text-color": "#fefefe", "--kup-text-on-primary-color": "#4a4a4a", "--kup-text-on-secondary-color": "#4a4a4a", @@ -1277,7 +1769,7 @@ "--kup-hover-color": "#dddddd", "--kup-title-background-color": "#151515", "--kup-title-color": "#d9d9d9", - "--kup-icon-color": "#c0c0c0", + "--kup-icon-color": "#636363", "--kup-border-color": "#c0c0c0", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -1311,6 +1803,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -1331,6 +1824,19 @@ }, "teal": { "cssVariables": { + "--kup-primary-color": "#068A9C", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#cde8eb", + "--kup-primary-color-10": "#b4dce1", + "--kup-primary-color-20": "#9bd0d7", + "--kup-primary-color-30": "#6ab9c4", + "--kup-primary-color-40": "#38a1b0", + "--kup-primary-color-50": "#068A9C", + "--kup-primary-color-60": "#056e7d", + "--kup-primary-color-70": "#04535e", + "--kup-primary-color-80": "#02373e", + "--kup-primary-color-90": "#011c1f", + "--kup-secondary-color": "#ffc107", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -1341,18 +1847,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#068A9C", - "--kup-secondary-color": "#ffc107", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#068A9C", "--kup-navbar-color": "#ffffff", @@ -1362,7 +1868,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Roboto, sans-serif", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "13px", + "--kup-font-size": "14px", "--kup-text-color": "#000000", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#ffffff", @@ -1372,7 +1878,7 @@ "--kup-hover-color": "#000000", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#2e2e2e", - "--kup-icon-color": "#808080", + "--kup-icon-color": "#636363", "--kup-border-color": "#ededed", "--kup-box-shadow": "rgba(0, 0, 0, 0.2) 0px 5px 5px -3px, rgba(0, 0, 0, 0.14) 0px 8px 10px 1px, rgba(0, 0, 0, 0.12) 0px 3px 14px 2px", "--kup-info-color": "#2592df", @@ -1409,6 +1915,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { @@ -1425,6 +1932,19 @@ }, "wildlife": { "cssVariables": { + "--kup-primary-color": "#0fa918", + "--kup-primary-color-0": "#ffffff", + "--kup-primary-color-5": "#cfeed1", + "--kup-primary-color-10": "#b7e5ba", + "--kup-primary-color-20": "#9fdda3", + "--kup-primary-color-30": "#6fcb74", + "--kup-primary-color-40": "#3fba46", + "--kup-primary-color-50": "#0fa918", + "--kup-primary-color-60": "#0c8713", + "--kup-primary-color-70": "#09650e", + "--kup-primary-color-80": "#06440a", + "--kup-primary-color-90": "#032205", + "--kup-secondary-color": "#739f5a", "--kup-gray-color-0": "#ffffff", "--kup-gray-color-10": "#F4F4F4", "--kup-gray-color-20": "#E0E0E0", @@ -1435,18 +1955,18 @@ "--kup-gray-color-70": "#525252", "--kup-gray-color-80": "#393939", "--kup-gray-color-90": "#262626", - "--kup-gray-color-100": "#161616", "--kup-danger-color-50": "#fa4d56", "--kup-danger-color-60": "#da1e28", "--kup-danger-color-70": "#ba1b23", "--kup-danger-color-80": "#750e13", - "--kup-success-color-40": "#42be65", - "--kup-success-color-60": "#198038", "--kup-info-color-50": "#4589ff", "--kup-info-color-70": "#0043ce", "--kup-warning-color-40": "#f1c21b", - "--kup-primary-color": "#0fa918", - "--kup-secondary-color": "#739f5a", + "--kup-accent-red-color": "#A6192E", + "--kup-accent-orange-color": "#DE8906", + "--kup-accent-yellow-color": "#FDDC69", + "--kup-accent-green-color": "#A4BA4C", + "--kup-accent-white-color": "#FFFFFF", "--kup-background-color": "#ffffff", "--kup-navbar-background-color": "#095a1f", "--kup-navbar-color": "#ffffff", @@ -1456,7 +1976,7 @@ "--kup-drawer-width": "300px", "--kup-font-family": "Abel, sans-serif", "--kup-font-family-monospace": "Roboto Mono, consolas, monospace", - "--kup-font-size": "16px", + "--kup-font-size": "14px", "--kup-text-color": "#000000", "--kup-text-on-primary-color": "#ffffff", "--kup-text-on-secondary-color": "#ffffff", @@ -1466,7 +1986,7 @@ "--kup-hover-color": "#ffffff", "--kup-title-background-color": "#f1f3f4", "--kup-title-color": "#000000", - "--kup-icon-color": "#333333", + "--kup-icon-color": "#636363", "--kup-border-color": "#e0e0e0", "--kup-box-shadow": "0px 0px 7.5px 0px rgba(128, 128, 128, 0.5)", "--kup-info-color": "#2592df", @@ -1497,6 +2017,7 @@ "--kup-space-12": "96px", "--kup-space-13": "160px", "--kup-radius-00": "0px", + "--kup-radius-01": "2px", "--kup-radius-100": "100px" }, "icons": { diff --git a/yarn.lock b/yarn.lock index 1bb64b47a0..97dcf19929 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2998,7 +2998,7 @@ __metadata: version: 0.0.0-use.local resolution: "@sme.up/ketchup-react@workspace:packages/ketchup-react" dependencies: - "@sme.up/ketchup": ^9.6.4 + "@sme.up/ketchup": ^9.6.5 "@types/geojson": ^7946.0.10 "@types/node": ^20.2.5 "@types/react": ^18.2.7 @@ -3032,7 +3032,7 @@ __metadata: resolution: "@sme.up/ketchup-showcase@workspace:packages/ketchup-showcase" dependencies: "@babel/plugin-transform-private-methods": ^7.24.1 - "@sme.up/ketchup": ^9.6.4 + "@sme.up/ketchup": ^9.6.5 "@typescript-eslint/eslint-plugin": ^5.59.8 "@typescript-eslint/parser": ^5.59.8 "@vue/cli-plugin-babel": ~5.0.8 @@ -3056,7 +3056,7 @@ __metadata: languageName: unknown linkType: soft -"@sme.up/ketchup@^9.6.4, @sme.up/ketchup@workspace:packages/ketchup": +"@sme.up/ketchup@^9.6.5, @sme.up/ketchup@workspace:packages/ketchup": version: 0.0.0-use.local resolution: "@sme.up/ketchup@workspace:packages/ketchup" dependencies: