From 80744018ec5043fc088c587006b17c1f49cf40b4 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 31 Oct 2022 14:50:19 -0400 Subject: [PATCH 01/22] added carbon react package w/ burnettk --- spiffworkflow-frontend/package-lock.json | 577 +++++++++++++++++- spiffworkflow-frontend/package.json | 5 + spiffworkflow-frontend/src/index.scss | 2 + spiffworkflow-frontend/src/index.tsx | 1 + .../src/routes/HomePage.tsx | 3 +- 5 files changed, 581 insertions(+), 7 deletions(-) create mode 100644 spiffworkflow-frontend/src/index.scss diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index 738cea50..7eb07fb0 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -12,6 +12,7 @@ "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/preset-react": "^7.18.6", "@bpmn-io/properties-panel": "^0.19.0", + "@carbon/react": "^1.16.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", "@rjsf/core": "^4.2.0", @@ -2094,6 +2095,138 @@ "resolved": "https://registry.npmjs.org/@camunda/zeebe-element-templates-json-schema/-/zeebe-element-templates-json-schema-0.5.0.tgz", "integrity": "sha512-BVHVl4cuK9LxL1eDSdWs8AzuZd981/+CPkw7xlwcB1Xkn6Di8E2iRbDUCBhOIqkahjJYq957nVtbM6jlqXX5qw==" }, + "node_modules/@carbon/colors": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/colors/-/colors-11.7.0.tgz", + "integrity": "sha512-2B57vtirYTpxGg7p9yIO+s4cwL5QB8ogGQB5Pz+zdaHoVxrLsGlxAg28CQgk7yxw7doqST79bRVYS6FaJq+qJw==" + }, + "node_modules/@carbon/feature-flags": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@carbon/feature-flags/-/feature-flags-0.9.0.tgz", + "integrity": "sha512-uNCRkxsNwLdJVNwQ5S5vrLAm4yawWzhFBwyP9EgXVmRzJH85Aim+miC+QNjRXntJDYhZYDuLABTeb3VD692ypA==" + }, + "node_modules/@carbon/grid": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/grid/-/grid-11.7.0.tgz", + "integrity": "sha512-OCDXQNSPVOoBQN08Qn5wo2WpKRGRm/kEBo6ZTl2NoDCl21mcYJZ0IDbKPTukixJB1sUNDUlnrpwMoaznPj48dw==", + "dependencies": { + "@carbon/layout": "^11.7.0" + } + }, + "node_modules/@carbon/icon-helpers": { + "version": "10.34.0", + "resolved": "https://registry.npmjs.org/@carbon/icon-helpers/-/icon-helpers-10.34.0.tgz", + "integrity": "sha512-Ov9EBc1tR/DDrMI0pN1drj2jb27ISmYFBLdDji+aivVJkLPy8R/jikJOsOBgIq2kUjQJYNN199k2acHKjZdYIg==" + }, + "node_modules/@carbon/icons-react": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/@carbon/icons-react/-/icons-react-11.10.0.tgz", + "integrity": "sha512-807RWTfbvVzmsDg2DJ4FjwYNbJSgkrEd1Ui8I07YheJVb3sbYGGZMG7aCS0qXVlrQOhB2hggtxSW1w9NksUXNA==", + "hasInstallScript": true, + "dependencies": { + "@carbon/icon-helpers": "^10.34.0", + "@carbon/telemetry": "0.1.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/@carbon/layout": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/layout/-/layout-11.7.0.tgz", + "integrity": "sha512-p4YQvW8U5Go0Tz1PZZgllGSPmoq8xBB5PHByuHiAjzwGclxPsBmY6Ea7tftINFW8VlcjDcampyT8VfZXhP2lFg==" + }, + "node_modules/@carbon/motion": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/@carbon/motion/-/motion-11.5.0.tgz", + "integrity": "sha512-5QEALh+xZzICdgVLanSpiDfBTErzVgEze/xUKs7ZdSbd6p1FaDKDGvCmj9RCsaz/CMVHIWo65MshIglSWX5Xvw==" + }, + "node_modules/@carbon/react": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@carbon/react/-/react-1.16.0.tgz", + "integrity": "sha512-kVeL/iyVqN2tfcoE1xliIm4w2ex9L4m/b8KuGo7ZuqBmRzANQdfSYGfj11KU0TXT1CbOVFrqsT/aBxApsP5IDg==", + "hasInstallScript": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@carbon/feature-flags": "^0.9.0", + "@carbon/icons-react": "^11.10.0", + "@carbon/layout": "^11.7.0", + "@carbon/styles": "^1.16.0", + "@carbon/telemetry": "0.1.0", + "classnames": "2.3.2", + "copy-to-clipboard": "^3.3.1", + "downshift": "5.2.1", + "flatpickr": "4.6.9", + "invariant": "^2.2.3", + "lodash.debounce": "^4.0.8", + "lodash.findlast": "^4.5.0", + "lodash.isequal": "^4.5.0", + "lodash.omit": "^4.5.0", + "lodash.throttle": "^4.1.1", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "use-resize-observer": "^6.0.0", + "wicg-inert": "^3.1.1", + "window-or-global": "^1.0.1" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.1", + "react-dom": "^16.8.6 || ^17.0.1", + "sass": "^1.33.0" + } + }, + "node_modules/@carbon/react/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/@carbon/styles": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@carbon/styles/-/styles-1.16.0.tgz", + "integrity": "sha512-LSjRw2Ws8rWI1a96KYUuX10jG+rpSn68dHlZhhDq+RJWsMGpjFhKUxPoTiJli2hHXyxey6rXV0hfr7oBJ0ud7w==", + "dependencies": { + "@carbon/colors": "^11.7.0", + "@carbon/feature-flags": "^0.9.0", + "@carbon/grid": "^11.7.0", + "@carbon/layout": "^11.7.0", + "@carbon/motion": "^11.5.0", + "@carbon/themes": "^11.11.0", + "@carbon/type": "^11.11.0", + "@ibm/plex": "6.0.0-next.6" + }, + "peerDependencies": { + "sass": "^1.33.0" + } + }, + "node_modules/@carbon/telemetry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@carbon/telemetry/-/telemetry-0.1.0.tgz", + "integrity": "sha512-kNWt0bkgPwGW0i5h7HFuljbKRXPvIhsKbB+1tEURAYLXoJg9iJLF1eGvWN5iVoFCS2zje4GR3OGOsvvKVe7Hlg==", + "bin": { + "carbon-telemetry": "bin/carbon-telemetry.js" + } + }, + "node_modules/@carbon/themes": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@carbon/themes/-/themes-11.11.0.tgz", + "integrity": "sha512-EhLizr2oMqJXNubI2zWw09qcSPLZdWoBOQ6uNcjHzpXgoGNMwbVJE/qGMy/ivr+EOs6Fe0z5T0u97v+ZhSmRhg==", + "dependencies": { + "@carbon/colors": "^11.7.0", + "@carbon/layout": "^11.7.0", + "@carbon/type": "^11.11.0", + "color": "^4.0.0" + } + }, + "node_modules/@carbon/type": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@carbon/type/-/type-11.11.0.tgz", + "integrity": "sha512-eX6z8BibP1En1xBm2wUd01Nzk0Tm1jftR2QSD4JBn4xhnkGR824gpcbLTAIMGx9/Mr3R65Enbam3uFO0OOaH8g==", + "dependencies": { + "@carbon/grid": "^11.7.0", + "@carbon/layout": "^11.7.0" + } + }, "node_modules/@codemirror/autocomplete": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz", @@ -2847,6 +2980,14 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "node_modules/@ibm/plex": { + "version": "6.0.0-next.6", + "resolved": "https://registry.npmjs.org/@ibm/plex/-/plex-6.0.0-next.6.tgz", + "integrity": "sha512-B3uGruTn2rS5gweynLmfSe7yCawSRsJguJJQHVQiqf4rh2RNgJFu8YLE2Zd/JHV0ZXoVMOslcXP2k3hMkxKEyA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -7939,9 +8080,9 @@ } }, "node_modules/classnames": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/clean-css": { "version": "5.3.1", @@ -8137,6 +8278,18 @@ "node": ">=0.10.0" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -8150,6 +8303,31 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -8414,6 +8592,14 @@ "node": ">=0.10.0" } }, + "node_modules/copy-to-clipboard": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz", + "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core_d": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz", @@ -9800,6 +9986,25 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, + "node_modules/downshift": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-5.2.1.tgz", + "integrity": "sha512-uHX2OLbWthLR8QbR8NCI8OmjvvJxq8+PrA95KblFd9JyB1zVZh1HnszzsWMMCnMuH6IvsUtVfF5HY7XfijJ2dw==", + "dependencies": { + "@babel/runtime": "^7.9.1", + "compute-scroll-into-view": "^1.0.13", + "prop-types": "^15.7.2", + "react-is": "^16.13.1" + }, + "peerDependencies": { + "react": ">=0.14.9" + } + }, + "node_modules/downshift/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -11524,6 +11729,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flatpickr": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz", + "integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==" + }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -12722,6 +12932,12 @@ "url": "https://opencollective.com/immer" } }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "peer": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -18165,6 +18381,16 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.findlast": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.findlast/-/lodash.findlast-4.6.0.tgz", + "integrity": "sha512-+OGwb1FVKjhc2aIEQ9vKqNDW1a0/HaCLr0iCIK10jfVif3dBE0nhQD0jOZNZLh7zOlmFUTrk+vt85eXoH4vKuA==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -18175,6 +18401,11 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -18186,6 +18417,11 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -23844,6 +24080,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -24172,6 +24413,23 @@ "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, + "node_modules/sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "peer": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -24642,6 +24900,19 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -26126,6 +26397,11 @@ "ret": "~0.1.10" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -27671,6 +27947,18 @@ "react": "^16.8.0 || ^17.0.0" } }, + "node_modules/use-resize-observer": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-6.1.0.tgz", + "integrity": "sha512-SiPcWHiIQ1CnHmb6PxbYtygqiZXR0U9dNkkbpX9VYnlstUwF8+QqpUTrzh13pjPwcjMVGR+QIC+nvF5ujfFNng==", + "dependencies": { + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -28791,6 +29079,11 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "node_modules/wicg-inert": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz", + "integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang==" + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -28846,6 +29139,11 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/window-or-global": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz", + "integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w==" + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -30704,6 +31002,124 @@ "resolved": "https://registry.npmjs.org/@camunda/zeebe-element-templates-json-schema/-/zeebe-element-templates-json-schema-0.5.0.tgz", "integrity": "sha512-BVHVl4cuK9LxL1eDSdWs8AzuZd981/+CPkw7xlwcB1Xkn6Di8E2iRbDUCBhOIqkahjJYq957nVtbM6jlqXX5qw==" }, + "@carbon/colors": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/colors/-/colors-11.7.0.tgz", + "integrity": "sha512-2B57vtirYTpxGg7p9yIO+s4cwL5QB8ogGQB5Pz+zdaHoVxrLsGlxAg28CQgk7yxw7doqST79bRVYS6FaJq+qJw==" + }, + "@carbon/feature-flags": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@carbon/feature-flags/-/feature-flags-0.9.0.tgz", + "integrity": "sha512-uNCRkxsNwLdJVNwQ5S5vrLAm4yawWzhFBwyP9EgXVmRzJH85Aim+miC+QNjRXntJDYhZYDuLABTeb3VD692ypA==" + }, + "@carbon/grid": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/grid/-/grid-11.7.0.tgz", + "integrity": "sha512-OCDXQNSPVOoBQN08Qn5wo2WpKRGRm/kEBo6ZTl2NoDCl21mcYJZ0IDbKPTukixJB1sUNDUlnrpwMoaznPj48dw==", + "requires": { + "@carbon/layout": "^11.7.0" + } + }, + "@carbon/icon-helpers": { + "version": "10.34.0", + "resolved": "https://registry.npmjs.org/@carbon/icon-helpers/-/icon-helpers-10.34.0.tgz", + "integrity": "sha512-Ov9EBc1tR/DDrMI0pN1drj2jb27ISmYFBLdDji+aivVJkLPy8R/jikJOsOBgIq2kUjQJYNN199k2acHKjZdYIg==" + }, + "@carbon/icons-react": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/@carbon/icons-react/-/icons-react-11.10.0.tgz", + "integrity": "sha512-807RWTfbvVzmsDg2DJ4FjwYNbJSgkrEd1Ui8I07YheJVb3sbYGGZMG7aCS0qXVlrQOhB2hggtxSW1w9NksUXNA==", + "requires": { + "@carbon/icon-helpers": "^10.34.0", + "@carbon/telemetry": "0.1.0", + "prop-types": "^15.7.2" + } + }, + "@carbon/layout": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@carbon/layout/-/layout-11.7.0.tgz", + "integrity": "sha512-p4YQvW8U5Go0Tz1PZZgllGSPmoq8xBB5PHByuHiAjzwGclxPsBmY6Ea7tftINFW8VlcjDcampyT8VfZXhP2lFg==" + }, + "@carbon/motion": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/@carbon/motion/-/motion-11.5.0.tgz", + "integrity": "sha512-5QEALh+xZzICdgVLanSpiDfBTErzVgEze/xUKs7ZdSbd6p1FaDKDGvCmj9RCsaz/CMVHIWo65MshIglSWX5Xvw==" + }, + "@carbon/react": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@carbon/react/-/react-1.16.0.tgz", + "integrity": "sha512-kVeL/iyVqN2tfcoE1xliIm4w2ex9L4m/b8KuGo7ZuqBmRzANQdfSYGfj11KU0TXT1CbOVFrqsT/aBxApsP5IDg==", + "requires": { + "@babel/runtime": "^7.18.3", + "@carbon/feature-flags": "^0.9.0", + "@carbon/icons-react": "^11.10.0", + "@carbon/layout": "^11.7.0", + "@carbon/styles": "^1.16.0", + "@carbon/telemetry": "0.1.0", + "classnames": "2.3.2", + "copy-to-clipboard": "^3.3.1", + "downshift": "5.2.1", + "flatpickr": "4.6.9", + "invariant": "^2.2.3", + "lodash.debounce": "^4.0.8", + "lodash.findlast": "^4.5.0", + "lodash.isequal": "^4.5.0", + "lodash.omit": "^4.5.0", + "lodash.throttle": "^4.1.1", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "use-resize-observer": "^6.0.0", + "wicg-inert": "^3.1.1", + "window-or-global": "^1.0.1" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } + }, + "@carbon/styles": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@carbon/styles/-/styles-1.16.0.tgz", + "integrity": "sha512-LSjRw2Ws8rWI1a96KYUuX10jG+rpSn68dHlZhhDq+RJWsMGpjFhKUxPoTiJli2hHXyxey6rXV0hfr7oBJ0ud7w==", + "requires": { + "@carbon/colors": "^11.7.0", + "@carbon/feature-flags": "^0.9.0", + "@carbon/grid": "^11.7.0", + "@carbon/layout": "^11.7.0", + "@carbon/motion": "^11.5.0", + "@carbon/themes": "^11.11.0", + "@carbon/type": "^11.11.0", + "@ibm/plex": "6.0.0-next.6" + } + }, + "@carbon/telemetry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@carbon/telemetry/-/telemetry-0.1.0.tgz", + "integrity": "sha512-kNWt0bkgPwGW0i5h7HFuljbKRXPvIhsKbB+1tEURAYLXoJg9iJLF1eGvWN5iVoFCS2zje4GR3OGOsvvKVe7Hlg==" + }, + "@carbon/themes": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@carbon/themes/-/themes-11.11.0.tgz", + "integrity": "sha512-EhLizr2oMqJXNubI2zWw09qcSPLZdWoBOQ6uNcjHzpXgoGNMwbVJE/qGMy/ivr+EOs6Fe0z5T0u97v+ZhSmRhg==", + "requires": { + "@carbon/colors": "^11.7.0", + "@carbon/layout": "^11.7.0", + "@carbon/type": "^11.11.0", + "color": "^4.0.0" + } + }, + "@carbon/type": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@carbon/type/-/type-11.11.0.tgz", + "integrity": "sha512-eX6z8BibP1En1xBm2wUd01Nzk0Tm1jftR2QSD4JBn4xhnkGR824gpcbLTAIMGx9/Mr3R65Enbam3uFO0OOaH8g==", + "requires": { + "@carbon/grid": "^11.7.0", + "@carbon/layout": "^11.7.0" + } + }, "@codemirror/autocomplete": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz", @@ -31226,6 +31642,11 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "@ibm/plex": { + "version": "6.0.0-next.6", + "resolved": "https://registry.npmjs.org/@ibm/plex/-/plex-6.0.0-next.6.tgz", + "integrity": "sha512-B3uGruTn2rS5gweynLmfSe7yCawSRsJguJJQHVQiqf4rh2RNgJFu8YLE2Zd/JHV0ZXoVMOslcXP2k3hMkxKEyA==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -35077,9 +35498,9 @@ } }, "classnames": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "clean-css": { "version": "5.3.1", @@ -35217,6 +35638,30 @@ "object-visit": "^1.0.0" } }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -35230,6 +35675,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -35455,6 +35909,14 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" }, + "copy-to-clipboard": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz", + "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "core_d": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz", @@ -36554,6 +37016,24 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, + "downshift": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-5.2.1.tgz", + "integrity": "sha512-uHX2OLbWthLR8QbR8NCI8OmjvvJxq8+PrA95KblFd9JyB1zVZh1HnszzsWMMCnMuH6IvsUtVfF5HY7XfijJ2dw==", + "requires": { + "@babel/runtime": "^7.9.1", + "compute-scroll-into-view": "^1.0.13", + "prop-types": "^15.7.2", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -37859,6 +38339,11 @@ "rimraf": "^3.0.2" } }, + "flatpickr": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz", + "integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==" + }, "flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -38715,6 +39200,12 @@ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" }, + "immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "peer": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -42838,6 +43329,16 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "lodash.findlast": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.findlast/-/lodash.findlast-4.6.0.tgz", + "integrity": "sha512-+OGwb1FVKjhc2aIEQ9vKqNDW1a0/HaCLr0iCIK10jfVif3dBE0nhQD0jOZNZLh7zOlmFUTrk+vt85eXoH4vKuA==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -42848,6 +43349,11 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -42859,6 +43365,11 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -46772,6 +47283,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -47005,6 +47521,17 @@ "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, + "sass": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", + "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "peer": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -47403,6 +47930,21 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -48573,6 +49115,11 @@ "is-number": "^7.0.0" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -49742,6 +50289,14 @@ "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", "requires": {} }, + "use-resize-observer": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-6.1.0.tgz", + "integrity": "sha512-SiPcWHiIQ1CnHmb6PxbYtygqiZXR0U9dNkkbpX9VYnlstUwF8+QqpUTrzh13pjPwcjMVGR+QIC+nvF5ujfFNng==", + "requires": { + "resize-observer-polyfill": "^1.5.1" + } + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -50618,6 +51173,11 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "wicg-inert": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz", + "integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang==" + }, "widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -50651,6 +51211,11 @@ } } }, + "window-or-global": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz", + "integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w==" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index 2ce2d7a1..c48ffca0 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -7,6 +7,7 @@ "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/preset-react": "^7.18.6", "@bpmn-io/properties-panel": "^0.19.0", + "@carbon/react": "^1.16.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", "@rjsf/core": "^4.2.0", @@ -57,6 +58,10 @@ "react": "^18.2.0", "bootstrap": "^5.2.0-beta1" }, + "@carbon/react": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, "dmn-js-properties-panel": { "@bpmn-io/properties-panel": "^0.19.0" } diff --git a/spiffworkflow-frontend/src/index.scss b/spiffworkflow-frontend/src/index.scss new file mode 100644 index 00000000..61228e3b --- /dev/null +++ b/spiffworkflow-frontend/src/index.scss @@ -0,0 +1,2 @@ +@use '@carbon/react'; + diff --git a/spiffworkflow-frontend/src/index.tsx b/spiffworkflow-frontend/src/index.tsx index ebd40415..a2fab5c0 100644 --- a/spiffworkflow-frontend/src/index.tsx +++ b/spiffworkflow-frontend/src/index.tsx @@ -4,6 +4,7 @@ import App from './App'; import 'bootstrap/dist/css/bootstrap.css'; import './index.css'; +import './index.scss'; import reportWebVitals from './reportWebVitals'; import UserService from './services/UserService'; diff --git a/spiffworkflow-frontend/src/routes/HomePage.tsx b/spiffworkflow-frontend/src/routes/HomePage.tsx index 4d348ed2..da39e205 100644 --- a/spiffworkflow-frontend/src/routes/HomePage.tsx +++ b/spiffworkflow-frontend/src/routes/HomePage.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; -import { Button, Table } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; import { Link, useSearchParams } from 'react-router-dom'; import PaginationForTable from '../components/PaginationForTable'; import { getPageInfoFromSearchParams } from '../helpers'; From c90992b03c089b0113ebe20f9624a5cc1be4358a Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 31 Oct 2022 15:09:21 -0400 Subject: [PATCH 02/22] many things have been switched to carbon and the home page loads w/ burnettk --- spiffworkflow-frontend/src/App.tsx | 7 +- .../src/components/ButtonWithConfirmation.tsx | 3 +- .../src/components/NavigationBar.tsx | 4 +- .../src/components/PaginationForTable.tsx | 274 +++++++++--------- .../src/routes/AuthenticationList.tsx | 3 +- .../src/routes/MessageInstanceList.tsx | 3 +- .../src/routes/ProcessGroupEdit.tsx | 3 +- .../src/routes/ProcessGroupList.tsx | 4 +- .../src/routes/ProcessGroupShow.tsx | 3 +- .../src/routes/ProcessInstanceList.tsx | 4 +- .../src/routes/ProcessInstanceLogList.tsx | 3 +- .../src/routes/ProcessInstanceReportList.tsx | 3 +- .../src/routes/ProcessInstanceReportShow.tsx | 3 +- .../src/routes/ProcessInstanceShow.tsx | 3 +- .../src/routes/ProcessModelEdit.tsx | 3 +- .../src/routes/ProcessModelEditDiagram.tsx | 3 +- .../src/routes/ProcessModelShow.tsx | 3 +- .../src/routes/ReactFormEditor.tsx | 3 +- .../src/routes/SecretList.tsx | 3 +- .../src/routes/SecretNew.tsx | 3 +- .../src/routes/SecretShow.tsx | 3 +- .../src/routes/TaskShow.tsx | 3 +- 22 files changed, 185 insertions(+), 159 deletions(-) diff --git a/spiffworkflow-frontend/src/App.tsx b/spiffworkflow-frontend/src/App.tsx index 0444f042..0684465e 100644 --- a/spiffworkflow-frontend/src/App.tsx +++ b/spiffworkflow-frontend/src/App.tsx @@ -1,5 +1,6 @@ import { useMemo, useState } from 'react'; -import { Container } from 'react-bootstrap'; +// @ts-ignore +// import { Container } from '@carbon/react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import ErrorContext from './contexts/ErrorContext'; @@ -48,7 +49,7 @@ export default function App() { return ( - +
{errorTag} @@ -70,7 +71,7 @@ export default function App() { - +
); } diff --git a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx index 6956dadc..663bae1e 100644 --- a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx +++ b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx @@ -1,5 +1,6 @@ import { useState } from 'react'; -import { Button, Modal } from 'react-bootstrap'; +// @ts-ignore +import { Button, Modal } from '@carbon/react'; type OwnProps = { description?: string; diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index 9b070a55..2f70ff0c 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -1,4 +1,6 @@ -import { Button, Navbar, Nav, Container } from 'react-bootstrap'; +// @ts-ignore +import { Button } from '@carbon/react'; +import { Navbar, Nav, Container } from 'react-bootstrap'; // @ts-expect-error TS(2307) FIXME: Cannot find module '../logo.svg' or its correspond... Remove this comment to see the full error message import logo from '../logo.svg'; import UserService from '../services/UserService'; diff --git a/spiffworkflow-frontend/src/components/PaginationForTable.tsx b/spiffworkflow-frontend/src/components/PaginationForTable.tsx index 2f648f52..c1cde1ab 100644 --- a/spiffworkflow-frontend/src/components/PaginationForTable.tsx +++ b/spiffworkflow-frontend/src/components/PaginationForTable.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { Link } from 'react-router-dom'; -import { Dropdown, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Dropdown, Stack } from '@carbon/react'; export const DEFAULT_PER_PAGE = 50; export const DEFAULT_PAGE = 1; @@ -29,139 +30,140 @@ export default function PaginationForTable({ }: OwnProps) { const PER_PAGE_OPTIONS = [2, 10, 50, 100]; - const buildPerPageDropdown = () => { - const perPageDropdownRows = (perPageOptions || PER_PAGE_OPTIONS).map( - (perPageOption) => { - if (perPageOption === perPage) { - return ( - - {perPageOption} - - ); - } - return ( - - {perPageOption} - - ); - } - ); - return ( - - - - Number to show: {perPage} - - - {perPageDropdownRows} - - - ); - }; - - const buildPaginationNav = () => { - let previousPageTag = null; - if (page === 1) { - previousPageTag = ( -
  • - - « - -
  • - ); - } else { - previousPageTag = ( -
  • - - « - -
  • - ); - } - - let nextPageTag = null; - if (page >= pagination.pages) { - nextPageTag = ( -
  • - - » - -
  • - ); - } else { - nextPageTag = ( -
  • - - » - -
  • - ); - } - - let startingNumber = (page - 1) * perPage + 1; - let endingNumber = page * perPage; - if (endingNumber > pagination.total) { - endingNumber = pagination.total; - } - if (startingNumber > pagination.total) { - startingNumber = pagination.total; - } - - return ( - -

    - {startingNumber}-{endingNumber} of{' '} - {pagination.total} -

    - -
    - ); - }; - - return ( -
    - {buildPaginationNav()} - {tableToDisplay} - {buildPerPageDropdown()} -
    - ); + // const buildPerPageDropdown = () => { + // const perPageDropdownRows = (perPageOptions || PER_PAGE_OPTIONS).map( + // (perPageOption) => { + // if (perPageOption === perPage) { + // return ( + // + // {perPageOption} + // + // ); + // } + // return ( + // + // {perPageOption} + // + // ); + // } + // ); + // return ( + // + // + // + // Number to show: {perPage} + // + // + // {perPageDropdownRows} + // + // + // ); + // }; + // + // const buildPaginationNav = () => { + // let previousPageTag = null; + // if (page === 1) { + // previousPageTag = ( + //
  • + // + // « + // + //
  • + // ); + // } else { + // previousPageTag = ( + //
  • + // + // « + // + //
  • + // ); + // } + // + // let nextPageTag = null; + // if (page >= pagination.pages) { + // nextPageTag = ( + //
  • + // + // » + // + //
  • + // ); + // } else { + // nextPageTag = ( + //
  • + // + // » + // + //
  • + // ); + // } + // + // let startingNumber = (page - 1) * perPage + 1; + // let endingNumber = page * perPage; + // if (endingNumber > pagination.total) { + // endingNumber = pagination.total; + // } + // if (startingNumber > pagination.total) { + // startingNumber = pagination.total; + // } + // + // return ( + // + //

    + // {startingNumber}-{endingNumber} of{' '} + // {pagination.total} + //

    + // + //
    + // ); + // }; + // + // return ( + //
    + // {buildPaginationNav()} + // {tableToDisplay} + // {buildPerPageDropdown()} + //
    + // ); + return null; } diff --git a/spiffworkflow-frontend/src/routes/AuthenticationList.tsx b/spiffworkflow-frontend/src/routes/AuthenticationList.tsx index 6be0f054..a249aa27 100644 --- a/spiffworkflow-frontend/src/routes/AuthenticationList.tsx +++ b/spiffworkflow-frontend/src/routes/AuthenticationList.tsx @@ -1,5 +1,6 @@ import { useContext, useEffect, useState } from 'react'; -import { Table } from 'react-bootstrap'; +// @ts-ignore +import { Table } from '@carbon/react'; import ErrorContext from '../contexts/ErrorContext'; import { AuthenticationItem } from '../interfaces'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx b/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx index 90c74c29..6bc0a57d 100644 --- a/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/MessageInstanceList.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; -import { Table } from 'react-bootstrap'; +// @ts-ignore +import { Table } from '@carbon/react'; import { Link, useParams, useSearchParams } from 'react-router-dom'; import PaginationForTable from '../components/PaginationForTable'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx index 83379999..05f75fb1 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx @@ -1,6 +1,7 @@ import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { Button, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index 3c1be15c..29dc3882 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -1,6 +1,8 @@ import { useEffect, useState } from 'react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; -import { Button, Form, InputGroup, Table } from 'react-bootstrap'; +// @ts-ignore +import { Button, Form, Table } from '@carbon/react'; +import { InputGroup } from 'react-bootstrap'; import { Typeahead } from 'react-bootstrap-typeahead'; import { Option } from 'react-bootstrap-typeahead/types/types'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx index 522058c3..02625a8f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import { Link, useSearchParams, useParams } from 'react-router-dom'; -import { Button, Table, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index a2e2aca2..32bf92ba 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -6,7 +6,9 @@ import { useSearchParams, } from 'react-router-dom'; -import { Button, Table, Stack, Form, InputGroup } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table, Stack, Form } from '@carbon/react'; +import { InputGroup } from 'react-bootstrap'; // @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'reac... Remove this comment to see the full error message import DatePicker from 'react-datepicker'; import { Typeahead } from 'react-bootstrap-typeahead'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx index f2d297f0..43a3ef1d 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceLogList.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; -import { Table } from 'react-bootstrap'; +// @ts-ignore +import { Table } from '@carbon/react'; import { useParams, useSearchParams } from 'react-router-dom'; import PaginationForTable from '../components/PaginationForTable'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceReportList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceReportList.tsx index 2d129837..4422b174 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceReportList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceReportList.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; -import { Button, Table } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; import { useParams, Link } from 'react-router-dom'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceReportShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceReportShow.tsx index a006d4b9..1d26e57f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceReportShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceReportShow.tsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react'; import { useParams, useSearchParams } from 'react-router-dom'; -import { Button, Table } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index f5336df8..0d97e608 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -1,7 +1,8 @@ import { useContext, useEffect, useState } from 'react'; import Editor from '@monaco-editor/react'; import { useParams, useNavigate, Link } from 'react-router-dom'; -import { Button, Modal, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Modal, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; import ReactDiagramEditor from '../components/ReactDiagramEditor'; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx index 4567d14a..45648b1f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx @@ -1,6 +1,7 @@ import { useState, useEffect, useContext } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { Button, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx index 2382fce7..aa1eafc6 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx @@ -1,6 +1,7 @@ import { useContext, useEffect, useRef, useState } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; -import { Button, Modal, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Modal, Stack } from '@carbon/react'; import Container from 'react-bootstrap/Container'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 63217d2d..b12aee95 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -1,6 +1,7 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useParams } from 'react-router-dom'; -import { Button, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import FileInput from '../components/FileInput'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx b/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx index 40dd2d89..2b92ea19 100644 --- a/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx +++ b/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react'; import Editor from '@monaco-editor/react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; -import { Button, Modal } from 'react-bootstrap'; +// @ts-ignore +import { Button, Modal } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; diff --git a/spiffworkflow-frontend/src/routes/SecretList.tsx b/spiffworkflow-frontend/src/routes/SecretList.tsx index 2b9e756a..7d165c01 100644 --- a/spiffworkflow-frontend/src/routes/SecretList.tsx +++ b/spiffworkflow-frontend/src/routes/SecretList.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; -import { Button, Table } from 'react-bootstrap'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; import { MdDelete } from 'react-icons/md'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/SecretNew.tsx b/spiffworkflow-frontend/src/routes/SecretNew.tsx index 7a697a98..e1f34e89 100644 --- a/spiffworkflow-frontend/src/routes/SecretNew.tsx +++ b/spiffworkflow-frontend/src/routes/SecretNew.tsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Stack } from 'react-bootstrap'; +// @ts-ignore +import { Stack } from '@carbon/react'; import Button from 'react-bootstrap/Button'; import Form from 'react-bootstrap/Form'; import HttpService from '../services/HttpService'; diff --git a/spiffworkflow-frontend/src/routes/SecretShow.tsx b/spiffworkflow-frontend/src/routes/SecretShow.tsx index 707f0d14..2ee75e19 100644 --- a/spiffworkflow-frontend/src/routes/SecretShow.tsx +++ b/spiffworkflow-frontend/src/routes/SecretShow.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; -import { Stack, Table, Button } from 'react-bootstrap'; +// @ts-ignore +import { Stack, Table, Button } from '@carbon/react'; import HttpService from '../services/HttpService'; import { Secret } from '../interfaces'; import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 28fc8582..97bb5d3c 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -1,7 +1,8 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; import Form from '@rjsf/core'; -import { Button, Stack } from 'react-bootstrap'; +// @ts-ignore +import { Button, Stack } from '@carbon/react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; From 15035c5a4ad1e30b6e9f2f5479c5d033f0395ddb Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 31 Oct 2022 16:03:14 -0400 Subject: [PATCH 03/22] some more changes... navigation bar is broken due to header container w/ burnettk --- spiffworkflow-frontend/src/App.tsx | 20 +- .../src/components/NavigationBar.tsx | 204 +++++++++++++----- spiffworkflow-frontend/src/index.css | 4 +- .../src/routes/ProcessModelEditDiagram.tsx | 8 +- 4 files changed, 161 insertions(+), 75 deletions(-) diff --git a/spiffworkflow-frontend/src/App.tsx b/spiffworkflow-frontend/src/App.tsx index 0684465e..4a078c21 100644 --- a/spiffworkflow-frontend/src/App.tsx +++ b/spiffworkflow-frontend/src/App.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react'; // @ts-ignore -// import { Container } from '@carbon/react'; +import { Content } from '@carbon/react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import ErrorContext from './contexts/ErrorContext'; @@ -46,14 +46,14 @@ export default function App() { ); } + // return ( - -
    - {errorTag} - - - + + + + {errorTag} +
    } /> @@ -69,9 +69,9 @@ export default function App() { />
    -
    -
    -
    + + +
    ); } diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index 2f70ff0c..606a2118 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -1,72 +1,158 @@ -// @ts-ignore -import { Button } from '@carbon/react'; -import { Navbar, Nav, Container } from 'react-bootstrap'; +import { + Header, + Theme, + HeaderName, + HeaderContainer, + HeaderNavigation, + HeaderMenuItem, + HeaderMenu, + // @ts-ignore +} from '@carbon/react'; +import { useEffect, useState } from 'react'; +import { Navbar, Nav } from 'react-bootstrap'; +import { useLocation } from 'react-router-dom'; // @ts-expect-error TS(2307) FIXME: Cannot find module '../logo.svg' or its correspond... Remove this comment to see the full error message import logo from '../logo.svg'; import UserService from '../services/UserService'; // for ref: https://react-bootstrap.github.io/components/navbar/ export default function NavigationBar() { - const navElements = null; + // const navElements = null; + // + // const handleLogout = () => { + // UserService.doLogout(); + // }; + // + // const handleLogin = () => { + // UserService.doLogin(); + // }; + // + // const loginLink = () => { + // if (!UserService.isLoggedIn()) { + // return ( + // + // + // + // + // + // ); + // } + // return null; + // }; + // + // const logoutLink = () => { + // if (UserService.isLoggedIn()) { + // return ( + // + // + // Signed in as: {UserService.getUsername()} + // + // + // + // + // + // ); + // } + // return null; + // }; - const handleLogout = () => { - UserService.doLogout(); - }; + const location = useLocation(); + const [activeKey, setActiveKey] = useState(''); - const handleLogin = () => { - UserService.doLogin(); - }; - - const loginLink = () => { - if (!UserService.isLoggedIn()) { - return ( - - - - - - ); + useEffect(() => { + let newActiveKey = '/admin/process-groups'; + if (location.pathname.match(/^\/admin\/messages\b/)) { + newActiveKey = '/admin/messages'; + } else if (location.pathname.match(/^\/admin\/process-instances\b/)) { + newActiveKey = '/admin/process-instances'; + } else if (location.pathname.match(/^\/admin\/secrets\b/)) { + newActiveKey = '/admin/secrets'; + } else if (location.pathname.match(/^\/admin\/authentications\b/)) { + newActiveKey = '/admin/authentications'; + } else if (location.pathname === '/') { + newActiveKey = '/'; + } else if (location.pathname.match(/^\/tasks\b/)) { + newActiveKey = '/'; } - return null; + setActiveKey(newActiveKey); + }, [location]); + + const isActivePage = (menuItemPath: string) => { + return activeKey === menuItemPath; }; - const logoutLink = () => { - if (UserService.isLoggedIn()) { - return ( - - - Signed in as: {UserService.getUsername()} - - - - - - ); - } - return null; - }; + // return ( + // + // + // + // + // logo + // + // + // + // + // + // {loginLink()} + // {logoutLink()} + // + // + // + // ); - return ( - - - - logo - - - - - - {loginLink()} - {logoutLink()} - - - ); + // + //
    + // + // [Platform] + // + // + // Link 1 + // Link 2 + // Link 3 + // + // Sub-link 1 + // Sub-link 2 + // Sub-link 3 + // + // + //
    + //
    + if (activeKey) { + return ( + + +
    + + logo + + + + Home + + + Processes + + + Process Instances + + +
    +
    +
    + ); + } + return null; } diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index fd156c23..32a712d5 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -20,8 +20,8 @@ span.bjs-crumb { } .app-logo { - height: 35%; - width: 35%; + height: 90%; + width: 90%; margin-top: 1em; margin-bottom: 1em; } diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx index aa1eafc6..9ca0754a 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx @@ -1,8 +1,8 @@ import { useContext, useEffect, useRef, useState } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; // @ts-ignore -import { Button, Modal, Stack } from '@carbon/react'; -import Container from 'react-bootstrap/Container'; +import { Button, Modal, Stack, Content } from '@carbon/react'; +// import Container from 'react-bootstrap/Container'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; @@ -463,7 +463,7 @@ export default function ProcessModelEditDiagram() { } return (
    - + + // + // + // + //
    + //
    + // + // ); + // return ( + // + // + // Hello1 + // + // + // Hello2 + // + // + // ); + // return ( + // + // + // + // Span 25% + // + // + // Span 25% + // + // + // Span 25% + // + // + // Span 25% + // + // + // + // ); return ( -
    -
    -
    -
    - - {processModelSearch()} - -
    - - {dateComponent( - 'Start Range: ', - 'start-from', - startFrom, - setStartFrom - )} - {dateComponent('-', 'start-till', startTill, setStartTill)} - -
    - - {dateComponent( - 'End Range: \u00A0\u00A0', - 'end-from', - endFrom, - setEndFrom - )} - {dateComponent('-', 'end-till', endTill, setEndTill)} - -
    - - {processStatusSearch()} - - - - -
    -
    -
    -
    -
    + <> + + + { + if (processModel) { + return `${processModel.process_group_id}/${ + processModel.id + } (${truncateString(processModel.display_name, 20)})`; + } + return null; + }} + shouldFilterItem={shouldFilterProcessModel} + placeholder="Process Model" + titleText="Process model" + /> + + {processStatusSearch()} + + + + + + + + + + + + + + + ); }; @@ -444,14 +561,6 @@ export default function ProcessInstanceList() { <> {processInstanceTitleElement()} {filterOptions()} - ); } From e199835079de4c918737e06f298b1754e16764e3 Mon Sep 17 00:00:00 2001 From: jasquat Date: Tue, 1 Nov 2022 17:00:59 -0400 Subject: [PATCH 05/22] filter is working for status and process model w/ burnettk --- .../src/routes/ProcessInstanceList.tsx | 204 +++++++----------- 1 file changed, 74 insertions(+), 130 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 498ca916..b6f87262 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -24,7 +24,6 @@ import { InputGroup } from 'react-bootstrap'; // @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'reac... Remove this comment to see the full error message import DatePicker from 'react-datepicker'; import { Typeahead } from 'react-bootstrap-typeahead'; -import { Option } from 'react-bootstrap-typeahead/types/types'; import { PROCESS_STATUSES, DATE_FORMAT } from '../config'; import { convertDateToSeconds, @@ -61,10 +60,11 @@ export default function ProcessInstanceList() { const setErrorMessage = (useContext as any)(ErrorContext)[1]; - const [processStatusSelectionOptions, setProcessStatusSelectionOptions] = - useState([]); + const [processStatusAllOptions, setProcessStatusAllOptions] = useState( + [] + ); const [processStatusSelection, setProcessStatusSelection] = useState< - Option[] + string[] >([]); const [processModelAvailableItems, setProcessModelAvailableItems] = useState< ProcessModel[] @@ -72,9 +72,8 @@ export default function ProcessInstanceList() { const [processModelFilteredItems, setProcessModelFilteredItems] = useState< ProcessModel[] >([]); - const [processModelSelection, setProcessModelSelection] = useState( - [] - ); + const [processModelSelection, setProcessModelSelection] = + useState(null); const parametersToAlwaysFilterBy = useMemo(() => { return { @@ -138,25 +137,25 @@ export default function ProcessInstanceList() { const label = `${item.process_group_id}/${item.id}`; Object.assign(item, { label }); if (label === processModelFullIdentifier) { - setProcessModelSelection([item]); + setProcessModelSelection(item); } return item; }); setProcessModelAvailableItems(selectionArray); setProcessModelFilteredItems(selectionArray); - const processStatusSelectedArray: Option[] = []; - const processStatusSelectionArray = PROCESS_STATUSES.map( + const processStatusSelectedArray: string[] = []; + const processStatusAllOptionsArray = PROCESS_STATUSES.map( (processStatusOption: any) => { const regex = new RegExp(`\\b${processStatusOption}\\b`); if ((searchParams.get('process_status') || '').match(regex)) { - processStatusSelectedArray.push({ label: processStatusOption }); + processStatusSelectedArray.push(processStatusOption); } - return { label: processStatusOption }; + return processStatusOption; } ); setProcessStatusSelection(processStatusSelectedArray); - setProcessStatusSelectionOptions(processStatusSelectionArray); + setProcessStatusAllOptions(processStatusAllOptionsArray); getProcessInstances(); } @@ -191,7 +190,7 @@ export default function ProcessInstanceList() { } }; - const handleFilter = (event: any) => { + const applyFilter = (event: any) => { event.preventDefault(); const { page, perPage } = getPageInfoFromSearchParams(searchParams); let queryParamString = `per_page=${perPage}&page=${page}`; @@ -226,16 +225,11 @@ export default function ProcessInstanceList() { queryParamString += `&end_till=${endTill}`; } if (processStatusSelection.length > 0) { - const processStatusSelectionString = processStatusSelection.map( - (pss: any) => { - return pss.label; - } - ); - queryParamString += `&process_status=${processStatusSelectionString}`; + queryParamString += `&process_status=${processStatusSelection}`; } - if (processModelSelection.length > 0) { - const currentProcessModel: any = processModelSelection[0]; - queryParamString += `&process_group_identifier=${currentProcessModel.process_group_id}&process_model_identifier=${currentProcessModel.id}`; + + if (processModelSelection) { + queryParamString += `&process_group_identifier=${processModelSelection.process_group_id}&process_model_identifier=${processModelSelection.id}`; } setErrorMessage(null); @@ -294,65 +288,6 @@ export default function ProcessInstanceList() { return queryParamString; }; - const processModelSearch = () => { - return ( - - - - Process Model:{' '} - - - - - ); - }; - - const processStatusSearch = () => { - // return ( - // - // - // - // Process Status:{' '} - // - // - // - // - // ); - return ( - { - return item.label || ''; - }} - selectionFeedback="top-after-reopen" - /> - ); - }; const shouldFilterProcessModel = (options: any) => { const processModel: ProcessModel = options.item; const { inputValue } = options; @@ -363,6 +298,54 @@ export default function ProcessInstanceList() { ); }; + const processModelSearch = () => { + return ( + + setProcessModelSelection(selection.selectedItem) + } + id="process-model-select" + items={processModelFilteredItems} + itemToString={(processModel: ProcessModel) => { + if (processModel) { + return `${processModel.process_group_id}/${ + processModel.id + } (${truncateString(processModel.display_name, 20)})`; + } + return null; + }} + shouldFilterItem={shouldFilterProcessModel} + placeholder="Choose a process model" + titleText="Process model" + selectedItem={processModelSelection} + /> + ); + }; + + const processStatusSearch = () => { + return ( + { + setProcessStatusSelection(selection.selectedItems); + }} + itemToString={(item: any) => { + return item || ''; + }} + selectionFeedback="top-after-reopen" + selectedItems={processStatusSelection} + /> + ); + }; + + const clearFilters = () => { + setProcessModelSelection(null); + setProcessStatusSelection([]); + }; + const filterOptions = () => { const { page, perPage } = getPageInfoFromSearchParams(searchParams); // return ( @@ -408,64 +391,25 @@ export default function ProcessInstanceList() { //
    // // ); - // return ( - // - // - // Hello1 - // - // - // Hello2 - // - // - // ); - // return ( - // - // - // - // Span 25% - // - // - // Span 25% - // - // - // Span 25% - // - // - // Span 25% - // - // - // - // ); return ( <> - - { - if (processModel) { - return `${processModel.process_group_id}/${ - processModel.id - } (${truncateString(processModel.display_name, 20)})`; - } - return null; - }} - shouldFilterItem={shouldFilterProcessModel} - placeholder="Process Model" - titleText="Process model" - /> - + {processModelSearch()} {processStatusSearch()} - - + From d0e56a2ea122646879591b8c137d2c4fd0e80099 Mon Sep 17 00:00:00 2001 From: jasquat Date: Tue, 1 Nov 2022 17:30:55 -0400 Subject: [PATCH 06/22] a simple date picker w/ burnettk --- spiffworkflow-frontend/src/config.tsx | 2 +- .../src/routes/ProcessInstanceList.tsx | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/spiffworkflow-frontend/src/config.tsx b/spiffworkflow-frontend/src/config.tsx index 94519ba8..573e96bf 100644 --- a/spiffworkflow-frontend/src/config.tsx +++ b/spiffworkflow-frontend/src/config.tsx @@ -16,4 +16,4 @@ export const PROCESS_STATUSES = [ 'suspended', ]; -export const DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss'; +export const DATE_FORMAT = 'Y-m-d'; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index b6f87262..214ab936 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -9,6 +9,8 @@ import { import { Button, ButtonSet, + DatePicker, + DatePickerInput, Table, Stack, Form, @@ -21,8 +23,6 @@ import { // @ts-ignore } from '@carbon/react'; import { InputGroup } from 'react-bootstrap'; -// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'reac... Remove this comment to see the full error message -import DatePicker from 'react-datepicker'; import { Typeahead } from 'react-bootstrap-typeahead'; import { PROCESS_STATUSES, DATE_FORMAT } from '../config'; import { @@ -397,6 +397,20 @@ export default function ProcessInstanceList() { {processModelSearch()} {processStatusSearch()} + + + {' '} + + + + + From 74976ec6df57086773679bf92bc4541eab714ce0 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 2 Nov 2022 12:42:49 -0400 Subject: [PATCH 07/22] add date ranges for process instances search w/ burnettk --- .../src/spiffworkflow_backend/api.yml | 4 +- .../routes/process_api_blueprint.py | 12 +- spiffworkflow-frontend/src/config.tsx | 4 +- spiffworkflow-frontend/src/helpers.tsx | 25 ++- .../src/routes/ProcessInstanceList.tsx | 191 ++++++++---------- 5 files changed, 110 insertions(+), 126 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index 614d4f26..de10f598 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -429,7 +429,7 @@ paths: description: For filtering - beginning of start window - in seconds since epoch schema: type: integer - - name: start_till + - name: start_to in: query required: false description: For filtering - end of start window - in seconds since epoch @@ -441,7 +441,7 @@ paths: description: For filtering - beginning of end window - in seconds since epoch schema: type: integer - - name: end_till + - name: end_to in: query required: false description: For filtering - end of end window - in seconds since epoch diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index f2ffec20..012cb52f 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -651,9 +651,9 @@ def process_instance_list( page: int = 1, per_page: int = 100, start_from: Optional[int] = None, - start_till: Optional[int] = None, + start_to: Optional[int] = None, end_from: Optional[int] = None, - end_till: Optional[int] = None, + end_to: Optional[int] = None, process_status: Optional[str] = None, ) -> flask.wrappers.Response: """Process_instance_list.""" @@ -684,17 +684,17 @@ def process_instance_list( process_instance_query = process_instance_query.filter( ProcessInstanceModel.start_in_seconds >= start_from ) - if start_till is not None: + if start_to is not None: process_instance_query = process_instance_query.filter( - ProcessInstanceModel.start_in_seconds <= start_till + ProcessInstanceModel.start_in_seconds <= start_to ) if end_from is not None: process_instance_query = process_instance_query.filter( ProcessInstanceModel.end_in_seconds >= end_from ) - if end_till is not None: + if end_to is not None: process_instance_query = process_instance_query.filter( - ProcessInstanceModel.end_in_seconds <= end_till + ProcessInstanceModel.end_in_seconds <= end_to ) if process_status is not None: process_status_array = process_status.split(",") diff --git a/spiffworkflow-frontend/src/config.tsx b/spiffworkflow-frontend/src/config.tsx index 573e96bf..c9e94eb0 100644 --- a/spiffworkflow-frontend/src/config.tsx +++ b/spiffworkflow-frontend/src/config.tsx @@ -16,4 +16,6 @@ export const PROCESS_STATUSES = [ 'suspended', ]; -export const DATE_FORMAT = 'Y-m-d'; +// with time: yyyy-MM-dd HH:mm:ss +export const DATE_FORMAT = 'yyyy-MM-dd'; +export const DATE_FORMAT_CARBON = 'Y-m-d'; diff --git a/spiffworkflow-frontend/src/helpers.tsx b/spiffworkflow-frontend/src/helpers.tsx index e9bb100a..6b27fb4c 100644 --- a/spiffworkflow-frontend/src/helpers.tsx +++ b/spiffworkflow-frontend/src/helpers.tsx @@ -20,7 +20,10 @@ export const capitalizeFirstLetter = (string: any) => { return string.charAt(0).toUpperCase() + string.slice(1); }; -export const convertDateToSeconds = (date: any, onChangeFunction: any) => { +export const convertDateToSeconds = ( + date: any, + onChangeFunction: any = null +) => { let dateInSeconds = date; if (date !== null) { let dateInMilliseconds = date; @@ -39,14 +42,26 @@ export const convertDateToSeconds = (date: any, onChangeFunction: any) => { return null; }; -export const convertSecondsToFormattedDate = (seconds: number) => { - if (seconds) { - const startDate = new Date(seconds * 1000); - return format(startDate, DATE_FORMAT); +export const convertStringToDate = (dateString: string) => { + if (dateString) { + return new Date(dateString); } return null; }; +export const convertSecondsToFormattedDate = (seconds: number) => { + if (seconds) { + const dateObject = new Date(seconds * 1000); + return format(dateObject, DATE_FORMAT); + } + return null; +}; + +export const convertDateStringToSeconds = (dateString: string) => { + const dateObject = convertStringToDate(dateString); + return convertDateToSeconds(dateObject); +}; + export const objectIsEmpty = (obj: object) => { return Object.keys(obj).length === 0; }; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 214ab936..63ee7a2f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -24,9 +24,9 @@ import { } from '@carbon/react'; import { InputGroup } from 'react-bootstrap'; import { Typeahead } from 'react-bootstrap-typeahead'; -import { PROCESS_STATUSES, DATE_FORMAT } from '../config'; +import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; import { - convertDateToSeconds, + convertDateStringToSeconds, convertSecondsToFormattedDate, getPageInfoFromSearchParams, getProcessModelFullIdentifierFromSearchParams, @@ -53,10 +53,10 @@ export default function ProcessInstanceList() { const oneHourInSeconds = 3600; const oneMonthInSeconds = oneHourInSeconds * 24 * 30; - const [startFrom, setStartFrom] = useState(null); - const [startTill, setStartTill] = useState(null); - const [endFrom, setEndFrom] = useState(null); - const [endTill, setEndTill] = useState(null); + const [startFrom, setStartFrom] = useState(''); + const [startTo, setStartTo] = useState(''); + const [endFrom, setEndFrom] = useState(''); + const [endTo, setEndTo] = useState(''); const setErrorMessage = (useContext as any)(ErrorContext)[1]; @@ -69,20 +69,17 @@ export default function ProcessInstanceList() { const [processModelAvailableItems, setProcessModelAvailableItems] = useState< ProcessModel[] >([]); - const [processModelFilteredItems, setProcessModelFilteredItems] = useState< - ProcessModel[] - >([]); const [processModelSelection, setProcessModelSelection] = useState(null); const parametersToAlwaysFilterBy = useMemo(() => { return { start_from: setStartFrom, - start_till: setStartTill, + start_to: setStartTo, end_from: setEndFrom, - end_till: setEndTill, + end_to: setEndTo, }; - }, [setStartFrom, setStartTill, setEndFrom, setEndTill]); + }, [setStartFrom, setStartTo, setEndFrom, setEndTo]); const parametersToGetFromSearchParams = useMemo(() => { return { @@ -109,7 +106,10 @@ export default function ProcessInstanceList() { const searchParamValue = searchParams.get(paramName); if (searchParamValue) { queryParamString += `&${paramName}=${searchParamValue}`; - functionToCall(searchParamValue); + const dateString = convertSecondsToFormattedDate( + searchParamValue as any + ); + functionToCall(dateString); } }); @@ -142,7 +142,6 @@ export default function ProcessInstanceList() { return item; }); setProcessModelAvailableItems(selectionArray); - setProcessModelFilteredItems(selectionArray); const processStatusSelectedArray: string[] = []; const processStatusAllOptionsArray = PROCESS_STATUSES.map( @@ -195,34 +194,46 @@ export default function ProcessInstanceList() { const { page, perPage } = getPageInfoFromSearchParams(searchParams); let queryParamString = `per_page=${perPage}&page=${page}`; - if (isTrueComparison(startFrom, '>', startTill)) { - setErrorMessage({ message: 'startFrom cannot be after startTill' }); + const startFromSeconds = convertDateStringToSeconds(startFrom); + const endFromSeconds = convertDateStringToSeconds(endFrom); + const startToSeconds = convertDateStringToSeconds(startTo); + const endToSeconds = convertDateStringToSeconds(endTo); + if (isTrueComparison(startFromSeconds, '>', startToSeconds)) { + setErrorMessage({ + message: '"Start date from" cannot be after "start date to"', + }); return; } - if (isTrueComparison(endFrom, '>', endTill)) { - setErrorMessage({ message: 'endFrom cannot be after endTill' }); + if (isTrueComparison(endFromSeconds, '>', endToSeconds)) { + setErrorMessage({ + message: '"End date from" cannot be after "end date to"', + }); return; } - if (isTrueComparison(startFrom, '>', endFrom)) { - setErrorMessage({ message: 'startFrom cannot be after endFrom' }); + if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) { + setErrorMessage({ + message: '"Start date from" cannot be after "end date from"', + }); return; } - if (isTrueComparison(startTill, '>', endTill)) { - setErrorMessage({ message: 'startTill cannot be after endTill' }); + if (isTrueComparison(startToSeconds, '>', endToSeconds)) { + setErrorMessage({ + message: '"Start date to" cannot be after "end date to"', + }); return; } - if (startFrom) { - queryParamString += `&start_from=${startFrom}`; + if (startFromSeconds) { + queryParamString += `&start_from=${startFromSeconds}`; } - if (startTill) { - queryParamString += `&start_till=${startTill}`; + if (startToSeconds) { + queryParamString += `&start_to=${startToSeconds}`; } - if (endFrom) { - queryParamString += `&end_from=${endFrom}`; + if (endFromSeconds) { + queryParamString += `&end_from=${endFromSeconds}`; } - if (endTill) { - queryParamString += `&end_till=${endTill}`; + if (endToSeconds) { + queryParamString += `&end_to=${endToSeconds}`; } if (processStatusSelection.length > 0) { queryParamString += `&process_status=${processStatusSelection}`; @@ -242,30 +253,22 @@ export default function ProcessInstanceList() { initialDate: any, onChangeFunction: any ) => { - let selectedDate = null; - if (initialDate) { - selectedDate = new Date(initialDate * 1000); - } return ( - - - - - {labelString} - {'\u00A0'} - - - convertDateToSeconds(date, onChangeFunction) - } - showTimeSelect - dateFormat={DATE_FORMAT} - /> - - - + + { + onChangeFunction(dateChangeEvent.srcElement.value); + }} + value={initialDate} + /> + ); }; @@ -291,10 +294,8 @@ export default function ProcessInstanceList() { const shouldFilterProcessModel = (options: any) => { const processModel: ProcessModel = options.item; const { inputValue } = options; - return ( - processModel.process_group_id.match(inputValue) || - processModel.id.match(inputValue) || - processModel.display_name.match(inputValue) + return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes( + inputValue ); }; @@ -305,7 +306,7 @@ export default function ProcessInstanceList() { setProcessModelSelection(selection.selectedItem) } id="process-model-select" - items={processModelFilteredItems} + items={processModelAvailableItems} itemToString={(processModel: ProcessModel) => { if (processModel) { return `${processModel.process_group_id}/${ @@ -344,53 +345,14 @@ export default function ProcessInstanceList() { const clearFilters = () => { setProcessModelSelection(null); setProcessStatusSelection([]); + setStartFrom(''); + setStartTo(''); + setEndFrom(''); + setEndTo(''); }; const filterOptions = () => { const { page, perPage } = getPageInfoFromSearchParams(searchParams); - // return ( - //
    - //
    - //
    - //
    - // - // {processModelSearch()} - // - //
    - // - // {dateComponent( - // 'Start Range: ', - // 'start-from', - // startFrom, - // setStartFrom - // )} - // {dateComponent('-', 'start-till', startTill, setStartTill)} - // - //
    - // - // {dateComponent( - // 'End Range: \u00A0\u00A0', - // 'end-from', - // endFrom, - // setEndFrom - // )} - // {dateComponent('-', 'end-till', endTill, setEndTill)} - // - //
    - // - // {processStatusSearch()} - // - // - // - // - //
    - //
    - //
    - //
    - //
    - // ); return ( <> @@ -398,17 +360,22 @@ export default function ProcessInstanceList() { {processStatusSearch()} - - {' '} - - - + + {dateComponent( + 'Start date from', + 'start-from', + startFrom, + setStartFrom + )} + + + {dateComponent('Start date to', 'start-to', startTo, setStartTo)} + + + {dateComponent('End date from', 'end-from', endFrom, setEndFrom)} + + + {dateComponent('End date to', 'end-to', endTo, setEndTo)} From 0365c699d8fceb5456bcb9a6182f106037099890 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 2 Nov 2022 14:54:02 -0400 Subject: [PATCH 08/22] finished process instance list filter w/ burnettk --- spiffworkflow-frontend/package-lock.json | 1 + spiffworkflow-frontend/package.json | 1 + .../src/routes/HomePage.tsx | 23 ++++++--- .../src/routes/ProcessInstanceList.tsx | 49 ++++++++++++++----- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index faba49ba..a72fc406 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -11,6 +11,7 @@ "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/preset-react": "^7.18.6", + "@carbon/icons-react": "^11.10.0", "@carbon/react": "^1.16.0", "@carbon/styles": "^1.16.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", diff --git a/spiffworkflow-frontend/package.json b/spiffworkflow-frontend/package.json index c3364a12..c9127d7c 100644 --- a/spiffworkflow-frontend/package.json +++ b/spiffworkflow-frontend/package.json @@ -6,6 +6,7 @@ "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/preset-react": "^7.18.6", + "@carbon/icons-react": "^11.10.0", "@carbon/react": "^1.16.0", "@carbon/styles": "^1.16.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", diff --git a/spiffworkflow-frontend/src/routes/HomePage.tsx b/spiffworkflow-frontend/src/routes/HomePage.tsx index a66ded5c..2cfc0078 100644 --- a/spiffworkflow-frontend/src/routes/HomePage.tsx +++ b/spiffworkflow-frontend/src/routes/HomePage.tsx @@ -5,14 +5,14 @@ import { Link, useSearchParams } from 'react-router-dom'; import PaginationForTable from '../components/PaginationForTable'; import { getPageInfoFromSearchParams } from '../helpers'; import HttpService from '../services/HttpService'; -import { RecentProcessModel } from '../interfaces'; +import { PaginationObject, RecentProcessModel } from '../interfaces'; const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5; export default function HomePage() { const [searchParams] = useSearchParams(); const [tasks, setTasks] = useState([]); - const [pagination, setPagination] = useState(null); + const [pagination, setPagination] = useState(null); useEffect(() => { const { page, perPage } = getPageInfoFromSearchParams( @@ -126,10 +126,10 @@ export default function HomePage() { ); }; - const relevantProcessModelSection = - recentProcessModels.length > 0 && buildRecentProcessModelSection(); - - if (pagination) { + const tasksWaitingForMeComponent = () => { + if (pagination && pagination.total < 1) { + return null; + } const { page, perPage } = getPageInfoFromSearchParams( searchParams, PER_PAGE_FOR_TASKS_ON_HOME_PAGE @@ -145,6 +145,17 @@ export default function HomePage() { tableToDisplay={buildTable()} path="/tasks" /> + + ); + }; + + const relevantProcessModelSection = + recentProcessModels.length > 0 && buildRecentProcessModelSection(); + + if (pagination) { + return ( + <> + {tasksWaitingForMeComponent()} {relevantProcessModelSection} ); diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 63ee7a2f..5be2c3c7 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -6,6 +6,8 @@ import { useSearchParams, } from 'react-router-dom'; +// @ts-ignore +import { Filter } from '@carbon/icons-react'; import { Button, ButtonSet, @@ -57,6 +59,7 @@ export default function ProcessInstanceList() { const [startTo, setStartTo] = useState(''); const [endFrom, setEndFrom] = useState(''); const [endTo, setEndTo] = useState(''); + const [showFilterOptions, setShowFilterOptions] = useState(false); const setErrorMessage = (useContext as any)(ErrorContext)[1]; @@ -352,7 +355,9 @@ export default function ProcessInstanceList() { }; const filterOptions = () => { - const { page, perPage } = getPageInfoFromSearchParams(searchParams); + if (!showFilterOptions) { + return null; + } return ( <> @@ -394,18 +399,6 @@ export default function ProcessInstanceList() { - - - - - ); }; @@ -480,12 +473,42 @@ export default function ProcessInstanceList() { ); }; + const toggleShowFilterOptions = () => { + setShowFilterOptions(!showFilterOptions); + }; + if (pagination) { const { page, perPage } = getPageInfoFromSearchParams(searchParams); return ( <> {processInstanceTitleElement()} + + + + - // - // - // ); - // } - // return null; - // }; - // - // const logoutLink = () => { - // if (UserService.isLoggedIn()) { - // return ( - // - // - // Signed in as: {UserService.getUsername()} - // - // - // - // - // - // ); - // } - // return null; - // }; + const handleLogout = () => { + UserService.doLogout(); + }; + + const handleLogin = () => { + UserService.doLogin(); + }; const location = useLocation(); const [activeKey, setActiveKey] = useState(''); @@ -87,6 +53,24 @@ export default function NavigationBar() { return activeKey === menuItemPath; }; + const loginAndLogoutAction = () => { + if (UserService.isLoggedIn()) { + return ( + <> + {UserService.getUsername()} + + + + + ); + } + return ( + + + + ); + }; + if (activeKey) { return (
    @@ -112,6 +96,7 @@ export default function NavigationBar() { Process Instances + {loginAndLogoutAction()}
    From f0cc086e09702477516132ba52254b5cf38ef526 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 2 Nov 2022 17:16:41 -0400 Subject: [PATCH 10/22] added search bar on process groups page w/ burnettk --- spiffworkflow-frontend/src/App.tsx | 2 - .../src/components/NavigationBar.tsx | 2 - .../src/components/PaginationForTable.tsx | 5 +- .../src/components/ProcessModelSearch.tsx | 45 ++++++++++++++++ spiffworkflow-frontend/src/index.css | 4 +- spiffworkflow-frontend/src/interfaces.ts | 4 ++ .../src/routes/ProcessGroupList.tsx | 40 +++++---------- .../src/routes/ProcessInstanceList.tsx | 51 ++++--------------- 8 files changed, 75 insertions(+), 78 deletions(-) create mode 100644 spiffworkflow-frontend/src/components/ProcessModelSearch.tsx diff --git a/spiffworkflow-frontend/src/App.tsx b/spiffworkflow-frontend/src/App.tsx index 84b99483..186ac513 100644 --- a/spiffworkflow-frontend/src/App.tsx +++ b/spiffworkflow-frontend/src/App.tsx @@ -10,7 +10,6 @@ import HomePage from './routes/HomePage'; import TaskShow from './routes/TaskShow'; import ErrorBoundary from './components/ErrorBoundary'; import AdminRoutes from './routes/AdminRoutes'; -import SubNavigation from './components/SubNavigation'; import { ErrorForDisplay } from './interfaces'; export default function App() { @@ -46,7 +45,6 @@ export default function App() { ); } - // return ( diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index cb3b5271..a51ee779 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -1,11 +1,9 @@ import { Header, Theme, - Button, HeaderName, HeaderNavigation, HeaderMenuItem, - HeaderMenu, HeaderGlobalAction, HeaderGlobalBar, // @ts-ignore diff --git a/spiffworkflow-frontend/src/components/PaginationForTable.tsx b/spiffworkflow-frontend/src/components/PaginationForTable.tsx index 44edff63..d9d94b84 100644 --- a/spiffworkflow-frontend/src/components/PaginationForTable.tsx +++ b/spiffworkflow-frontend/src/components/PaginationForTable.tsx @@ -1,8 +1,7 @@ -import React from 'react'; -import { Link, useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; // @ts-ignore -import { Dropdown, Stack, Pagination } from '@carbon/react'; +import { Pagination } from '@carbon/react'; import { PaginationObject } from '../interfaces'; export const DEFAULT_PER_PAGE = 50; diff --git a/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx new file mode 100644 index 00000000..679831a5 --- /dev/null +++ b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx @@ -0,0 +1,45 @@ +import { + ComboBox, + // @ts-ignore +} from '@carbon/react'; +import { truncateString } from '../helpers'; +import { ProcessModel } from '../interfaces'; + +type OwnProps = { + onChange: (..._args: any[]) => any; + processModels: ProcessModel[]; + selectedItem?: ProcessModel | null; +}; + +export default function ProcessModelSearch({ + processModels, + selectedItem, + onChange, +}: OwnProps) { + const shouldFilterProcessModel = (options: any) => { + const processModel: ProcessModel = options.item; + const { inputValue } = options; + return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes( + inputValue + ); + }; + return ( + { + if (processModel) { + return `${processModel.process_group_id}/${ + processModel.id + } (${truncateString(processModel.display_name, 20)})`; + } + return null; + }} + shouldFilterItem={shouldFilterProcessModel} + placeholder="Choose a process model" + titleText="Process model" + selectedItem={selectedItem} + /> + ); +} diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index 763200df..c51398c4 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -20,8 +20,8 @@ span.bjs-crumb { } .app-logo { - height: 90%; - width: 90%; + height: 85%; + width: 85%; margin-top: 1em; margin-bottom: 1em; } diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index 16e1491b..08c8e4fa 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -47,3 +47,7 @@ export interface PaginationObject { total: number; pages: number; } + +export interface CarbonComboBoxSelection { + selectedItem: ProcessModel; +} diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index 29dc3882..f9881def 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -9,7 +9,8 @@ import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; import { getPageInfoFromSearchParams } from '../helpers'; -import { ProcessModel } from '../interfaces'; +import { CarbonComboBoxSelection, ProcessModel } from '../interfaces'; +import ProcessModelSearch from '../components/ProcessModelSearch'; // Example process group json // {'process_group_id': 'sure', 'display_name': 'Test Workflows', 'id': 'test_process_group'} @@ -19,8 +20,9 @@ export default function ProcessGroupList() { const [processGroups, setProcessGroups] = useState([]); const [pagination, setPagination] = useState(null); - const [processModeleSelectionOptions, setProcessModelSelectionOptions] = - useState([]); + const [processModelAvailableItems, setProcessModelAvailableItems] = useState( + [] + ); useEffect(() => { const setProcessGroupsFromResult = (result: any) => { @@ -33,7 +35,7 @@ export default function ProcessGroupList() { Object.assign(item, { label }); return item; }); - setProcessModelSelectionOptions(selectionArray); + setProcessModelAvailableItems(selectionArray); }; const { page, perPage } = getPageInfoFromSearchParams(searchParams); @@ -99,35 +101,17 @@ export default function ProcessGroupList() { }; const processModelSearchArea = () => { - const processModelSearchOnChange = (selected: Option[]) => { - const processModel = selected[0] as ProcessModel; + const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => { + const processModel = selection.selectedItem; navigate( `/admin/process-models/${processModel.process_group_id}/${processModel.id}` ); }; return ( -
    -

    Search

    - - - - Process Model:{' '} - - - - -
    + ); }; diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 5be2c3c7..10ac2c0b 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -14,25 +14,17 @@ import { DatePicker, DatePickerInput, Table, - Stack, - Form, - ComboBox, Grid, Column, - FlexGrid, - Row, MultiSelect, // @ts-ignore } from '@carbon/react'; -import { InputGroup } from 'react-bootstrap'; -import { Typeahead } from 'react-bootstrap-typeahead'; import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; import { convertDateStringToSeconds, convertSecondsToFormattedDate, getPageInfoFromSearchParams, getProcessModelFullIdentifierFromSearchParams, - truncateString, } from '../helpers'; import PaginationForTable from '../components/PaginationForTable'; @@ -44,6 +36,7 @@ import HttpService from '../services/HttpService'; import 'react-bootstrap-typeahead/css/Typeahead.css'; import 'react-bootstrap-typeahead/css/Typeahead.bs5.css'; import { PaginationObject, ProcessModel } from '../interfaces'; +import ProcessModelSearch from '../components/ProcessModelSearch'; export default function ProcessInstanceList() { const params = useParams(); @@ -294,38 +287,6 @@ export default function ProcessInstanceList() { return queryParamString; }; - const shouldFilterProcessModel = (options: any) => { - const processModel: ProcessModel = options.item; - const { inputValue } = options; - return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes( - inputValue - ); - }; - - const processModelSearch = () => { - return ( - - setProcessModelSelection(selection.selectedItem) - } - id="process-model-select" - items={processModelAvailableItems} - itemToString={(processModel: ProcessModel) => { - if (processModel) { - return `${processModel.process_group_id}/${ - processModel.id - } (${truncateString(processModel.display_name, 20)})`; - } - return null; - }} - shouldFilterItem={shouldFilterProcessModel} - placeholder="Choose a process model" - titleText="Process model" - selectedItem={processModelSelection} - /> - ); - }; - const processStatusSearch = () => { return ( - {processModelSearch()} + + + setProcessModelSelection(selection.selectedItem) + } + processModels={processModelAvailableItems} + selectedItem={processModelSelection} + /> + {processStatusSearch()} From 7fffa650b067df1a978164a8922499faccb37809 Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 3 Nov 2022 15:55:50 -0400 Subject: [PATCH 11/22] some more updates for group forms w/ burnettk --- .../src/spiffworkflow_backend/api.yml | 2 - .../models/process_group.py | 7 + .../routes/process_api_blueprint.py | 23 +-- .../services/process_model_service.py | 3 +- .../integration/test_process_api.py | 13 +- .../src/components/ButtonWithConfirmation.tsx | 44 +++-- .../src/components/ProcessGroupForm.tsx | 178 ++++++++++++++++++ .../src/components/ProcessModelSearch.tsx | 4 +- spiffworkflow-frontend/src/interfaces.ts | 1 + .../src/routes/ProcessGroupEdit.tsx | 74 +------- .../src/routes/ProcessGroupList.tsx | 12 +- .../src/routes/ProcessGroupNew.tsx | 71 ++----- 12 files changed, 266 insertions(+), 166 deletions(-) create mode 100644 spiffworkflow-frontend/src/components/ProcessGroupForm.tsx diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index de10f598..2ca57999 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -153,7 +153,6 @@ paths: description: The number of groups to show per page. Defaults to page 10. schema: type: integer - # process_groups_list get: operationId: spiffworkflow_backend.routes.process_api_blueprint.process_groups_list summary: get list @@ -168,7 +167,6 @@ paths: type: array items: $ref: "#/components/schemas/ProcessModelCategory" - # process_group_add post: operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_add summary: Add process group diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py index 0b100ed4..549ab008 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py @@ -1,5 +1,6 @@ """Process_group.""" from __future__ import annotations +import dataclasses from dataclasses import dataclass from dataclasses import field @@ -20,6 +21,7 @@ class ProcessGroup: id: str # A unique string name, lower case, under scores (ie, 'my_group') display_name: str + description: str | None = None display_order: int | None = 0 admin: bool | None = False process_models: list[ProcessModelInfo] = field( @@ -38,6 +40,11 @@ class ProcessGroup: return True return False + @property + def serialized(self) -> dict: + original_dict = dataclasses.asdict(self) + return {x: original_dict[x] for x in original_dict if x not in ["sort_index"]} + class ProcessGroupSchema(Schema): """ProcessGroupSchema.""" diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index fd20341c..63c717d1 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -43,7 +43,7 @@ from spiffworkflow_backend.models.message_triggerable_process_model import ( MessageTriggerableProcessModel, ) from spiffworkflow_backend.models.principal import PrincipalModel -from spiffworkflow_backend.models.process_group import ProcessGroupSchema +from spiffworkflow_backend.models.process_group import ProcessGroup, ProcessGroupSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema @@ -135,17 +135,13 @@ def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.R def process_group_add( - body: Dict[str, Union[str, bool, int]] + body: dict ) -> flask.wrappers.Response: """Add_process_group.""" process_model_service = ProcessModelService() - process_group = ProcessGroupSchema().load(body) + process_group = ProcessGroup(**body) process_model_service.add_process_group(process_group) - return Response( - json.dumps(ProcessGroupSchema().dump(process_group)), - status=201, - mimetype="application/json", - ) + return make_response(jsonify(process_group), 201) def process_group_delete(process_group_id: str) -> flask.wrappers.Response: @@ -155,12 +151,12 @@ def process_group_delete(process_group_id: str) -> flask.wrappers.Response: def process_group_update( - process_group_id: str, body: Dict[str, Union[str, bool, int]] -) -> Dict[str, Union[str, bool, int]]: + process_group_id: str, body: dict +) -> flask.wrappers.Response: """Process Group Update.""" - process_group = ProcessGroupSchema().load(body) + process_group = ProcessGroup(id=process_group_id, **body) ProcessModelService().update_process_group(process_group) - return ProcessGroupSchema().dump(process_group) # type: ignore + return make_response(jsonify(process_group), 200) def process_groups_list(page: int = 1, per_page: int = 100) -> flask.wrappers.Response: @@ -173,6 +169,7 @@ def process_groups_list(page: int = 1, per_page: int = 100) -> flask.wrappers.Re remainder = len(process_groups) % per_page if remainder > 0: pages += 1 + response_json = { "results": ProcessGroupSchema(many=True).dump(batch), "pagination": { @@ -198,7 +195,7 @@ def process_group_show( status_code=400, ) ) from exception - return ProcessGroupSchema().dump(process_group) + return make_response(jsonify(process_group), 200) def process_model_add( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py index 57d84229..7789493f 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py @@ -1,4 +1,5 @@ """Process_model_service.""" +import dataclasses import json import os import shutil @@ -170,7 +171,7 @@ class ProcessModelService(FileSystemService): json_path = os.path.join(cat_path, self.CAT_JSON_FILE) with open(json_path, "w") as cat_json: json.dump( - self.GROUP_SCHEMA.dump(process_group), + process_group.serialized, cat_json, indent=4, sort_keys=True, diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 9a923b97..6fe38f40 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -1,4 +1,5 @@ """Test Process Api Blueprint.""" +import dataclasses import io import json import time @@ -8,6 +9,7 @@ import pytest from flask.app import Flask from flask.testing import FlaskClient from flask_bpmn.models.db import db +from spiffworkflow_backend import MyJSONEncoder from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec @@ -17,7 +19,7 @@ from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( from spiffworkflow_backend.models.active_task import ActiveTaskModel from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.process_group import ProcessGroup -from spiffworkflow_backend.models.process_group import ProcessGroupSchema +# from spiffworkflow_backend.models.process_group import ProcessGroupSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance_report import ( @@ -388,25 +390,30 @@ class TestProcessApi(BaseTest): display_name="Another Test Category", display_order=0, admin=False, + description="Test Description" ) response = client.post( "/v1.0/process-groups", headers=self.logged_in_headers(with_super_admin_user), content_type="application/json", - data=json.dumps(ProcessGroupSchema().dump(process_group)), + data=json.dumps(process_group.serialized), + ) assert response.status_code == 201 + assert response.json # Check what is returned - result = ProcessGroupSchema().loads(response.get_data(as_text=True)) + result = ProcessGroup(**response.json) assert result is not None assert result.display_name == "Another Test Category" assert result.id == "test" + assert result.description == "Test Description" # Check what is persisted persisted = ProcessModelService().get_process_group("test") assert persisted.display_name == "Another Test Category" assert persisted.id == "test" + assert persisted.description == "Test Description" def test_process_group_delete( self, diff --git a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx index 663bae1e..f8e8bf77 100644 --- a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx +++ b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx @@ -41,23 +41,35 @@ export default function ButtonWithConfirmation({ const confirmationDialog = () => { return ( - - {title} - - {modalBodyElement()} - - - - - + open={showConfirmationPrompt} + danger + modalHeading={description} + modalLabel={title} + primaryButtonText={confirmButtonLabel} + secondaryButtonText="Cancel" + onSecondarySubmit={handleConfirmationPromptCancel} + onRequestSubmit={handleConfirmation} + /> ); + // return ( + // + // + // {title} + // + // {modalBodyElement()} + // + // + // + // + // + // ); }; return ( diff --git a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx new file mode 100644 index 00000000..21cabc93 --- /dev/null +++ b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx @@ -0,0 +1,178 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +// @ts-ignore +import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react'; +import { slugifyString } from '../helpers'; +import HttpService from '../services/HttpService'; +import { ProcessGroup } from '../interfaces'; +import ButtonWithConfirmation from './ButtonWithConfirmation'; + +type OwnProps = { + mode: string; + processGroup: ProcessGroup; + setProcessGroup: (..._args: any[]) => any; +}; + +export default function ProcessGroupForm({ + mode, + processGroup, + setProcessGroup, +}: OwnProps) { + const [identifierInvalid, setIdentifierInvalid] = useState(false); + const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] = + useState(false); + const [displayNameInvalid, setDisplayNameInvalid] = useState(false); + const navigate = useNavigate(); + + const navigateToProcessGroup = (_result: any) => { + if (processGroup) { + navigate(`/admin/process-groups/${processGroup.id}`); + } + }; + + const navigateToProcessGroups = (_result: any) => { + navigate(`/admin/process-groups`); + }; + + const hasValidIdentifier = (identifierToCheck: string) => { + return identifierToCheck.match(/^[a-z0-9][0-9a-z-]+[a-z0-9]$/); + }; + + const deleteProcessGroup = () => { + HttpService.makeCallToBackend({ + path: `/process-groups/${processGroup.id}`, + successCallback: navigateToProcessGroups, + httpMethod: 'DELETE', + }); + }; + + const handleFormSubmission = (event: any) => { + event.preventDefault(); + let hasErrors = false; + if (!hasValidIdentifier(processGroup.id)) { + setIdentifierInvalid(true); + hasErrors = true; + } + if (processGroup.display_name === '') { + setDisplayNameInvalid(true); + hasErrors = true; + } + if (hasErrors) { + return; + } + let path = '/process-groups'; + if (mode === 'edit') { + path = `/process-groups/${processGroup.id}`; + } + let httpMethod = 'POST'; + if (mode === 'edit') { + httpMethod = 'PUT'; + } + const postBody = { + display_name: processGroup.display_name, + description: processGroup.description, + }; + if (mode === 'new') { + Object.assign(postBody, { id: processGroup.id }); + } + + HttpService.makeCallToBackend({ + path, + successCallback: navigateToProcessGroup, + httpMethod, + postBody, + }); + }; + + const updateProcessGroup = (newValues: any) => { + const processGroupToCopy = { + ...processGroup, + }; + Object.assign(processGroupToCopy, newValues); + setProcessGroup(processGroupToCopy); + }; + + const onDisplayNameChanged = (newDisplayName: any) => { + setDisplayNameInvalid(false); + const updateDict = { display_name: newDisplayName }; + if (!idHasBeenUpdatedByUser) { + Object.assign(updateDict, { id: slugifyString(newDisplayName) }); + } + updateProcessGroup(updateDict); + }; + + const formElements = () => { + const textInputs = [ + onDisplayNameChanged(event.target.value)} + onBlur={(event: any) => console.log('event', event)} + />, + ]; + + if (mode === 'new') { + textInputs.push( + { + updateProcessGroup({ id: event.target.value }); + // was invalid, and now valid + if (identifierInvalid && hasValidIdentifier(event.target.value)) { + setIdentifierInvalid(false); + } + setIdHasBeenUpdatedByUser(true); + }} + /> + ); + } + + textInputs.push( + + updateProcessGroup({ description: event.target.value }) + } + /> + ); + + return textInputs; + }; + + const formButtons = () => { + const buttons = [ + , + ]; + if (mode === 'edit') { + buttons.push( + + ); + } + return {buttons}; + }; + + return ( +
    + + {formElements()} + {formButtons()} + +
    + ); +} diff --git a/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx index 679831a5..1f138f6e 100644 --- a/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx +++ b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx @@ -9,12 +9,14 @@ type OwnProps = { onChange: (..._args: any[]) => any; processModels: ProcessModel[]; selectedItem?: ProcessModel | null; + titleText?: string; }; export default function ProcessModelSearch({ processModels, selectedItem, onChange, + titleText = 'Process model', }: OwnProps) { const shouldFilterProcessModel = (options: any) => { const processModel: ProcessModel = options.item; @@ -38,7 +40,7 @@ export default function ProcessModelSearch({ }} shouldFilterItem={shouldFilterProcessModel} placeholder="Choose a process model" - titleText="Process model" + titleText={titleText} selectedItem={selectedItem} /> ); diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index 08c8e4fa..14ead3ba 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -14,6 +14,7 @@ export interface RecentProcessModel { export interface ProcessGroup { id: string; display_name: string; + description?: string | null; } export interface ProcessModel { diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx index 05f75fb1..d624309c 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupEdit.tsx @@ -1,21 +1,18 @@ import { useState, useEffect } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; // @ts-ignore -import { Button, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import HttpService from '../services/HttpService'; -import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; +import ProcessGroupForm from '../components/ProcessGroupForm'; +import { ProcessGroup } from '../interfaces'; export default function ProcessGroupEdit() { - const [displayName, setDisplayName] = useState(''); const params = useParams(); - const navigate = useNavigate(); - const [processGroup, setProcessGroup] = useState(null); + const [processGroup, setProcessGroup] = useState(null); useEffect(() => { const setProcessGroupsFromResult = (result: any) => { setProcessGroup(result); - setDisplayName(result.display_name); }; HttpService.makeCallToBackend({ @@ -24,69 +21,16 @@ export default function ProcessGroupEdit() { }); }, [params]); - const navigateToProcessGroup = (_result: any) => { - navigate(`/admin/process-groups/${(processGroup as any).id}`); - }; - - const navigateToProcessGroups = (_result: any) => { - navigate(`/admin/process-groups`); - }; - - const updateProcessGroup = (event: any) => { - event.preventDefault(); - HttpService.makeCallToBackend({ - path: `/process-groups/${(processGroup as any).id}`, - successCallback: navigateToProcessGroup, - httpMethod: 'PUT', - postBody: { - display_name: displayName, - id: (processGroup as any).id, - }, - }); - }; - - const deleteProcessGroup = () => { - HttpService.makeCallToBackend({ - path: `/process-groups/${(processGroup as any).id}`, - successCallback: navigateToProcessGroups, - httpMethod: 'DELETE', - }); - }; - - const onDisplayNameChanged = (newDisplayName: any) => { - setDisplayName(newDisplayName); - }; - if (processGroup) { return ( <>

    Edit Process Group: {(processGroup as any).id}

    -
    - - onDisplayNameChanged(e.target.value)} - /> -
    -
    - - - - - -
    + ); } diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index f9881def..bb19e939 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -1,15 +1,12 @@ import { useEffect, useState } from 'react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; // @ts-ignore -import { Button, Form, Table } from '@carbon/react'; -import { InputGroup } from 'react-bootstrap'; -import { Typeahead } from 'react-bootstrap-typeahead'; -import { Option } from 'react-bootstrap-typeahead/types/types'; +import { Button, Table } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; import { getPageInfoFromSearchParams } from '../helpers'; -import { CarbonComboBoxSelection, ProcessModel } from '../interfaces'; +import { CarbonComboBoxSelection } from '../interfaces'; import ProcessModelSearch from '../components/ProcessModelSearch'; // Example process group json @@ -111,6 +108,7 @@ export default function ProcessGroupList() { ); }; @@ -119,7 +117,9 @@ export default function ProcessGroupList() { return ( <> - +

    {processModelSearchArea()} diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupNew.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupNew.tsx index 2f3f3a35..d4d8b038 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupNew.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupNew.tsx @@ -1,71 +1,24 @@ import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import Button from 'react-bootstrap/Button'; -import Form from 'react-bootstrap/Form'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; -import { slugifyString } from '../helpers'; -import HttpService from '../services/HttpService'; +import ProcessGroupForm from '../components/ProcessGroupForm'; +import { ProcessGroup } from '../interfaces'; export default function ProcessGroupNew() { - const [identifier, setIdentifier] = useState(''); - const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] = useState(false); - const [displayName, setDisplayName] = useState(''); - const navigate = useNavigate(); - - const navigateToProcessGroup = (_result: any) => { - navigate(`/admin/process-groups/${identifier}`); - }; - - const addProcessGroup = (event: any) => { - event.preventDefault(); - HttpService.makeCallToBackend({ - path: `/process-groups`, - successCallback: navigateToProcessGroup, - httpMethod: 'POST', - postBody: { - id: identifier, - display_name: displayName, - }, - }); - }; - - const onDisplayNameChanged = (newDisplayName: any) => { - setDisplayName(newDisplayName); - if (!idHasBeenUpdatedByUser) { - setIdentifier(slugifyString(newDisplayName)); - } - }; + const [processGroup, setProcessGroup] = useState({ + id: '', + display_name: '', + description: '', + }); return ( <>

    Add Process Group

    -
    - - Display Name: - onDisplayNameChanged(e.target.value)} - /> - - - ID: - { - setIdentifier(e.target.value); - setIdHasBeenUpdatedByUser(true); - }} - /> - - -
    + ); } From 57cc5f732b5bf7a1842f7a1974f13d9394d179ce Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 4 Nov 2022 11:03:40 -0400 Subject: [PATCH 12/22] pyl is passing w/ burnettk --- .../models/process_group.py | 3 ++- .../models/process_model.py | 1 - .../routes/process_api_blueprint.py | 21 ++++++++------- .../services/process_model_service.py | 2 -- .../integration/test_process_api.py | 15 +++++------ .../src/routes/ProcessGroupList.tsx | 27 ++++++++++++++++--- 6 files changed, 43 insertions(+), 26 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py index 549ab008..381f8f63 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_group.py @@ -1,7 +1,7 @@ """Process_group.""" from __future__ import annotations -import dataclasses +import dataclasses from dataclasses import dataclass from dataclasses import field from typing import Any @@ -42,6 +42,7 @@ class ProcessGroup: @property def serialized(self) -> dict: + """Serialized.""" original_dict = dataclasses.asdict(self) return {x: original_dict[x] for x in original_dict if x not in ["sort_index"]} diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_model.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_model.py index 9558a79b..1928f312 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_model.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_model.py @@ -30,7 +30,6 @@ class ProcessModelInfo: display_name: str description: str process_group_id: str = "" - process_group: Any | None = None primary_file_name: str | None = None primary_process_id: str | None = None display_order: int | None = 0 diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index 63c717d1..65fc299b 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -43,7 +43,8 @@ from spiffworkflow_backend.models.message_triggerable_process_model import ( MessageTriggerableProcessModel, ) from spiffworkflow_backend.models.principal import PrincipalModel -from spiffworkflow_backend.models.process_group import ProcessGroup, ProcessGroupSchema +from spiffworkflow_backend.models.process_group import ProcessGroup +from spiffworkflow_backend.models.process_group import ProcessGroupSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema @@ -134,9 +135,7 @@ def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.R return make_response(jsonify({"results": response_dict}), 200) -def process_group_add( - body: dict -) -> flask.wrappers.Response: +def process_group_add(body: dict) -> flask.wrappers.Response: """Add_process_group.""" process_model_service = ProcessModelService() process_group = ProcessGroup(**body) @@ -150,11 +149,16 @@ def process_group_delete(process_group_id: str) -> flask.wrappers.Response: return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") -def process_group_update( - process_group_id: str, body: dict -) -> flask.wrappers.Response: +def process_group_update(process_group_id: str, body: dict) -> flask.wrappers.Response: """Process Group Update.""" - process_group = ProcessGroup(id=process_group_id, **body) + body_include_list = ["display_name", "description"] + body_filtered = { + include_item: body[include_item] + for include_item in body_include_list + if include_item in body + } + + process_group = ProcessGroup(id=process_group_id, **body_filtered) ProcessModelService().update_process_group(process_group) return make_response(jsonify(process_group), 200) @@ -221,7 +225,6 @@ def process_model_add( status_code=400, ) - process_model_info.process_group = process_group process_model_service.add_spec(process_model_info) return Response( json.dumps(ProcessModelInfoSchema().dump(process_model_info)), diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py index 7789493f..e10092d5 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_model_service.py @@ -1,5 +1,4 @@ """Process_model_service.""" -import dataclasses import json import os import shutil @@ -275,6 +274,5 @@ class ProcessModelService(FileSystemService): with open(spec_path, "w") as wf_json: json.dump(self.WF_SCHEMA.dump(spec), wf_json, indent=4) if process_group: - spec.process_group = process_group spec.process_group_id = process_group.id return spec diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 6fe38f40..9b8b75da 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -1,5 +1,4 @@ """Test Process Api Blueprint.""" -import dataclasses import io import json import time @@ -9,7 +8,6 @@ import pytest from flask.app import Flask from flask.testing import FlaskClient from flask_bpmn.models.db import db -from spiffworkflow_backend import MyJSONEncoder from tests.spiffworkflow_backend.helpers.base_test import BaseTest from tests.spiffworkflow_backend.helpers.test_data import load_test_spec @@ -19,7 +17,6 @@ from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( from spiffworkflow_backend.models.active_task import ActiveTaskModel from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.process_group import ProcessGroup -# from spiffworkflow_backend.models.process_group import ProcessGroupSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance_report import ( @@ -390,14 +387,13 @@ class TestProcessApi(BaseTest): display_name="Another Test Category", display_order=0, admin=False, - description="Test Description" + description="Test Description", ) response = client.post( "/v1.0/process-groups", headers=self.logged_in_headers(with_super_admin_user), content_type="application/json", data=json.dumps(process_group.serialized), - ) assert response.status_code == 201 assert response.json @@ -468,7 +464,7 @@ class TestProcessApi(BaseTest): f"/v1.0/process-groups/{group_id}", headers=self.logged_in_headers(with_super_admin_user), content_type="application/json", - data=json.dumps(ProcessGroupSchema().dump(process_group)), + data=json.dumps(process_group.serialized), ) assert response.status_code == 200 @@ -795,6 +791,7 @@ class TestProcessApi(BaseTest): f"/v1.0/process-groups/{test_process_group_id}", headers=self.logged_in_headers(with_super_admin_user), ) + assert response.status_code == 200 assert response.json is not None assert response.json["id"] == test_process_group_id @@ -1304,7 +1301,7 @@ class TestProcessApi(BaseTest): # start > 2000, end < 5000 - this should eliminate the first 2 and the last response = client.get( - "/v1.0/process-instances?start_from=2001&end_till=5999", + "/v1.0/process-instances?start_from=2001&end_to=5999", headers=self.logged_in_headers(with_super_admin_user), ) assert response.json is not None @@ -1315,7 +1312,7 @@ class TestProcessApi(BaseTest): # start > 1000, start < 4000 - this should eliminate the first and the last 2 response = client.get( - "/v1.0/process-instances?start_from=1001&start_till=3999", + "/v1.0/process-instances?start_from=1001&start_to=3999", headers=self.logged_in_headers(with_super_admin_user), ) assert response.json is not None @@ -1326,7 +1323,7 @@ class TestProcessApi(BaseTest): # end > 2000, end < 6000 - this should eliminate the first and the last response = client.get( - "/v1.0/process-instances?end_from=2001&end_till=5999", + "/v1.0/process-instances?end_from=2001&end_to=5999", headers=self.logged_in_headers(with_super_admin_user), ) assert response.json is not None diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index bb19e939..3e396448 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -1,12 +1,20 @@ import { useEffect, useState } from 'react'; import { Link, useNavigate, useSearchParams } from 'react-router-dom'; -// @ts-ignore -import { Button, Table } from '@carbon/react'; +import { + Button, + Table, + ExpandableTile, + TileAboveTheFoldContent, + TileBelowTheFoldContent, + TextInput, + ClickableTile, + // @ts-ignore +} from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; import { getPageInfoFromSearchParams } from '../helpers'; -import { CarbonComboBoxSelection } from '../interfaces'; +import { CarbonComboBoxSelection, ProcessGroup } from '../interfaces'; import ProcessModelSearch from '../components/ProcessModelSearch'; // Example process group json @@ -49,7 +57,7 @@ export default function ProcessGroupList() { }, [searchParams]); const buildTable = () => { - const rows = processGroups.map((row) => { + const rows = processGroups.map((row: ProcessGroup) => { return ( @@ -73,6 +81,17 @@ export default function ProcessGroupList() { {rows} ); + // const rows = processGroups.map((row: ProcessGroup) => { + // return ( + // + // + // {row.display_name} + // + // + // ); + // }); + // + // return
    {rows}
    ; }; const processGroupsDisplayArea = () => { From 8a7a7f3de295eebd06bf4673ea77342926862dfd Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 4 Nov 2022 12:20:55 -0400 Subject: [PATCH 13/22] process group cypress tests are passing w/ burnettk --- spiffworkflow-frontend/cypress.config.js | 5 +++ .../cypress/e2e/process_groups.cy.js | 4 +-- .../cypress/support/commands.js | 19 +++++----- spiffworkflow-frontend/package-lock.json | 12 +++---- .../src/components/ButtonWithConfirmation.tsx | 8 +---- .../src/components/NavigationBar.tsx | 12 +++++-- .../src/components/PaginationForTable.tsx | 36 ++++++++++--------- .../src/components/ProcessGroupForm.tsx | 5 ++- .../src/routes/ProcessGroupList.tsx | 10 +++--- 9 files changed, 61 insertions(+), 50 deletions(-) diff --git a/spiffworkflow-frontend/cypress.config.js b/spiffworkflow-frontend/cypress.config.js index c4bf94c4..1c8c1c6e 100644 --- a/spiffworkflow-frontend/cypress.config.js +++ b/spiffworkflow-frontend/cypress.config.js @@ -10,4 +10,9 @@ module.exports = defineConfig({ // implement node event listeners here }, }, + + // this scrolls away from the elements for some reason with carbon when set to top + // https://github.com/cypress-io/cypress/issues/2353 + // https://docs.cypress.io/guides/core-concepts/interacting-with-elements#Scrolling + scrollBehavior: "center", }); diff --git a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js index 1f2c675e..4860a68b 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js @@ -30,9 +30,9 @@ describe('process-groups', () => { newGroupDisplayName ); - cy.contains('Delete').click(); + cy.contains('Delete Process Group').click(); cy.contains('Are you sure'); - cy.contains('OK').click(); + cy.getBySel('modal-confirmation-dialog').get('.cds--btn--danger').click(); cy.url().should('include', `process-groups`); cy.contains(groupId).should('not.exist'); }); diff --git a/spiffworkflow-frontend/cypress/support/commands.js b/spiffworkflow-frontend/cypress/support/commands.js index 1b9c9241..e6d801d8 100644 --- a/spiffworkflow-frontend/cypress/support/commands.js +++ b/spiffworkflow-frontend/cypress/support/commands.js @@ -101,18 +101,15 @@ Cypress.Commands.add( ); Cypress.Commands.add('basicPaginationTest', () => { - cy.get('#pagination-page-dropdown') - .type('typing_to_open_dropdown_box....FIXME') - .find('.dropdown-item') - .contains(/^2$/) - .click(); + cy.getBySel('pagination-options').scrollIntoView(); + cy.get('.cds--select__item-count').find('.cds--select-input').select('2'); - cy.contains(/^1-2 of \d+$/); - cy.getBySel('pagination-previous-button-inactive'); - cy.getBySel('pagination-next-button').click(); - cy.contains(/^3-4 of \d+$/); - cy.getBySel('pagination-previous-button').click(); - cy.contains(/^1-2 of \d+$/); + // NOTE: this is a em dash instead of en dash + cy.contains(/\b1–2 of \d+/); + cy.get('.cds--pagination__button--forward').click(); + cy.contains(/\b3–4 of \d+/); + cy.get('.cds--pagination__button--backward').click(); + cy.contains(/\b1–2 of \d+/); }); Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => { diff --git a/spiffworkflow-frontend/package-lock.json b/spiffworkflow-frontend/package-lock.json index a72fc406..a08036b5 100644 --- a/spiffworkflow-frontend/package-lock.json +++ b/spiffworkflow-frontend/package-lock.json @@ -9193,9 +9193,9 @@ "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==" }, "node_modules/cypress": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.8.0.tgz", - "integrity": "sha512-QVse0dnLm018hgti2enKMVZR9qbIO488YGX06nH5j3Dg1isL38DwrBtyrax02CANU6y8F4EJUuyW6HJKw1jsFA==", + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz", + "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -36484,9 +36484,9 @@ "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==" }, "cypress": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.8.0.tgz", - "integrity": "sha512-QVse0dnLm018hgti2enKMVZR9qbIO488YGX06nH5j3Dg1isL38DwrBtyrax02CANU6y8F4EJUuyW6HJKw1jsFA==", + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz", + "integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==", "dev": true, "requires": { "@cypress/request": "^2.88.10", diff --git a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx index f8e8bf77..31a8e5ef 100644 --- a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx +++ b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx @@ -26,13 +26,6 @@ export default function ButtonWithConfirmation({ setShowConfirmationPrompt(false); }; - const modalBodyElement = () => { - if (description) { - return {description}; - } - return null; - }; - const handleConfirmation = () => { onConfirmation(); setShowConfirmationPrompt(false); @@ -43,6 +36,7 @@ export default function ButtonWithConfirmation({ {UserService.getUsername()} - + ); } return ( - + ); diff --git a/spiffworkflow-frontend/src/components/PaginationForTable.tsx b/spiffworkflow-frontend/src/components/PaginationForTable.tsx index d9d94b84..3b65c78c 100644 --- a/spiffworkflow-frontend/src/components/PaginationForTable.tsx +++ b/spiffworkflow-frontend/src/components/PaginationForTable.tsx @@ -35,20 +35,24 @@ export default function PaginationForTable({ navigate(`${path}?page=${newPage}&per_page=${pageSize}${queryParamString}`); }; - return ( - <> - {tableToDisplay} - - - ); + if (pagination) { + return ( + <> + {tableToDisplay} + + + ); + } + return null; } diff --git a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx index 21cabc93..99db3434 100644 --- a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx +++ b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx @@ -105,6 +105,7 @@ export default function ProcessGroupForm({ const textInputs = [ @@ -159,7 +162,7 @@ export default function ProcessGroupForm({ ); diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx index 3e396448..13f3d455 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupList.tsx @@ -3,11 +3,11 @@ import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { Button, Table, - ExpandableTile, - TileAboveTheFoldContent, - TileBelowTheFoldContent, - TextInput, - ClickableTile, + // ExpandableTile, + // TileAboveTheFoldContent, + // TileBelowTheFoldContent, + // TextInput, + // ClickableTile, // @ts-ignore } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; From 5b2264b7f87c83cf806c87096a10480eaf2994b0 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 4 Nov 2022 12:48:05 -0400 Subject: [PATCH 14/22] process model cypress tests are passing w/ burnettk --- .../cypress/e2e/process_models.cy.js | 12 ++--- .../src/components/ButtonWithConfirmation.tsx | 21 +-------- .../src/components/ProcessModelSearch.tsx | 1 + .../src/components/ReactDiagramEditor.tsx | 3 +- .../src/routes/ProcessModelEditDiagram.tsx | 44 ++++++++---------- .../src/routes/ReactFormEditor.tsx | 46 ++++++++----------- 6 files changed, 47 insertions(+), 80 deletions(-) diff --git a/spiffworkflow-frontend/cypress/e2e/process_models.cy.js b/spiffworkflow-frontend/cypress/e2e/process_models.cy.js index 3b28514b..48b65d5d 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_models.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_models.cy.js @@ -99,7 +99,7 @@ describe('process-models', () => { cy.contains(/^Process Model File$/); // Some reason, cypress evals json strings so we have to escape it it with '{{}' cy.get('.view-line').type('{{} "test_key": "test_value" }'); - cy.contains('Save').click(); + cy.getBySel('file-save-button').click(); cy.get('input[name=file_name]').type(jsonFileName); cy.contains('Save Changes').click(); cy.contains(`Process Model File: ${jsonFileName}`); @@ -168,12 +168,8 @@ describe('process-models', () => { }); it('can allow searching for model', () => { - cy.get('[name=process-model-selection]').click(); - cy.get('[name=process-model-selection]').type('model-3'); - cy.get( - `[aria-label="acceptance-tests-group-one/acceptance-tests-model-3"]` - ).click(); - - cy.contains('Process Instances').click(); + cy.getBySel('process-model-selection').click().type('model-3'); + cy.contains('acceptance-tests-group-one/acceptance-tests-model-3').click(); + cy.contains('List').click(); }); }); diff --git a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx index 31a8e5ef..25aaadc1 100644 --- a/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx +++ b/spiffworkflow-frontend/src/components/ButtonWithConfirmation.tsx @@ -45,30 +45,11 @@ export default function ButtonWithConfirmation({ onRequestSubmit={handleConfirmation} /> ); - // return ( - // - // - // {title} - // - // {modalBodyElement()} - // - // - // - // - // - // ); }; return ( <> - {confirmationDialog()} diff --git a/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx index 1f138f6e..98419d6c 100644 --- a/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx +++ b/spiffworkflow-frontend/src/components/ProcessModelSearch.tsx @@ -29,6 +29,7 @@ export default function ProcessModelSearch({ { if (processModel) { diff --git a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx index 9728e7d5..2bbf64db 100644 --- a/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx +++ b/spiffworkflow-frontend/src/components/ReactDiagramEditor.tsx @@ -18,7 +18,8 @@ import { } from 'dmn-js-properties-panel'; import React, { useRef, useEffect, useState } from 'react'; -import Button from 'react-bootstrap/Button'; +// @ts-ignore +import { Button } from '@carbon/react'; import 'bpmn-js/dist/assets/diagram-js.css'; import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx index 787db12c..f6fb211f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx @@ -194,31 +194,25 @@ export default function ProcessModelEditDiagram() { const newFileNameBox = () => { const fileExtension = `.${searchParams.get('file_type')}`; return ( - - - Process Model File Name - -
    - - - setNewFileName(e.target.value)} - autoFocus - /> - {fileExtension} - - - - - -
    + + + + setNewFileName(e.target.value)} + autoFocus + /> + {fileExtension} + ); }; diff --git a/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx b/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx index 2b92ea19..e706a3ef 100644 --- a/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx +++ b/spiffworkflow-frontend/src/routes/ReactFormEditor.tsx @@ -119,31 +119,25 @@ export default function ReactFormEditor() { const newFileNameBox = () => { return ( - - - Process Model File Name - -
    - - - setNewFileName(e.target.value)} - autoFocus - /> - .{fileExtension} - - - - - -
    + + + + setNewFileName(e.target.value)} + autoFocus + /> + {fileExtension} + ); }; @@ -161,7 +155,7 @@ export default function ReactFormEditor() { {processModelFile ? `: ${(processModelFile as any).name}` : ''} {newFileNameBox()} - {params.file_name ? ( From b1656084304787be286d2bcf639602914ed08654 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 4 Nov 2022 15:07:40 -0400 Subject: [PATCH 15/22] instances tests are mostly passing, issues with table resizing on the list w/ burnettk --- .../cypress/e2e/process_groups.cy.js | 2 +- .../cypress/e2e/process_instances.cy.js | 10 +- .../cypress/support/commands.js | 2 +- .../src/components/NavigationBar.tsx | 79 +++++--- spiffworkflow-frontend/src/index.css | 4 + spiffworkflow-frontend/src/index.scss | 2 + .../src/routes/ProcessInstanceList.tsx | 188 +++++++++++++----- .../src/routes/ProcessModelEditDiagram.tsx | 40 ++-- 8 files changed, 229 insertions(+), 98 deletions(-) diff --git a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js index 4860a68b..9e974084 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js @@ -32,7 +32,7 @@ describe('process-groups', () => { cy.contains('Delete Process Group').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').get('.cds--btn--danger').click(); + cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.url().should('include', `process-groups`); cy.contains(groupId).should('not.exist'); }); diff --git a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js index d5383d5a..a2fcb266 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js @@ -48,7 +48,7 @@ const updateBpmnPythonScriptWithMonaco = ( .focused() // change subject to currently focused element // .type('{ctrl}a') // had been doing it this way, but it turns out to be flaky relative to clear() .clear() - .type(pythonScript); + .type(pythonScript, { delay: 30 }); cy.contains('Close').click(); // wait for a little bit for the xml to get set before saving @@ -111,8 +111,10 @@ describe('process-instances', () => { }); it('can create a new instance and can modify with monaco text editor', () => { - const originalPythonScript = 'person = "Kevin"'; - const newPythonScript = 'person = "Mike"'; + // leave off the ending double quote since manco adds it + const originalPythonScript = 'person = "Kevin'; + const newPythonScript = 'person = "Mike'; + const bpmnFile = 'process_model_one.bpmn'; // Change bpmn @@ -152,7 +154,7 @@ describe('process-instances', () => { cy.basicPaginationTest(); }); - it('can filter', () => { + it.only('can filter', () => { cy.getBySel('process-instance-list-link').click(); cy.assertAtLeastOneItemInPaginatedResults(); diff --git a/spiffworkflow-frontend/cypress/support/commands.js b/spiffworkflow-frontend/cypress/support/commands.js index e6d801d8..3a1a0ac4 100644 --- a/spiffworkflow-frontend/cypress/support/commands.js +++ b/spiffworkflow-frontend/cypress/support/commands.js @@ -35,7 +35,7 @@ Cypress.Commands.add('navigateToHome', () => { }); Cypress.Commands.add('navigateToAdmin', () => { - cy.getBySel('spiffworkflow-logo').click(); + cy.visit('/admin'); }); Cypress.Commands.add('login', (selector, ...args) => { diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index 8dd0ed6b..4dd81f9a 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -1,6 +1,14 @@ import { Header, + HeaderContainer, + HeaderMenuButton, + SkipToContent, Theme, + HeaderMenu, + SideNav, + SideNavItem, + SideNavItems, + HeaderSideNavItems, HeaderName, HeaderNavigation, HeaderMenuItem, @@ -77,35 +85,60 @@ export default function NavigationBar() { ); }; - if (activeKey) { + const headerMenuItems = () => { return ( -
    - -
    - + <> + + Home + + + Processes + + + Process Instances + + + ); + }; + + if (activeKey) { + // TODO: apply theme g100 to the header + return ( + ( +
    + + + logo - - - Home - - - Processes - - - Process Instances - + + {headerMenuItems()} + + + {headerMenuItems()} + + {loginAndLogoutAction()}
    - -
    + )} + /> ); } return null; diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index c51398c4..67494b82 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -30,6 +30,10 @@ span.bjs-crumb { margin-bottom: 2em; } +// forces the navigation items to be displayed at all viewport sizes +.cds--header__nav { + display: block; +} .active-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) { fill: yellow !important; diff --git a/spiffworkflow-frontend/src/index.scss b/spiffworkflow-frontend/src/index.scss index c9671651..b4c90da1 100644 --- a/spiffworkflow-frontend/src/index.scss +++ b/spiffworkflow-frontend/src/index.scss @@ -1,3 +1,5 @@ +// @use '@carbon/react/scss/themes'; +// @use '@carbon/react/scss/theme' with ($theme: themes.$g100); @use '@carbon/react'; @use '@carbon/styles'; // @include grid.flex-grid(); diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 10ac2c0b..84ce676f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -17,6 +17,11 @@ import { Grid, Column, MultiSelect, + TableHeader, + TableHead, + TableRow, + TableBody, + TableCell, // @ts-ignore } from '@carbon/react'; import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; @@ -373,55 +378,144 @@ export default function ProcessInstanceList() { }; const buildTable = () => { - const rows = processInstances.map((row: any) => { - const formattedStartDate = - convertSecondsToFormattedDate(row.start_in_seconds) || '-'; - const formattedEndDate = - convertSecondsToFormattedDate(row.end_in_seconds) || '-'; + // const rows = processInstances.map((row: any) => { + // const formattedStartDate = + // convertSecondsToFormattedDate(row.start_in_seconds) || '-'; + // const formattedEndDate = + // convertSecondsToFormattedDate(row.end_in_seconds) || '-'; + // + // return ( + // + // + // + // {row.id} + // + // + // + // + // {row.process_group_identifier} + // + // + // + // + // {row.process_model_identifier} + // + // + // {formattedStartDate} + // {formattedEndDate} + // + // {row.status} + // + // + // ); + // }); + // return ( + // + // + // + // + // + // + // + // + // + // + // + // {rows} + //
    Process Instance IdProcess GroupProcess ModelStart TimeEnd TimeStatus
    + // ); + const rows = [ + { + id: 'load-balancer-1', + name: 'Load Balancer 1', + rule: 'Round robin', + Status: 'Starting', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-2', + name: 'Load Balancer 2', + rule: 'DNS delegation', + status: 'Active', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-3', + name: 'Load Balancer 3', + rule: 'Round robin', + status: 'Disabled', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-4', + name: 'Load Balancer 4', + rule: 'Round robin', + status: 'Disabled', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-5', + name: 'Load Balancer 5', + rule: 'Round robin', + status: 'Disabled', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-6', + name: 'Load Balancer 6', + rule: 'Round robin', + status: 'Disabled', + other: 'Test', + example: '22', + }, + { + id: 'load-balancer-7', + name: 'Load Balancer 7', + rule: 'Round robin', + status: 'Disabled', + other: 'Test', + example: '22', + }, + ]; + const headers = ['Name', 'Rule', 'Status', 'Other', 'Example']; - return ( - - - - {row.id} - - - - - {row.process_group_identifier} - - - - - {row.process_model_identifier} - - - {formattedStartDate} - {formattedEndDate} - - {row.status} - - - ); - }); return ( - - - - - - - - - - - - {rows} +
    Process Instance IdProcess GroupProcess ModelStart TimeEnd TimeStatus
    + + + {headers.map((header) => ( + + {header} + + ))} + + + + {rows.map((row) => ( + + {Object.keys(row) + .filter((key) => key !== 'id') + .map((key) => { + return {(row as any)[key]}; + })} + + ))} +
    ); }; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx index f6fb211f..8776df97 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx @@ -283,7 +283,6 @@ export default function ProcessModelEditDiagram() { // we should update this to act like updating scripts // where we pass an event to bpmn-js setScriptModeling(modeling); - setScriptText(script || ''); setScriptType(scriptTypeString); setScriptEventBus(eventBus); @@ -559,28 +558,25 @@ export default function ProcessModelEditDiagram() { if (scriptElement) { scriptName = (scriptElement as any).di.bpmnElement.name; } + return ( - - - Editing Script: {scriptName} - - - - {scriptUnitTestEditorElement()} - - - - + + + {scriptUnitTestEditorElement()} ); }; From a346df80592850d53cf0d1de6b3612e28b3a6281 Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 17:14:48 -0400 Subject: [PATCH 16/22] fix a few tests --- spiffworkflow-frontend/cypress/e2e/tasks.cy.js | 1 + spiffworkflow-frontend/cypress/support/commands.js | 4 +++- spiffworkflow-frontend/src/components/NavigationBar.tsx | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/spiffworkflow-frontend/cypress/e2e/tasks.cy.js b/spiffworkflow-frontend/cypress/e2e/tasks.cy.js index 86298f59..377b05ac 100644 --- a/spiffworkflow-frontend/cypress/e2e/tasks.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/tasks.cy.js @@ -21,6 +21,7 @@ describe('tasks', () => { cy.logout(); }); + // TODO: need to fix the next_task thing to make this pass it('can complete and navigate a form', () => { const groupDisplayName = 'Acceptance Tests Group One'; const modelId = `acceptance-tests-model-2`; diff --git a/spiffworkflow-frontend/cypress/support/commands.js b/spiffworkflow-frontend/cypress/support/commands.js index 3a1a0ac4..affce0d1 100644 --- a/spiffworkflow-frontend/cypress/support/commands.js +++ b/spiffworkflow-frontend/cypress/support/commands.js @@ -31,7 +31,9 @@ Cypress.Commands.add('getBySel', (selector, ...args) => { }); Cypress.Commands.add('navigateToHome', () => { - cy.getBySel('nav-home').click(); + cy.get('button[aria-label="Open menu"]').click(); + cy.getBySel('side-nav-items').contains('Home').click(); + // cy.getBySel('nav-home').click(); }); Cypress.Commands.add('navigateToAdmin', () => { diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index 4dd81f9a..3f7e124d 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -123,10 +123,14 @@ export default function NavigationBar() { logo - + {headerMenuItems()} Date: Fri, 4 Nov 2022 17:21:25 -0400 Subject: [PATCH 17/22] unhardcode --- .../src/routes/ProcessInstanceList.tsx | 183 +++++------------- 1 file changed, 47 insertions(+), 136 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 84ce676f..39794f9f 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -378,144 +378,55 @@ export default function ProcessInstanceList() { }; const buildTable = () => { - // const rows = processInstances.map((row: any) => { - // const formattedStartDate = - // convertSecondsToFormattedDate(row.start_in_seconds) || '-'; - // const formattedEndDate = - // convertSecondsToFormattedDate(row.end_in_seconds) || '-'; - // - // return ( - // - // - // - // {row.id} - // - // - // - // - // {row.process_group_identifier} - // - // - // - // - // {row.process_model_identifier} - // - // - // {formattedStartDate} - // {formattedEndDate} - // - // {row.status} - // - // - // ); - // }); - // return ( - // - // - // - // - // - // - // - // - // - // - // - // {rows} - //
    Process Instance IdProcess GroupProcess ModelStart TimeEnd TimeStatus
    - // ); - const rows = [ - { - id: 'load-balancer-1', - name: 'Load Balancer 1', - rule: 'Round robin', - Status: 'Starting', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-2', - name: 'Load Balancer 2', - rule: 'DNS delegation', - status: 'Active', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-3', - name: 'Load Balancer 3', - rule: 'Round robin', - status: 'Disabled', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-4', - name: 'Load Balancer 4', - rule: 'Round robin', - status: 'Disabled', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-5', - name: 'Load Balancer 5', - rule: 'Round robin', - status: 'Disabled', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-6', - name: 'Load Balancer 6', - rule: 'Round robin', - status: 'Disabled', - other: 'Test', - example: '22', - }, - { - id: 'load-balancer-7', - name: 'Load Balancer 7', - rule: 'Round robin', - status: 'Disabled', - other: 'Test', - example: '22', - }, - ]; - const headers = ['Name', 'Rule', 'Status', 'Other', 'Example']; + const rows = processInstances.map((row: any) => { + const formattedStartDate = + convertSecondsToFormattedDate(row.start_in_seconds) || '-'; + const formattedEndDate = + convertSecondsToFormattedDate(row.end_in_seconds) || '-'; + return ( + + + + {row.id} + + + + + {row.process_group_identifier} + + + + + {row.process_model_identifier} + + + {formattedStartDate} + {formattedEndDate} + + {row.status} + + + ); + }); return ( - - - - {headers.map((header) => ( - - {header} - - ))} - - - - {rows.map((row) => ( - - {Object.keys(row) - .filter((key) => key !== 'id') - .map((key) => { - return {(row as any)[key]}; - })} - - ))} - +
    + + + + + + + + + + + {rows}
    Process Instance IdProcess GroupProcess ModelStart TimeEnd TimeStatus
    ); }; From 4079c75b34344c5331bbd8d8e414418217529777 Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 17:37:32 -0400 Subject: [PATCH 18/22] fix label and comment artificial slowdown --- spiffworkflow-frontend/cypress/e2e/process_groups.cy.js | 2 +- spiffworkflow-frontend/cypress/e2e/process_instances.cy.js | 7 +++++++ spiffworkflow-frontend/src/components/ProcessGroupForm.tsx | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js index 9e974084..629b18c6 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_groups.cy.js @@ -30,7 +30,7 @@ describe('process-groups', () => { newGroupDisplayName ); - cy.contains('Delete Process Group').click(); + cy.contains('Delete').click(); cy.contains('Are you sure'); cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.url().should('include', `process-groups`); diff --git a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js index a2fcb266..62fe3cbc 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js @@ -43,6 +43,13 @@ const updateBpmnPythonScriptWithMonaco = ( cy.contains('Launch Editor').click(); // sometimes, Loading... appears for more than 4 seconds. not sure why. cy.contains('Loading...').should('not.exist'); + + // the delay 30 is because, at some point, monaco started automatically + // adding a second double quote when we type a double quote. when it does + // that, there is a race condition where it sometimes gets in more text + // before the second double quote appears because the robot is typing faster + // than a human being could, so we artificially slow it down to make it more + // human. cy.get('.monaco-editor textarea:first') .click() .focused() // change subject to currently focused element diff --git a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx index 99db3434..128a13c0 100644 --- a/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx +++ b/spiffworkflow-frontend/src/components/ProcessGroupForm.tsx @@ -162,7 +162,7 @@ export default function ProcessGroupForm({ ); From 703e967ea03aeca321f9ef05527a58574f2b5b3e Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 18:02:09 -0400 Subject: [PATCH 19/22] lint --- .../cypress/e2e/process_instances.cy.js | 2 +- .../src/components/NavigationBar.tsx | 3 --- .../src/routes/ProcessInstanceList.tsx | 10 +++++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js index 62fe3cbc..b7bbf9d4 100644 --- a/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/process_instances.cy.js @@ -161,7 +161,7 @@ describe('process-instances', () => { cy.basicPaginationTest(); }); - it.only('can filter', () => { + it('can filter', () => { cy.getBySel('process-instance-list-link').click(); cy.assertAtLeastOneItemInPaginatedResults(); diff --git a/spiffworkflow-frontend/src/components/NavigationBar.tsx b/spiffworkflow-frontend/src/components/NavigationBar.tsx index 3f7e124d..30fcb70c 100644 --- a/spiffworkflow-frontend/src/components/NavigationBar.tsx +++ b/spiffworkflow-frontend/src/components/NavigationBar.tsx @@ -3,10 +3,7 @@ import { HeaderContainer, HeaderMenuButton, SkipToContent, - Theme, - HeaderMenu, SideNav, - SideNavItem, SideNavItems, HeaderSideNavItems, HeaderName, diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx index 39794f9f..42ecf674 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceList.tsx @@ -17,11 +17,11 @@ import { Grid, Column, MultiSelect, - TableHeader, - TableHead, - TableRow, - TableBody, - TableCell, + // TableHeader, + // TableHead, + // TableRow, + // TableBody, + // TableCell, // @ts-ignore } from '@carbon/react'; import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; From c75220b6f6286b2fd255fb91ab17c8b0ed540073 Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 18:18:28 -0400 Subject: [PATCH 20/22] fix last modal --- .../src/routes/ProcessInstanceShow.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 0d97e608..0c0342b2 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -339,15 +339,15 @@ export default function ProcessInstanceShow() { const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay }; if (taskToDisplay) { return ( - - - - - {taskToUse.name} ({taskToUse.type}): {taskToUse.state} - {taskDataButtons(taskToUse)} - - - + + + {taskToUse.name} ({taskToUse.type}): {taskToUse.state} + {taskDataButtons(taskToUse)} + {taskDataContainer()} ); From d65b6bdfd3193190cb5d5a1ebe9cd333706e28b2 Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 18:27:10 -0400 Subject: [PATCH 21/22] Stack direction to orientation --- spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx | 2 +- spiffworkflow-frontend/src/routes/ProcessModelEditDiagram.tsx | 4 ++-- spiffworkflow-frontend/src/routes/ProcessModelShow.tsx | 2 +- spiffworkflow-frontend/src/routes/SecretNew.tsx | 2 +- spiffworkflow-frontend/src/routes/SecretShow.tsx | 4 ++-- spiffworkflow-frontend/src/routes/TaskShow.tsx | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx b/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx index 02625a8f..25e58044 100644 --- a/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessGroupShow.tsx @@ -82,7 +82,7 @@ export default function ProcessGroupShow() { ]} />
      - + diff --git a/spiffworkflow-frontend/src/routes/SecretNew.tsx b/spiffworkflow-frontend/src/routes/SecretNew.tsx index e1f34e89..016fec2e 100644 --- a/spiffworkflow-frontend/src/routes/SecretNew.tsx +++ b/spiffworkflow-frontend/src/routes/SecretNew.tsx @@ -68,7 +68,7 @@ export default function SecretNew() { }} /> - + diff --git a/spiffworkflow-frontend/src/routes/SecretShow.tsx b/spiffworkflow-frontend/src/routes/SecretShow.tsx index 2ee75e19..9882247b 100644 --- a/spiffworkflow-frontend/src/routes/SecretShow.tsx +++ b/spiffworkflow-frontend/src/routes/SecretShow.tsx @@ -65,8 +65,8 @@ export default function SecretShow() { if (secret) { return ( <> - -

      Secret Key: {secret.key}

      +

      Secret Key: {secret.key}

      + + {userTasksElement} From 30f0ce92a3d7fd0d32cd360127f348861581244b Mon Sep 17 00:00:00 2001 From: burnettk Date: Fri, 4 Nov 2022 18:30:45 -0400 Subject: [PATCH 22/22] remove garbage css rule --- spiffworkflow-frontend/src/index.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index 67494b82..988fae27 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -30,11 +30,6 @@ span.bjs-crumb { margin-bottom: 2em; } -// forces the navigation items to be displayed at all viewport sizes -.cds--header__nav { - display: block; -} - .active-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) { fill: yellow !important; opacity: .6;