diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..0e223626f --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +/src/themes/carbon diff --git a/.eslintrc.js b/.eslintrc.js index ebec84ef7..b6829ff48 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -36,6 +36,7 @@ module.exports = { ], 'react/react-in-jsx-scope': 'off', 'react/require-default-props': 'off', + 'import/prefer-default-export': 'off', 'no-unused-vars': [ 'error', { diff --git a/bin/run_cypress_tests_locally b/bin/run_cypress_tests_locally index 7416dac93..cf4db6387 100755 --- a/bin/run_cypress_tests_locally +++ b/bin/run_cypress_tests_locally @@ -7,6 +7,9 @@ function error_handler() { trap 'error_handler ${LINENO} $?' ERR set -o errtrace -o errexit -o nounset -o pipefail +# see also: npx cypress run --env grep="can filter",grepFilterSpecs=true +# https://github.com/cypress-io/cypress/tree/develop/npm/grep#pre-filter-specs-grepfilterspecs + command="${1:-}" if [[ -z "$command" ]]; then command=open diff --git a/cypress.config.js b/cypress.config.js index 1c8c1c6ee..580bf1ffd 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -6,8 +6,9 @@ module.exports = defineConfig({ chromeWebSecurity: false, e2e: { baseUrl: 'http://localhost:7001', - setupNodeEvents(_on, _config) { - // implement node event listeners here + setupNodeEvents(_on, config) { + require('@cypress/grep/src/plugin')(config); + return config; }, }, diff --git a/cypress/e2e/process_instances.cy.js b/cypress/e2e/process_instances.cy.js index 6999acc2b..09cad2987 100644 --- a/cypress/e2e/process_instances.cy.js +++ b/cypress/e2e/process_instances.cy.js @@ -169,14 +169,13 @@ describe('process-instances', () => { cy.getBySel('process-instance-list-link').click(); cy.assertAtLeastOneItemInPaginatedResults(); + const statusSelect = '#process-instance-status-select'; PROCESS_STATUSES.forEach((processStatus) => { if (!['all', 'waiting'].includes(processStatus)) { - cy.get('#process-instance-status-select').click(); - cy.get('#process-instance-status-select') - .contains(processStatus) - .click(); + cy.get(statusSelect).click(); + cy.get(statusSelect).contains(processStatus).click(); // close the dropdown again - cy.get('#process-instance-status-select').click(); + cy.get(statusSelect).click(); cy.getBySel('filter-button').click(); cy.assertAtLeastOneItemInPaginatedResults(); cy.getBySel(`process-instance-status-${processStatus}`).contains( diff --git a/cypress/e2e/process_models.cy.js b/cypress/e2e/process_models.cy.js index cc4ef606f..705f6011c 100644 --- a/cypress/e2e/process_models.cy.js +++ b/cypress/e2e/process_models.cy.js @@ -144,10 +144,11 @@ describe('process-models', () => { cy.getBySel('process-instance-list-link').click(); cy.getBySel('process-instance-show-link').click(); - cy.contains('Delete').click(); + cy.getBySel('process-instance-delete').click(); cy.contains('Are you sure'); cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); - cy.contains(`Process Instances for: ${groupId}/${modelId}`); + + // in breadcrumb cy.contains(modelId).click(); cy.contains('Edit process model').click(); diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index 5df9c0186..47c62f9c0 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -16,5 +16,9 @@ // Import commands.js using ES2015 syntax: import './commands'; +import registerCypressGrep from '@cypress/grep'; + +registerCypressGrep(); + // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/package-lock.json b/package-lock.json index 258b3e586..f31017c8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,16 @@ "@carbon/icons-react": "^11.10.0", "@carbon/react": "^1.16.0", "@carbon/styles": "^1.16.0", + "@casl/ability": "^6.3.2", + "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", - "@rjsf/core": "^4.2.0", + "@mui/material": "^5.10.14", + "@react-icons/all-files": "^4.1.0", + "@rjsf/core": "*", + "@rjsf/mui": "^5.0.0-beta.13", + "@rjsf/utils": "^5.0.0-beta.13", + "@rjsf/validator-ajv6": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -58,6 +65,7 @@ "web-vitals": "^3.0.2" }, "devDependencies": { + "@cypress/grep": "^3.1.0", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.6", "cypress": "^10.8.0", @@ -1956,11 +1964,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.10" }, "engines": { "node": ">=6.9.0" @@ -2276,6 +2284,26 @@ "@carbon/layout": "^11.7.0" } }, + "node_modules/@casl/ability": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.3.2.tgz", + "integrity": "sha512-ygOlg3WDu39t1ZOVdDfRpPXEiCn7F/a7uLBJIuAE6KksdBogzPszFRAuGULmo4h37fXIyouYUilVIryh0ddTRA==", + "dependencies": { + "@ucast/mongo2js": "^1.3.0" + }, + "funding": { + "url": "https://github.com/stalniy/casl/blob/master/BACKERS.md" + } + }, + "node_modules/@casl/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@casl/react/-/react-3.1.0.tgz", + "integrity": "sha512-p4Xmex1Slxz/G0cBtZik+xyOkeOynBUe0UrMFTai6aYkYOb4NyUy3w+9rtnedjcuKijiow2HKJQjnSurLxdc/g==", + "peerDependencies": { + "@casl/ability": "^3.0.0 || ^4.0.0 || ^5.1.0 || ^6.0.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@codemirror/autocomplete": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.0.tgz", @@ -2648,6 +2676,20 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@cypress/grep": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@cypress/grep/-/grep-3.1.0.tgz", + "integrity": "sha512-ZSAwUyEw7e7Lu4KhjQLZrJDnzA04awqikj7ZcPHr+oW4wDpiVscn7VEZ/P/WRC1fBydUoZ5e24aFEPxXmKCreg==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "find-test-names": "^1.19.0", + "globby": "^11.0.4" + }, + "peerDependencies": { + "cypress": ">=10" + } + }, "node_modules/@cypress/request": { "version": "2.88.10", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz", @@ -2711,22 +2753,22 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -2757,15 +2799,15 @@ } }, "node_modules/@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "dependencies": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.3" } }, "node_modules/@emotion/cache/node_modules/@emotion/memoize": { @@ -2818,9 +2860,9 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "dependencies": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -2835,15 +2877,66 @@ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/sheet": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "node_modules/@emotion/styled": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true }, "node_modules/@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peer": true, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/@emotion/utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", @@ -4351,6 +4444,276 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@mui/base": { + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/base/node_modules/@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@mui/base/node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "node_modules/@mui/base/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", + "dependencies": { + "@babel/runtime": "^7.20.1", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4460,6 +4823,14 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@restart/hooks": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", @@ -4492,26 +4863,90 @@ } }, "node_modules/@rjsf/core": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.3.tgz", - "integrity": "sha512-dRXhd1Tac/9OcG0VDrYDF2boNTyKINEEITEtJ4L1Yce2iMVk66U52BhWKIFp/WXDM27vwnOfwQo4NwGiqeQeHw==", + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.0.0-beta.13.tgz", + "integrity": "sha512-uQ3A9aJhMJsz9ct5tV3ogZkSFEkKUxrM9SJ9Hc8ijxmuaW7Jv8tNv5jiWZZsLvNXlIONX83s6JqkiOJf6IOAvg==", "dependencies": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.7.0", - "core-js-pure": "^3.6.5", - "json-schema-merge-allof": "^0.6.0", - "jsonpointer": "^5.0.0", "lodash": "^4.17.15", "lodash-es": "^4.17.15", - "nanoid": "^3.1.23", - "prop-types": "^15.7.2", - "react-is": "16.9.0" + "nanoid": "^3.3.4", + "prop-types": "^15.7.2" }, "engines": { - "node": ">=12" + "node": ">=14" }, "peerDependencies": { - "react": ">=16 || >=17" + "@rjsf/utils": "^5.0.0-beta.1", + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/mui": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/mui/-/mui-5.0.0-beta.13.tgz", + "integrity": "sha512-hwCtADpjNssq/CsT3Wj1FDVJfdCN3gptKedGjbusLUEwQqXoVzkzl25e/IRfN8y/JxYu4lMXDU89bN9nJSKWLA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@emotion/react": "^11.7.0", + "@emotion/styled": "^11.6.0", + "@mui/icons-material": "^5.2.0", + "@mui/material": "^5.2.2", + "@rjsf/core": "^5.0.0-beta.1", + "@rjsf/utils": "^5.0.0-beta.1", + "react": ">=17" + } + }, + "node_modules/@rjsf/utils": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.0.0-beta.13.tgz", + "integrity": "sha512-hWWWFD2ifjSOhqWueML4OHrZe2HW5pE2nfKGhCObFbwtggHoQlj64xDBsJ1qfUG8DGvCHztJQ/sKIaOvXnpt7w==", + "dependencies": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.14.0 || >=17" + } + }, + "node_modules/@rjsf/utils/node_modules/json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "dependencies": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@rjsf/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@rjsf/validator-ajv6": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv6/-/validator-ajv6-5.0.0-beta.13.tgz", + "integrity": "sha512-X9N3/HJYV23MjUN/VJHIdBhUdBuMTUsh4HAZm50eUvUAhWK95wIqjjhAs24rzeLajrjFeH7kFr89zAqDgIFhVQ==", + "dependencies": { + "ajv": "^6.7.0", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@rjsf/utils": "^5.0.0-beta.1" } }, "node_modules/@rollup/plugin-babel": { @@ -4593,6 +5028,15 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==" }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -4827,6 +5271,18 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@tanstack/react-table": { "version": "8.5.11", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.5.11.tgz", @@ -5448,6 +5904,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-redux": { "version": "7.1.24", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", @@ -5889,6 +6353,37 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ucast/core": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.1.tgz", + "integrity": "sha512-sXKbvQiagjFh2JCpaHUa64P4UdJbOxYeC5xiZFn8y6iYdb0WkismduE+RmiJrIjw/eLDYmIEXiQeIYYowmkcAw==" + }, + "node_modules/@ucast/js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.0.2.tgz", + "integrity": "sha512-zxNkdIPVvqJjHI7D/iK8Aai1+59yqU+N7bpHFodVmiTN7ukeNiGGpNmmSjQgsUw7eNcEBnPrZHNzp5UBxwmaPw==", + "dependencies": { + "@ucast/core": "^1.0.0" + } + }, + "node_modules/@ucast/mongo": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@ucast/mongo/-/mongo-2.4.2.tgz", + "integrity": "sha512-/zH1TdBJlYGKKD+Wh0oyD+aBvDSWrwHcD8b4tUL9UgHLhzHtkEnMVFuxbw3SRIRsAa01wmy06+LWt+WoZdj1Bw==", + "dependencies": { + "@ucast/core": "^1.4.1" + } + }, + "node_modules/@ucast/mongo2js": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.3.3.tgz", + "integrity": "sha512-sBPtMUYg+hRnYeVYKL+ATm8FaRPdlU9PijMhGYKgsPGjV9J4Ks41ytIjGayvKUnBOEhiCaKUUnY4qPeifdqATw==", + "dependencies": { + "@ucast/core": "^1.6.1", + "@ucast/js": "^3.0.0", + "@ucast/mongo": "^2.4.0" + } + }, "node_modules/@uiw/copy-to-clipboard": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.12.tgz", @@ -7485,7 +7980,7 @@ }, "node_modules/bpmn-js-spiffworkflow": { "version": "0.0.8", - "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#09fa713bb0bb1b9d4f97684afc46bc3711e11770", + "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#e92f48da7cb4416310af71bb1699caaca87324cd", "license": "MIT", "dependencies": { "inherits": "^2.0.4", @@ -7794,6 +8289,42 @@ "node": ">=0.10.0" } }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/cachedir": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", @@ -8395,6 +8926,26 @@ "node": ">=6" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -8656,6 +9207,23 @@ "typedarray": "^0.0.6" } }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", @@ -9272,9 +9840,9 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/cyclist": { "version": "1.0.1", @@ -9572,6 +10140,18 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -9650,6 +10230,12 @@ "node": ">=10.17.0" } }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -10148,6 +10734,27 @@ "tslib": "^2.0.3" } }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/dotenv": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", @@ -10185,6 +10792,12 @@ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, "node_modules/duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -10444,6 +11057,15 @@ "node": ">=6" } }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -11877,6 +12499,33 @@ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, + "node_modules/find-test-names": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.21.0.tgz", + "integrity": "sha512-yYcl4X2U1maVXCktO24e9K7qs1uDqDTQWe51gso6JgK2iinRbNyHKrb43/LQTit8/SteA2qODqPkapgeuSdzZw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.16.5", + "acorn-walk": "^8.2.0", + "debug": "^4.3.3", + "globby": "^11.0.4", + "simple-bin-help": "^1.7.7" + }, + "bin": { + "find-test-names": "bin/find-test-names.js", + "print-tests": "bin/print-tests.js", + "update-test-count": "bin/update-test-count.js" + } + }, + "node_modules/find-test-names/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -12496,6 +13145,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -12659,6 +13342,15 @@ "node": ">=0.10.0" } }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -13127,6 +13819,12 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -13351,6 +14049,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -13745,6 +14452,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -13950,6 +14669,12 @@ "node": ">=8" } }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -18356,6 +19081,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -18379,16 +19110,6 @@ "lodash": "^4.17.4" } }, - "node_modules/json-schema-merge-allof": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz", - "integrity": "sha512-LEw4VMQVRceOPLuGRWcxW5orTTiR9ZAtqTAe4rQUjNADTeR81bezBVFa0MqIwp0YmHIM1KkhSjZM7o+IQhaPbQ==", - "dependencies": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -18642,6 +19363,15 @@ "js-sha256": "^0.9.0" } }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -18693,6 +19423,18 @@ "language-subtag-registry": "~0.3.2" } }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -18781,9 +19523,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -19070,6 +19812,15 @@ "tslib": "^2.0.3" } }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -20024,6 +20775,15 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/min-dash": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/min-dash/-/min-dash-3.8.1.tgz", @@ -20721,6 +21481,15 @@ "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", "dev": true }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -20784,6 +21553,45 @@ "node": ">=6" } }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/registry-auth-token": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", + "dev": true, + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/package-json/node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -22434,6 +23242,15 @@ "node": ">= 0.8.0" } }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", @@ -22704,6 +23521,18 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -23066,9 +23895,9 @@ } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "engines": { "node": ">= 12.13.0" } @@ -24163,25 +24992,14 @@ } }, "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "dependencies": { - "minimatch": "3.0.4" + "minimatch": "^3.0.5" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "node": ">=6.0.0" } }, "node_modules/redent": { @@ -24236,9 +25054,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" }, "node_modules/regenerator-transform": { "version": "0.15.0", @@ -24820,6 +25638,15 @@ "node": ">=10" } }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -25156,6 +25983,18 @@ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -25214,9 +26053,9 @@ } }, "node_modules/serve": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/serve/-/serve-14.0.1.tgz", - "integrity": "sha512-tNGwxl27FwA8TbmMQqN0jTaSx8/trL532qZsJHX1VdiEIjjtMJHCs7AFS6OvtC7cTHOvmjXqt5yczejU6CV2Xg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.1.1.tgz", + "integrity": "sha512-7RhRDEirZ7Qyee4QWhBHO9qRtjIGsIPGecDDPzNzlOsjDiZWcq36GS8FioVJAuJPVJBBDTsGp33WWOO4B9A82g==", "dependencies": { "@zeit/schemas": "2.21.0", "ajv": "8.11.0", @@ -25227,7 +26066,7 @@ "clipboardy": "3.0.0", "compression": "1.7.4", "is-port-reachable": "4.0.0", - "serve-handler": "6.1.3", + "serve-handler": "6.1.5", "update-check": "1.5.4" }, "bin": { @@ -25238,15 +26077,15 @@ } }, "node_modules/serve-handler": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", - "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", + "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "fast-url-parser": "1.1.3", "mime-types": "2.1.18", - "minimatch": "3.0.4", + "minimatch": "3.1.2", "path-is-inside": "1.0.2", "path-to-regexp": "2.2.1", "range-parser": "1.2.0" @@ -25271,17 +26110,6 @@ "node": ">= 0.6" } }, - "node_modules/serve-handler/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -25530,6 +26358,26 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-bin-help": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.7.7.tgz", + "integrity": "sha512-e36uqSXbTL0yNUc7RgjMFAEMDgV5jbPd18LrCeswZJ7aUtEq0qPf4rroQyW3Tfl1E7rcsW1amZoV3OCGOne1Tg==", + "dev": true, + "dependencies": { + "debug": "3.2.7", + "update-notifier": "5.1.0", + "word-wrap": "1.2.3" + } + }, + "node_modules/simple-bin-help/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -26331,9 +27179,9 @@ } }, "node_modules/stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -27008,6 +27856,15 @@ "node": ">=0.10.0" } }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -28540,6 +29397,213 @@ "registry-url": "3.1.0" } }, + "node_modules/update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/update-notifier/node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/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==", + "dev": true + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/update-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -28580,6 +29644,18 @@ "requires-port": "^1.0.0" } }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -29593,9 +30669,9 @@ } }, "node_modules/webpack/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -30190,6 +31266,15 @@ } } }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -31556,11 +32641,11 @@ } }, "@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.10" } }, "@babel/runtime-corejs2": { @@ -31852,6 +32937,20 @@ "@carbon/layout": "^11.7.0" } }, + "@casl/ability": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.3.2.tgz", + "integrity": "sha512-ygOlg3WDu39t1ZOVdDfRpPXEiCn7F/a7uLBJIuAE6KksdBogzPszFRAuGULmo4h37fXIyouYUilVIryh0ddTRA==", + "requires": { + "@ucast/mongo2js": "^1.3.0" + } + }, + "@casl/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@casl/react/-/react-3.1.0.tgz", + "integrity": "sha512-p4Xmex1Slxz/G0cBtZik+xyOkeOynBUe0UrMFTai6aYkYOb4NyUy3w+9rtnedjcuKijiow2HKJQjnSurLxdc/g==", + "requires": {} + }, "@codemirror/autocomplete": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.0.tgz", @@ -32061,6 +33160,17 @@ "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", "requires": {} }, + "@cypress/grep": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@cypress/grep/-/grep-3.1.0.tgz", + "integrity": "sha512-ZSAwUyEw7e7Lu4KhjQLZrJDnzA04awqikj7ZcPHr+oW4wDpiVscn7VEZ/P/WRC1fBydUoZ5e24aFEPxXmKCreg==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "find-test-names": "^1.19.0", + "globby": "^11.0.4" + } + }, "@cypress/request": { "version": "2.88.10", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz", @@ -32122,22 +33232,22 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "dependencies": { "@emotion/memoize": { @@ -32158,15 +33268,15 @@ } }, "@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "requires": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "dependencies": { "@emotion/memoize": { @@ -32209,9 +33319,9 @@ } }, "@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "requires": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -32228,15 +33338,53 @@ } }, "@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + }, + "@emotion/styled": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "peer": true, + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==", + "peer": true + } + } }, "@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peer": true, + "requires": {} + }, "@emotion/utils": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", @@ -33393,6 +34541,142 @@ "prop-types": "^15.7.2" } }, + "@mui/base": { + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", + "requires": { + "@babel/runtime": "^7.20.1", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==" + }, + "@mui/icons-material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", + "peer": true, + "requires": { + "@babel/runtime": "^7.20.1" + } + }, + "@mui/material": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", + "requires": { + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", + "requires": { + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", + "requires": {} + }, + "@mui/utils": { + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", + "requires": { + "@babel/runtime": "^7.20.1", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -33452,6 +34736,12 @@ "@babel/runtime": "^7.6.2" } }, + "@react-icons/all-files": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", + "requires": {} + }, "@restart/hooks": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz", @@ -33477,20 +34767,59 @@ } }, "@rjsf/core": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.3.tgz", - "integrity": "sha512-dRXhd1Tac/9OcG0VDrYDF2boNTyKINEEITEtJ4L1Yce2iMVk66U52BhWKIFp/WXDM27vwnOfwQo4NwGiqeQeHw==", + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-5.0.0-beta.13.tgz", + "integrity": "sha512-uQ3A9aJhMJsz9ct5tV3ogZkSFEkKUxrM9SJ9Hc8ijxmuaW7Jv8tNv5jiWZZsLvNXlIONX83s6JqkiOJf6IOAvg==", "requires": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.7.0", - "core-js-pure": "^3.6.5", - "json-schema-merge-allof": "^0.6.0", - "jsonpointer": "^5.0.0", "lodash": "^4.17.15", "lodash-es": "^4.17.15", - "nanoid": "^3.1.23", - "prop-types": "^15.7.2", - "react-is": "16.9.0" + "nanoid": "^3.3.4", + "prop-types": "^15.7.2" + } + }, + "@rjsf/mui": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/mui/-/mui-5.0.0-beta.13.tgz", + "integrity": "sha512-hwCtADpjNssq/CsT3Wj1FDVJfdCN3gptKedGjbusLUEwQqXoVzkzl25e/IRfN8y/JxYu4lMXDU89bN9nJSKWLA==", + "requires": {} + }, + "@rjsf/utils": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/utils/-/utils-5.0.0-beta.13.tgz", + "integrity": "sha512-hWWWFD2ifjSOhqWueML4OHrZe2HW5pE2nfKGhCObFbwtggHoQlj64xDBsJ1qfUG8DGvCHztJQ/sKIaOvXnpt7w==", + "requires": { + "json-schema-merge-allof": "^0.8.1", + "jsonpointer": "^5.0.1", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "react-is": "^18.2.0" + }, + "dependencies": { + "json-schema-merge-allof": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz", + "integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==", + "requires": { + "compute-lcm": "^1.1.2", + "json-schema-compare": "^0.2.2", + "lodash": "^4.17.20" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@rjsf/validator-ajv6": { + "version": "5.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@rjsf/validator-ajv6/-/validator-ajv6-5.0.0-beta.13.tgz", + "integrity": "sha512-X9N3/HJYV23MjUN/VJHIdBhUdBuMTUsh4HAZm50eUvUAhWK95wIqjjhAs24rzeLajrjFeH7kFr89zAqDgIFhVQ==", + "requires": { + "ajv": "^6.7.0", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15" } }, "@rollup/plugin-babel": { @@ -33544,6 +34873,12 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==" }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -33680,6 +35015,15 @@ "loader-utils": "^2.0.0" } }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, "@tanstack/react-table": { "version": "8.5.11", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.5.11.tgz", @@ -34207,6 +35551,14 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { "version": "7.1.24", "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", @@ -34534,6 +35886,37 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@ucast/core": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.1.tgz", + "integrity": "sha512-sXKbvQiagjFh2JCpaHUa64P4UdJbOxYeC5xiZFn8y6iYdb0WkismduE+RmiJrIjw/eLDYmIEXiQeIYYowmkcAw==" + }, + "@ucast/js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@ucast/js/-/js-3.0.2.tgz", + "integrity": "sha512-zxNkdIPVvqJjHI7D/iK8Aai1+59yqU+N7bpHFodVmiTN7ukeNiGGpNmmSjQgsUw7eNcEBnPrZHNzp5UBxwmaPw==", + "requires": { + "@ucast/core": "^1.0.0" + } + }, + "@ucast/mongo": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@ucast/mongo/-/mongo-2.4.2.tgz", + "integrity": "sha512-/zH1TdBJlYGKKD+Wh0oyD+aBvDSWrwHcD8b4tUL9UgHLhzHtkEnMVFuxbw3SRIRsAa01wmy06+LWt+WoZdj1Bw==", + "requires": { + "@ucast/core": "^1.4.1" + } + }, + "@ucast/mongo2js": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ucast/mongo2js/-/mongo2js-1.3.3.tgz", + "integrity": "sha512-sBPtMUYg+hRnYeVYKL+ATm8FaRPdlU9PijMhGYKgsPGjV9J4Ks41ytIjGayvKUnBOEhiCaKUUnY4qPeifdqATw==", + "requires": { + "@ucast/core": "^1.6.1", + "@ucast/js": "^3.0.0", + "@ucast/mongo": "^2.4.0" + } + }, "@uiw/copy-to-clipboard": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.12.tgz", @@ -35755,7 +37138,7 @@ } }, "bpmn-js-spiffworkflow": { - "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#09fa713bb0bb1b9d4f97684afc46bc3711e11770", + "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#e92f48da7cb4416310af71bb1699caaca87324cd", "from": "bpmn-js-spiffworkflow@sartography/bpmn-js-spiffworkflow#main", "requires": { "inherits": "^2.0.4", @@ -35995,6 +37378,35 @@ "unset-value": "^1.0.0" } }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + } + } + }, "cachedir": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", @@ -36427,6 +37839,20 @@ "shallow-clone": "^3.0.0" } }, + "clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -36651,6 +38077,20 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, "confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", @@ -37136,9 +38576,9 @@ } }, "csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "cyclist": { "version": "1.0.1", @@ -37365,6 +38805,15 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -37421,6 +38870,12 @@ } } }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -37836,6 +39291,23 @@ "tslib": "^2.0.3" } }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + }, + "dependencies": { + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + } + } + }, "dotenv": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", @@ -37869,6 +39341,12 @@ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, + "duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -38084,6 +39562,12 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -39151,6 +40635,27 @@ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, + "find-test-names": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.21.0.tgz", + "integrity": "sha512-yYcl4X2U1maVXCktO24e9K7qs1uDqDTQWe51gso6JgK2iinRbNyHKrb43/LQTit8/SteA2qODqPkapgeuSdzZw==", + "dev": true, + "requires": { + "@babel/parser": "^7.16.5", + "acorn-walk": "^8.2.0", + "debug": "^4.3.3", + "globby": "^11.0.4", + "simple-bin-help": "^1.7.7" + }, + "dependencies": { + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -39586,6 +41091,36 @@ "slash": "^3.0.0" } }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -39705,6 +41240,12 @@ } } }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -40058,6 +41599,12 @@ } } }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -40215,6 +41762,12 @@ "resolve-from": "^4.0.0" } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "dev": true + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -40493,6 +42046,12 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -40620,6 +42179,12 @@ "is-docker": "^2.0.0" } }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -43953,6 +45518,12 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -43976,16 +45547,6 @@ "lodash": "^4.17.4" } }, - "json-schema-merge-allof": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz", - "integrity": "sha512-LEw4VMQVRceOPLuGRWcxW5orTTiR9ZAtqTAe4rQUjNADTeR81bezBVFa0MqIwp0YmHIM1KkhSjZM7o+IQhaPbQ==", - "requires": { - "compute-lcm": "^1.1.0", - "json-schema-compare": "^0.2.2", - "lodash": "^4.17.4" - } - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -44218,6 +45779,15 @@ "js-sha256": "^0.9.0" } }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -44260,6 +45830,15 @@ "language-subtag-registry": "~0.3.2" } }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, "lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -44322,9 +45901,9 @@ "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -44548,6 +46127,12 @@ "tslib": "^2.0.3" } }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -45162,6 +46747,12 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, "min-dash": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/min-dash/-/min-dash-3.8.1.tgz", @@ -45714,6 +47305,12 @@ "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", "dev": true }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -45753,6 +47350,38 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "registry-auth-token": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", + "dev": true, + "requires": { + "rc": "1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + } + } + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -46545,7 +48174,7 @@ "@csstools/postcss-text-decoration-shorthand": "^1.0.0", "@csstools/postcss-trigonometric-functions": "^1.0.2", "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "10.4.8", + "autoprefixer": "10.4.5", "browserslist": "^4.21.3", "css-blank-pseudo": "^3.0.3", "css-has-pseudo": "^3.0.4", @@ -46583,7 +48212,8 @@ }, "dependencies": { "autoprefixer": { - "version": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.5.tgz", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.5.tgz", "integrity": "sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw==", "requires": { "browserslist": "^4.20.2", @@ -46768,6 +48398,12 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true + }, "prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", @@ -46990,6 +48626,15 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -47253,9 +48898,9 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" }, "supports-color": { "version": "7.2.0", @@ -48030,21 +49675,11 @@ } }, "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "requires": { - "minimatch": "3.0.4" - }, - "dependencies": { - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - } + "minimatch": "^3.0.5" } }, "redent": { @@ -48089,9 +49724,9 @@ } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" }, "regenerator-transform": { "version": "0.15.0", @@ -48528,6 +50163,15 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==" }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -48784,6 +50428,15 @@ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -48840,9 +50493,9 @@ } }, "serve": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/serve/-/serve-14.0.1.tgz", - "integrity": "sha512-tNGwxl27FwA8TbmMQqN0jTaSx8/trL532qZsJHX1VdiEIjjtMJHCs7AFS6OvtC7cTHOvmjXqt5yczejU6CV2Xg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.1.1.tgz", + "integrity": "sha512-7RhRDEirZ7Qyee4QWhBHO9qRtjIGsIPGecDDPzNzlOsjDiZWcq36GS8FioVJAuJPVJBBDTsGp33WWOO4B9A82g==", "requires": { "@zeit/schemas": "2.21.0", "ajv": "8.11.0", @@ -48853,7 +50506,7 @@ "clipboardy": "3.0.0", "compression": "1.7.4", "is-port-reachable": "4.0.0", - "serve-handler": "6.1.3", + "serve-handler": "6.1.5", "update-check": "1.5.4" }, "dependencies": { @@ -48881,15 +50534,15 @@ } }, "serve-handler": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", - "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", + "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", "requires": { "bytes": "3.0.0", "content-disposition": "0.5.2", "fast-url-parser": "1.1.3", "mime-types": "2.1.18", - "minimatch": "3.0.4", + "minimatch": "3.1.2", "path-is-inside": "1.0.2", "path-to-regexp": "2.2.1", "range-parser": "1.2.0" @@ -48907,14 +50560,6 @@ "requires": { "mime-db": "~1.33.0" } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } } } }, @@ -49102,6 +50747,28 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "simple-bin-help": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.7.7.tgz", + "integrity": "sha512-e36uqSXbTL0yNUc7RgjMFAEMDgV5jbPd18LrCeswZJ7aUtEq0qPf4rroQyW3Tfl1E7rcsW1amZoV3OCGOne1Tg==", + "dev": true, + "requires": { + "debug": "3.2.7", + "update-notifier": "5.1.0", + "word-wrap": "1.2.3" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -49745,9 +51412,9 @@ } }, "stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "supports-color": { "version": "5.5.0", @@ -50268,6 +51935,12 @@ } } }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -51425,6 +53098,155 @@ "registry-url": "3.1.0" } }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -51470,6 +53292,15 @@ "requires-port": "^1.0.0" } }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -52083,9 +53914,9 @@ } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -52739,6 +54570,12 @@ "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", "requires": {} }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, "xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", diff --git a/package.json b/package.json index 92ba23aa9..b896bdcec 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,16 @@ "@carbon/icons-react": "^11.10.0", "@carbon/react": "^1.16.0", "@carbon/styles": "^1.16.0", + "@casl/ability": "^6.3.2", + "@casl/react": "^3.1.0", "@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0", "@monaco-editor/react": "^4.4.5", - "@rjsf/core": "^4.2.0", + "@mui/material": "^5.10.14", + "@react-icons/all-files": "^4.1.0", + "@rjsf/core": "*", + "@rjsf/mui": "^5.0.0-beta.13", + "@rjsf/utils": "^5.0.0-beta.13", + "@rjsf/validator-ajv6": "^5.0.0-beta.13", "@tanstack/react-table": "^8.2.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.3.0", @@ -71,9 +78,9 @@ "test": "react-scripts test --coverage", "t": "npm test -- --watchAll=false", "eject": "craco eject", - "format": "prettier --write src/**/*.js{,x}", - "lint": "./node_modules/.bin/eslint src *.js", - "lint:fix": "./node_modules/.bin/eslint --fix src *.js" + "format": "prettier --write src/**/*.[tj]s{,x}", + "lint": "./node_modules/.bin/eslint src", + "lint:fix": "./node_modules/.bin/eslint --fix src" }, "eslintConfig": { "extends": [ @@ -94,6 +101,7 @@ ] }, "devDependencies": { + "@cypress/grep": "^3.1.0", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.6", "cypress": "^10.8.0", diff --git a/src/App.tsx b/src/App.tsx index 2561c2a8e..deb38410d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,15 +3,17 @@ import { useMemo, useState } from 'react'; import { Content } from '@carbon/react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import { defineAbility } from '@casl/ability'; import ErrorContext from './contexts/ErrorContext'; import NavigationBar from './components/NavigationBar'; -import HomePage from './routes/HomePage'; -import TaskShow from './routes/TaskShow'; +import HomePageRoutes from './routes/HomePageRoutes'; import ErrorBoundary from './components/ErrorBoundary'; import AdminRoutes from './routes/AdminRoutes'; import { ErrorForDisplay } from './interfaces'; +import { AbilityContext } from './contexts/Can'; + export default function App() { const [errorMessage, setErrorMessage] = useState( null @@ -22,6 +24,8 @@ export default function App() { [errorMessage] ); + const ability = defineAbility(() => {}); + let errorTag = null; if (errorMessage) { let sentryLinkTag = null; @@ -47,29 +51,24 @@ export default function App() { return (
- - - - - {errorTag} - - - } /> - } /> - } /> - } - /> - } - /> - - - - - + {/* @ts-ignore */} + + + + + + {errorTag} + + + } /> + } /> + } /> + + + + + +
); } diff --git a/src/components/ButtonWithConfirmation.tsx b/src/components/ButtonWithConfirmation.tsx index 883869199..af2ec5eba 100644 --- a/src/components/ButtonWithConfirmation.tsx +++ b/src/components/ButtonWithConfirmation.tsx @@ -3,6 +3,7 @@ import { useState } from 'react'; import { Button, Modal } from '@carbon/react'; type OwnProps = { + 'data-qa'?: string; description?: string; buttonLabel?: string; onConfirmation: (..._args: any[]) => any; @@ -18,6 +19,7 @@ export default function ButtonWithConfirmation({ description, buttonLabel, onConfirmation, + 'data-qa': dataQa, title = 'Are you sure?', confirmButtonLabel = 'OK', kind = 'danger', @@ -51,6 +53,7 @@ export default function ButtonWithConfirmation({ secondaryButtonText="Cancel" onSecondarySubmit={handleConfirmationPromptCancel} onRequestSubmit={handleConfirmation} + onRequestClose={handleConfirmationPromptCancel} /> ); }; @@ -58,6 +61,7 @@ export default function ButtonWithConfirmation({ return ( <> - - ); - } -} diff --git a/src/components/MyCompletedInstances.tsx b/src/components/MyCompletedInstances.tsx new file mode 100644 index 000000000..fe6652951 --- /dev/null +++ b/src/components/MyCompletedInstances.tsx @@ -0,0 +1,13 @@ +import ProcessInstanceListTable from './ProcessInstanceListTable'; + +const paginationQueryParamPrefix = 'my_completed_instances'; + +export default function MyCompletedInstances() { + return ( + + ); +} diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index 25ff3582f..cc7137fb8 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -17,9 +17,13 @@ import { import { Logout, Login } from '@carbon/icons-react'; import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; +import { Can } from '@casl/react'; // @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'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; +import { PermissionsToCheck } from '../interfaces'; +import { usePermissionFetcher } from '../hooks/PermissionService'; // for ref: https://react-bootstrap.github.io/components/navbar/ export default function NavigationBar() { @@ -34,6 +38,14 @@ export default function NavigationBar() { const location = useLocation(); const [activeKey, setActiveKey] = useState(''); + const { targetUris } = useUriListForPermissions(); + const permissionRequestData: PermissionsToCheck = { + [targetUris.authenticationListPath]: ['GET'], + [targetUris.messageInstanceListPath]: ['GET'], + [targetUris.secretListPath]: ['GET'], + }; + const { ability } = usePermissionFetcher(permissionRequestData); + useEffect(() => { let newActiveKey = '/admin/process-groups'; if (location.pathname.match(/^\/admin\/messages\b/)) { @@ -44,10 +56,8 @@ export default function NavigationBar() { newActiveKey = '/admin/process-instances/reports'; } 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.match(/^\/admin\/configuration\b/)) { + newActiveKey = '/admin/configuration'; } else if (location.pathname === '/') { newActiveKey = '/'; } else if (location.pathname.match(/^\/tasks\b/)) { @@ -86,6 +96,42 @@ export default function NavigationBar() { ); }; + const configurationElement = () => { + return ( + + {(authenticationAllowed: boolean) => { + return ( + + {(secretAllowed: boolean) => { + if (secretAllowed || authenticationAllowed) { + return ( + + Configuration + + ); + } + return null; + }} + + ); + }} + + ); + }; + const headerMenuItems = () => { return ( <> @@ -105,35 +151,26 @@ export default function NavigationBar() { > Process Instances - - Messages - - - Secrets - - - Authentications - + + + Messages + + + {configurationElement()} - Reports + Perspectives ); }; - if (activeKey) { + if (activeKey && ability) { return ( ( diff --git a/src/components/PaginationForTable.tsx b/src/components/PaginationForTable.tsx index 3b65c78c2..70da531d9 100644 --- a/src/components/PaginationForTable.tsx +++ b/src/components/PaginationForTable.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom'; // @ts-ignore import { Pagination } from '@carbon/react'; @@ -13,8 +13,7 @@ type OwnProps = { perPageOptions?: number[]; pagination: PaginationObject | null; tableToDisplay: any; - queryParamString?: string; - path: string; + paginationQueryParamPrefix?: string; }; export default function PaginationForTable({ @@ -23,16 +22,21 @@ export default function PaginationForTable({ perPageOptions, pagination, tableToDisplay, - queryParamString = '', - path, + paginationQueryParamPrefix, }: OwnProps) { const PER_PAGE_OPTIONS = [2, 10, 50, 100]; - const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const paginationQueryParamPrefixToUse = paginationQueryParamPrefix + ? `${paginationQueryParamPrefix}_` + : ''; const updateRows = (args: any) => { const newPage = args.page; const { pageSize } = args; - navigate(`${path}?page=${newPage}&per_page=${pageSize}${queryParamString}`); + + searchParams.set(`${paginationQueryParamPrefixToUse}page`, newPage); + searchParams.set(`${paginationQueryParamPrefixToUse}per_page`, pageSize); + setSearchParams(searchParams); }; if (pagination) { diff --git a/src/components/ProcessGroupForm.tsx b/src/components/ProcessGroupForm.tsx index 3d51adeb9..e427f43b2 100644 --- a/src/components/ProcessGroupForm.tsx +++ b/src/components/ProcessGroupForm.tsx @@ -165,11 +165,7 @@ export default function ProcessGroupForm({ }; const formButtons = () => { - const buttons = [ - , - ]; + const buttons = []; if (mode === 'edit') { buttons.push( ( + null + ); + + useEffect(() => { + const setProcessGroupsFromResult = (result: any) => { + setProcessGroups(result.results); + }; + let queryParams = '?per_page=1000'; + if (processGroup) { + queryParams = `${queryParams}&process_group_identifier=${processGroup.id}`; + } + HttpService.makeCallToBackend({ + path: `/process-groups${queryParams}`, + successCallback: setProcessGroupsFromResult, + }); + }, [searchParams, processGroup]); + + const processGroupDirectChildrenCount = (pg: ProcessGroup) => { + return (pg.process_models || []).length + (pg.process_groups || []).length; + }; + + const processGroupsDisplayArea = () => { + let displayText = null; + if (processGroups && processGroups.length > 0) { + displayText = (processGroups || []).map((row: ProcessGroup) => { + return ( + +
+ +
+ {row.display_name} +
+

+ {truncateString(row.description || '', 25)} +

+

+ Total Sub Items: {processGroupDirectChildrenCount(row)} +

+
+
+ ); + }); + } else { + displayText =

No Groups To Display

; + } + return displayText; + }; + + const processGroupArea = () => { + if (processGroups && (!processGroup || processGroups.length > 0)) { + return ( + <> + {headerElement} + {processGroupsDisplayArea()} + + ); + } + return null; + }; + + if (processGroups) { + return <>{processGroupArea()}; + } + return null; +} diff --git a/src/components/ProcessInstanceListTable.tsx b/src/components/ProcessInstanceListTable.tsx new file mode 100644 index 000000000..6d5fbb0b0 --- /dev/null +++ b/src/components/ProcessInstanceListTable.tsx @@ -0,0 +1,723 @@ +import { useContext, useEffect, useMemo, useState } from 'react'; +import { + Link, + useNavigate, + useParams, + useSearchParams, +} from 'react-router-dom'; + +// @ts-ignore +import { Filter } from '@carbon/icons-react'; +import { + Button, + ButtonSet, + DatePicker, + DatePickerInput, + Table, + Grid, + Column, + MultiSelect, + TableHeader, + TableHead, + TableRow, + TimePicker, + // @ts-ignore +} from '@carbon/react'; +import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; +import { + convertDateAndTimeStringsToSeconds, + convertDateObjectToFormattedHoursMinutes, + convertSecondsToFormattedDateString, + convertSecondsToFormattedDateTime, + convertSecondsToFormattedTimeHoursMinutes, + getPageInfoFromSearchParams, + getProcessModelFullIdentifierFromSearchParams, + modifyProcessModelPath, +} from '../helpers'; + +import PaginationForTable from './PaginationForTable'; +import 'react-datepicker/dist/react-datepicker.css'; + +import ErrorContext from '../contexts/ErrorContext'; +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 './ProcessModelSearch'; + +type OwnProps = { + filtersEnabled?: boolean; + processModelFullIdentifier?: string; + paginationQueryParamPrefix?: string; + perPageOptions?: number[]; +}; + +interface dateParameters { + [key: string]: ((..._args: any[]) => any)[]; +} + +export default function ProcessInstanceListTable({ + filtersEnabled = true, + processModelFullIdentifier, + paginationQueryParamPrefix, + perPageOptions, +}: OwnProps) { + const params = useParams(); + const [searchParams] = useSearchParams(); + const navigate = useNavigate(); + + const [processInstances, setProcessInstances] = useState([]); + const [reportMetadata, setReportMetadata] = useState({}); + const [pagination, setPagination] = useState(null); + const [processInstanceFilters, setProcessInstanceFilters] = useState({}); + + const oneHourInSeconds = 3600; + const oneMonthInSeconds = oneHourInSeconds * 24 * 30; + const [startFromDate, setStartFromDate] = useState(''); + const [startToDate, setStartToDate] = useState(''); + const [endFromDate, setEndFromDate] = useState(''); + const [endToDate, setEndToDate] = useState(''); + const [startFromTime, setStartFromTime] = useState(''); + const [startToTime, setStartToTime] = useState(''); + const [endFromTime, setEndFromTime] = useState(''); + const [endToTime, setEndToTime] = useState(''); + const [showFilterOptions, setShowFilterOptions] = useState(false); + const [startFromTimeInvalid, setStartFromTimeInvalid] = + useState(false); + const [startToTimeInvalid, setStartToTimeInvalid] = useState(false); + const [endFromTimeInvalid, setEndFromTimeInvalid] = useState(false); + const [endToTimeInvalid, setEndToTimeInvalid] = useState(false); + + const setErrorMessage = (useContext as any)(ErrorContext)[1]; + + const [processStatusAllOptions, setProcessStatusAllOptions] = useState( + [] + ); + const [processStatusSelection, setProcessStatusSelection] = useState< + string[] + >([]); + const [processModelAvailableItems, setProcessModelAvailableItems] = useState< + ProcessModel[] + >([]); + const [processModelSelection, setProcessModelSelection] = + useState(null); + + const dateParametersToAlwaysFilterBy: dateParameters = useMemo(() => { + return { + start_from: [setStartFromDate, setStartFromTime], + start_to: [setStartToDate, setStartToTime], + end_from: [setEndFromDate, setEndFromTime], + end_to: [setEndToDate, setEndToTime], + }; + }, [ + setStartFromDate, + setStartFromTime, + setStartToDate, + setStartToTime, + setEndFromDate, + setEndFromTime, + setEndToDate, + setEndToTime, + ]); + + const parametersToGetFromSearchParams = useMemo(() => { + return { + process_model_identifier: null, + process_status: null, + }; + }, []); + + // eslint-disable-next-line sonarjs/cognitive-complexity + useEffect(() => { + function setProcessInstancesFromResult(result: any) { + const processInstancesFromApi = result.results; + setProcessInstances(processInstancesFromApi); + setReportMetadata(result.report_metadata); + setPagination(result.pagination); + setProcessInstanceFilters(result.filters); + } + function getProcessInstances() { + // eslint-disable-next-line prefer-const + let { page, perPage } = getPageInfoFromSearchParams( + searchParams, + undefined, + undefined, + paginationQueryParamPrefix + ); + if (perPageOptions && !perPageOptions.includes(perPage)) { + // eslint-disable-next-line prefer-destructuring + perPage = perPageOptions[1]; + } + let queryParamString = `per_page=${perPage}&page=${page}`; + + const userAppliedFilter = searchParams.get('user_filter'); + if (userAppliedFilter) { + queryParamString += `&user_filter=${userAppliedFilter}`; + } + + Object.keys(dateParametersToAlwaysFilterBy).forEach( + (paramName: string) => { + const dateFunctionToCall = + dateParametersToAlwaysFilterBy[paramName][0]; + const timeFunctionToCall = + dateParametersToAlwaysFilterBy[paramName][1]; + const searchParamValue = searchParams.get(paramName); + if (searchParamValue) { + queryParamString += `&${paramName}=${searchParamValue}`; + const dateString = convertSecondsToFormattedDateString( + searchParamValue as any + ); + dateFunctionToCall(dateString); + const timeString = convertSecondsToFormattedTimeHoursMinutes( + searchParamValue as any + ); + timeFunctionToCall(timeString); + setShowFilterOptions(true); + } + } + ); + + Object.keys(parametersToGetFromSearchParams).forEach( + (paramName: string) => { + if ( + paramName === 'process_model_identifier' && + processModelFullIdentifier + ) { + queryParamString += `&process_model_identifier=${processModelFullIdentifier}`; + } else if (searchParams.get(paramName)) { + // @ts-expect-error TS(7053) FIXME: + const functionToCall = parametersToGetFromSearchParams[paramName]; + queryParamString += `&${paramName}=${searchParams.get(paramName)}`; + if (functionToCall !== null) { + functionToCall(searchParams.get(paramName) || ''); + } + setShowFilterOptions(true); + } + } + ); + + HttpService.makeCallToBackend({ + path: `/process-instances?${queryParamString}`, + successCallback: setProcessInstancesFromResult, + }); + } + function processResultForProcessModels(result: any) { + const processModelFullIdentifierFromSearchParams = + getProcessModelFullIdentifierFromSearchParams(searchParams); + const selectionArray = result.results.map((item: any) => { + const label = `${item.id}`; + Object.assign(item, { label }); + if (label === processModelFullIdentifierFromSearchParams) { + setProcessModelSelection(item); + } + return item; + }); + setProcessModelAvailableItems(selectionArray); + + 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(processStatusOption); + } + return processStatusOption; + } + ); + setProcessStatusSelection(processStatusSelectedArray); + setProcessStatusAllOptions(processStatusAllOptionsArray); + + getProcessInstances(); + } + + if (filtersEnabled) { + // populate process model selection + HttpService.makeCallToBackend({ + path: `/process-models?per_page=1000`, + successCallback: processResultForProcessModels, + }); + } else { + getProcessInstances(); + } + }, [ + searchParams, + params, + oneMonthInSeconds, + oneHourInSeconds, + dateParametersToAlwaysFilterBy, + parametersToGetFromSearchParams, + filtersEnabled, + paginationQueryParamPrefix, + processModelFullIdentifier, + perPageOptions, + ]); + + // This sets the filter data using the saved reports returned from the initial instance_list query. + // This could probably be merged into the main useEffect but it works here now. + useEffect(() => { + const filters = processInstanceFilters as any; + Object.keys(dateParametersToAlwaysFilterBy).forEach((paramName: string) => { + const dateFunctionToCall = dateParametersToAlwaysFilterBy[paramName][0]; + const timeFunctionToCall = dateParametersToAlwaysFilterBy[paramName][1]; + const paramValue = filters[paramName]; + dateFunctionToCall(''); + timeFunctionToCall(''); + if (paramValue) { + const dateString = convertSecondsToFormattedDateString( + paramValue as any + ); + dateFunctionToCall(dateString); + const timeString = convertSecondsToFormattedTimeHoursMinutes( + paramValue as any + ); + timeFunctionToCall(timeString); + setShowFilterOptions(true); + } + }); + + setProcessModelSelection(null); + processModelAvailableItems.forEach((item: any) => { + if (item.id === filters.process_model_identifier) { + setProcessModelSelection(item); + } + }); + + const processStatusSelectedArray: string[] = []; + if (filters.process_status) { + PROCESS_STATUSES.forEach((processStatusOption: any) => { + const regex = new RegExp(`\\b${processStatusOption}\\b`); + if (filters.process_status.match(regex)) { + processStatusSelectedArray.push(processStatusOption); + } + }); + setShowFilterOptions(true); + } + setProcessStatusSelection(processStatusSelectedArray); + }, [ + processInstanceFilters, + dateParametersToAlwaysFilterBy, + parametersToGetFromSearchParams, + processModelAvailableItems, + ]); + + // does the comparison, but also returns false if either argument + // is not truthy and therefore not comparable. + const isTrueComparison = (param1: any, operation: any, param2: any) => { + if (param1 && param2) { + switch (operation) { + case '<': + return param1 < param2; + case '>': + return param1 > param2; + default: + return false; + } + } else { + return false; + } + }; + + const applyFilter = (event: any) => { + event.preventDefault(); + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + undefined, + undefined, + paginationQueryParamPrefix + ); + let queryParamString = `per_page=${perPage}&page=${page}&user_filter=true`; + + const startFromSeconds = convertDateAndTimeStringsToSeconds( + startFromDate, + startFromTime || '00:00:00' + ); + const startToSeconds = convertDateAndTimeStringsToSeconds( + startToDate, + startToTime || '00:00:00' + ); + const endFromSeconds = convertDateAndTimeStringsToSeconds( + endFromDate, + endFromTime || '00:00:00' + ); + const endToSeconds = convertDateAndTimeStringsToSeconds( + endToDate, + endToTime || '00:00:00' + ); + if (isTrueComparison(startFromSeconds, '>', startToSeconds)) { + setErrorMessage({ + message: '"Start date from" cannot be after "start date to"', + }); + return; + } + if (isTrueComparison(endFromSeconds, '>', endToSeconds)) { + setErrorMessage({ + message: '"End date from" cannot be after "end date to"', + }); + return; + } + if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) { + setErrorMessage({ + message: '"Start date from" cannot be after "end date from"', + }); + return; + } + if (isTrueComparison(startToSeconds, '>', endToSeconds)) { + setErrorMessage({ + message: '"Start date to" cannot be after "end date to"', + }); + return; + } + + if (startFromSeconds) { + queryParamString += `&start_from=${startFromSeconds}`; + } + if (startToSeconds) { + queryParamString += `&start_to=${startToSeconds}`; + } + if (endFromSeconds) { + queryParamString += `&end_from=${endFromSeconds}`; + } + if (endToSeconds) { + queryParamString += `&end_to=${endToSeconds}`; + } + if (processStatusSelection.length > 0) { + queryParamString += `&process_status=${processStatusSelection}`; + } + + if (processModelSelection) { + queryParamString += `&process_model_identifier=${processModelSelection.id}`; + } + + setErrorMessage(null); + navigate(`/admin/process-instances?${queryParamString}`); + }; + + const dateComponent = ( + labelString: any, + name: any, + initialDate: any, + initialTime: string, + onChangeDateFunction: any, + onChangeTimeFunction: any, + timeInvalid: boolean, + setTimeInvalid: any + ) => { + return ( + <> + + { + if (!initialDate && !initialTime) { + onChangeTimeFunction( + convertDateObjectToFormattedHoursMinutes(new Date()) + ); + } + onChangeDateFunction(dateChangeEvent.srcElement.value); + }} + value={initialDate} + /> + + { + if (event.srcElement.validity.valid) { + setTimeInvalid(false); + } else { + setTimeInvalid(true); + } + onChangeTimeFunction(event.srcElement.value); + }} + /> + + ); + }; + + const processStatusSearch = () => { + return ( + { + setProcessStatusSelection(selection.selectedItems); + }} + itemToString={(item: any) => { + return item || ''; + }} + selectionFeedback="top-after-reopen" + selectedItems={processStatusSelection} + /> + ); + }; + + const clearFilters = () => { + setProcessModelSelection(null); + setProcessStatusSelection([]); + setStartFromDate(''); + setStartFromTime(''); + setStartToDate(''); + setStartToTime(''); + setEndFromDate(''); + setEndFromTime(''); + setEndToDate(''); + setEndToTime(''); + }; + + const filterOptions = () => { + if (!showFilterOptions) { + return null; + } + return ( + <> + + + + setProcessModelSelection(selection.selectedItem) + } + processModels={processModelAvailableItems} + selectedItem={processModelSelection} + /> + + {processStatusSearch()} + + + + {dateComponent( + 'Start date from', + 'start-from', + startFromDate, + startFromTime, + setStartFromDate, + setStartFromTime, + startFromTimeInvalid, + setStartFromTimeInvalid + )} + + + {dateComponent( + 'Start date to', + 'start-to', + startToDate, + startToTime, + setStartToDate, + setStartToTime, + startToTimeInvalid, + setStartToTimeInvalid + )} + + + {dateComponent( + 'End date from', + 'end-from', + endFromDate, + endFromTime, + setEndFromDate, + setEndFromTime, + endFromTimeInvalid, + setEndFromTimeInvalid + )} + + + {dateComponent( + 'End date to', + 'end-to', + endToDate, + endToTime, + setEndToDate, + setEndToTime, + endToTimeInvalid, + setEndToTimeInvalid + )} + + + + + + + + + + + + ); + }; + + const buildTable = () => { + const headerLabels: Record = { + id: 'Id', + process_model_identifier: 'Process Model', + start_in_seconds: 'Start Time', + end_in_seconds: 'End Time', + status: 'Status', + spiff_step: 'SpiffWorkflow Step', + }; + const getHeaderLabel = (header: string) => { + return headerLabels[header] ?? header; + }; + const headers = (reportMetadata as any).columns.map((column: any) => { + // return {getHeaderLabel((column as any).Header)}; + return getHeaderLabel((column as any).Header); + }); + + const formatProcessInstanceId = (row: any, id: any) => { + const modifiedProcessModelId: String = modifyProcessModelPath( + row.process_model_identifier + ); + return ( + + {id} + + ); + }; + const formatProcessModelIdentifier = (_row: any, identifier: any) => { + return ( + + {identifier} + + ); + }; + const formatSecondsForDisplay = (_row: any, seconds: any) => { + return convertSecondsToFormattedDateTime(seconds) || '-'; + }; + const defaultFormatter = (_row: any, value: any) => { + return value; + }; + + const columnFormatters: Record = { + id: formatProcessInstanceId, + process_model_identifier: formatProcessModelIdentifier, + start_in_seconds: formatSecondsForDisplay, + end_in_seconds: formatSecondsForDisplay, + }; + const formattedColumn = (row: any, column: any) => { + const formatter = columnFormatters[column.accessor] ?? defaultFormatter; + const value = row[column.accessor]; + if (column.accessor === 'status') { + return ( + + {formatter(row, value)} + + ); + } + return {formatter(row, value)}; + }; + + const rows = processInstances.map((row: any) => { + const currentRow = (reportMetadata as any).columns.map((column: any) => { + return formattedColumn(row, column); + }); + return {currentRow}; + }); + + return ( + + + + {headers.map((header: any) => ( + + {header} + + ))} + + + {rows} +
+ ); + }; + + const toggleShowFilterOptions = () => { + setShowFilterOptions(!showFilterOptions); + }; + + const filterComponent = () => { + if (!filtersEnabled) { + return null; + } + return ( + <> + + + + ); +} diff --git a/src/components/ProcessModelForm.tsx b/src/components/ProcessModelForm.tsx index 8cca57934..9725f2422 100644 --- a/src/components/ProcessModelForm.tsx +++ b/src/components/ProcessModelForm.tsx @@ -2,14 +2,9 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; // @ts-ignore import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react'; -import { - getGroupFromModifiedModelId, - modifyProcessModelPath, - slugifyString, -} from '../helpers'; +import { modifyProcessModelPath, slugifyString } from '../helpers'; import HttpService from '../services/HttpService'; import { ProcessModel } from '../interfaces'; -import ButtonWithConfirmation from './ButtonWithConfirmation'; type OwnProps = { mode: string; @@ -29,7 +24,6 @@ export default function ProcessModelForm({ useState(false); const [displayNameInvalid, setDisplayNameInvalid] = useState(false); const navigate = useNavigate(); - const modifiedProcessModelPath = modifyProcessModelPath(processModel.id); const navigateToProcessModel = (result: ProcessModel) => { if ('id' in result) { @@ -40,30 +34,14 @@ export default function ProcessModelForm({ } }; - const navigateToProcessModels = (_result: any) => { - navigate( - `/admin/process-groups/${getGroupFromModifiedModelId( - modifiedProcessModelPath - )}` - ); - }; - const hasValidIdentifier = (identifierToCheck: string) => { return identifierToCheck.match(/^[a-z0-9][0-9a-z-]+[a-z0-9]$/); }; - const deleteProcessModel = () => { - HttpService.makeCallToBackend({ - path: `/process-models/${modifiedProcessModelPath}`, - successCallback: navigateToProcessModels, - httpMethod: 'DELETE', - }); - }; - const handleFormSubmission = (event: any) => { event.preventDefault(); let hasErrors = false; - if (!hasValidIdentifier(processModel.id)) { + if (mode === 'new' && !hasValidIdentifier(processModel.id)) { setIdentifierInvalid(true); hasErrors = true; } @@ -74,10 +52,7 @@ export default function ProcessModelForm({ if (hasErrors) { return; } - let path = `/process-models`; - if (mode === 'edit') { - path = `/process-models/${modifiedProcessModelPath}`; - } + const path = `/process-models/${processGroupId}`; let httpMethod = 'POST'; if (mode === 'edit') { httpMethod = 'PUT'; @@ -88,7 +63,7 @@ export default function ProcessModelForm({ }; if (mode === 'new') { Object.assign(postBody, { - id: `${processGroupId}:${processModel.id}`, + id: `${processGroupId}/${processModel.id}`, }); } @@ -175,16 +150,6 @@ export default function ProcessModelForm({ Submit , ]; - if (mode === 'edit') { - buttons.push( - - ); - } return {buttons}; }; return ( diff --git a/src/components/ProcessModelListTiles.tsx b/src/components/ProcessModelListTiles.tsx new file mode 100644 index 000000000..a10fd7543 --- /dev/null +++ b/src/components/ProcessModelListTiles.tsx @@ -0,0 +1,105 @@ +import { ReactElement, useEffect, useState } from 'react'; +import { Link, useSearchParams } from 'react-router-dom'; +import { + Tile, + // @ts-ignore +} from '@carbon/react'; +import HttpService from '../services/HttpService'; +import { ProcessModel, ProcessInstance } from '../interfaces'; +import { modifyProcessModelPath, truncateString } from '../helpers'; +import ProcessInstanceRun from './ProcessInstanceRun'; + +type OwnProps = { + headerElement?: ReactElement; +}; + +export default function ProcessModelListTiles({ headerElement }: OwnProps) { + const [searchParams] = useSearchParams(); + const [processModels, setProcessModels] = useState( + null + ); + const [processInstance, setProcessInstance] = + useState(null); + + useEffect(() => { + const setProcessModelsFromResult = (result: any) => { + setProcessModels(result.results); + }; + // only allow 10 for now until we get the backend only returnin certain models for user execution + const queryParams = '?per_page=10'; + HttpService.makeCallToBackend({ + path: `/process-models${queryParams}`, + successCallback: setProcessModelsFromResult, + }); + }, [searchParams]); + + const processInstanceRunResultTag = () => { + if (processInstance) { + return ( +
+

+ Process Instance {processInstance.id} kicked off ( + + view + + ). +

+
+ ); + } + return null; + }; + + const processModelsDisplayArea = () => { + let displayText = null; + if (processModels && processModels.length > 0) { + displayText = (processModels || []).map((row: ProcessModel) => { + return ( + +
+
{row.display_name}
+

+ {truncateString(row.description || '', 25)} +

+ +
+
+ ); + }); + } else { + displayText =

No Models To Display

; + } + return displayText; + }; + + const processModelArea = () => { + if (processModels && processModels.length > 0) { + return ( + <> + {headerElement} + {processInstanceRunResultTag()} + {processModelsDisplayArea()} + + ); + } + return null; + }; + + if (processModels) { + return <>{processModelArea()}; + } + return null; +} diff --git a/src/components/ProcessSearch.tsx b/src/components/ProcessSearch.tsx new file mode 100644 index 000000000..75ee69b24 --- /dev/null +++ b/src/components/ProcessSearch.tsx @@ -0,0 +1,56 @@ +import { + ComboBox, + // @ts-ignore +} from '@carbon/react'; +import { truncateString } from '../helpers'; +import { ProcessReference } from '../interfaces'; + +type OwnProps = { + onChange: (..._args: any[]) => any; + processes: ProcessReference[]; + selectedItem?: ProcessReference | null; + titleText?: string; + height?: string; +}; + +export default function ProcessSearch({ + processes, + selectedItem, + onChange, + titleText = 'Process Search', + height = '50px', +}: OwnProps) { + const shouldFilter = (options: any) => { + const process: ProcessReference = options.item; + const { inputValue } = options; + return ( + inputValue === null || + `${process.display_name} (${process.identifier})` + .toLowerCase() + .includes(inputValue.toLowerCase()) + ); + }; + return ( +
+ { + if (process) { + return `${process.display_name} (${truncateString( + process.identifier, + 20 + )})`; + } + return null; + }} + shouldFilterItem={shouldFilter} + placeholder="Choose a process" + titleText={titleText} + selectedItem={selectedItem} + /> +
+ ); +} diff --git a/src/components/ReactDiagramEditor.tsx b/src/components/ReactDiagramEditor.tsx index 37a947e43..956ff6c62 100644 --- a/src/components/ReactDiagramEditor.tsx +++ b/src/components/ReactDiagramEditor.tsx @@ -52,10 +52,14 @@ import TouchModule from 'diagram-js/lib/navigation/touch'; // @ts-expect-error TS(7016) FIXME import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'; +import { Can } from '@casl/react'; import HttpService from '../services/HttpService'; import ButtonWithConfirmation from './ButtonWithConfirmation'; import { makeid } from '../helpers'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; +import { PermissionsToCheck } from '../interfaces'; +import { usePermissionFetcher } from '../hooks/PermissionService'; type OwnProps = { processModelId: string; @@ -76,6 +80,7 @@ type OwnProps = { onServiceTasksRequested?: (..._args: any[]) => any; onJsonFilesRequested?: (..._args: any[]) => any; onDmnFilesRequested?: (..._args: any[]) => any; + onSearchProcessModels?: (..._args: any[]) => any; url?: string; }; @@ -99,6 +104,7 @@ export default function ReactDiagramEditor({ onServiceTasksRequested, onJsonFilesRequested, onDmnFilesRequested, + onSearchProcessModels, url, }: OwnProps) { const [diagramXMLString, setDiagramXMLString] = useState(''); @@ -107,6 +113,13 @@ export default function ReactDiagramEditor({ const alreadyImportedXmlRef = useRef(false); + const { targetUris } = useUriListForPermissions(); + const permissionRequestData: PermissionsToCheck = { + [targetUris.processModelShowPath]: ['PUT'], + [targetUris.processModelFileShowPath]: ['POST', 'GET', 'PUT', 'DELETE'], + }; + const { ability } = usePermissionFetcher(permissionRequestData); + useEffect(() => { if (diagramModelerState) { return; @@ -292,6 +305,12 @@ export default function ReactDiagramEditor({ diagramModeler.on('spiff.json_files.requested', (event: any) => { handleServiceTasksRequested(event); }); + + diagramModeler.on('spiff.callactivity.search', (event: any) => { + if (onSearchProcessModels) { + onSearchProcessModels(event.value, event.eventBus, event.element); + } + }); }, [ diagramModelerState, diagramType, @@ -304,6 +323,7 @@ export default function ReactDiagramEditor({ onServiceTasksRequested, onJsonFilesRequested, onDmnFilesRequested, + onSearchProcessModels, ]); useEffect(() => { @@ -517,20 +537,40 @@ export default function ReactDiagramEditor({ if (diagramType !== 'readonly') { return ( <> - - {fileName && ( - - )} - {onSetPrimaryFile && ( - - )} - + + + + + {fileName && ( + + )} + + + {onSetPrimaryFile && ( + + )} + + + + ); } diff --git a/src/components/SubNavigation.tsx b/src/components/SubNavigation.tsx deleted file mode 100644 index be3097f72..000000000 --- a/src/components/SubNavigation.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useEffect, useState } from 'react'; -import Nav from 'react-bootstrap/Nav'; -import { useLocation } from 'react-router-dom'; - -export default function SubNavigation() { - const location = useLocation(); - const [activeKey, setActiveKey] = useState(''); - - useEffect(() => { - let newActiveKey = '/admin/process-groups'; - if (location.pathname.match(/^\/admin\/messages\b/)) { - newActiveKey = '/admin/messages'; - } else if ( - location.pathname.match(/^\/admin\/process-instances\/reports\b/) - ) { - newActiveKey = '/admin/process-instances/reports'; - } 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 = '/'; - } - setActiveKey(newActiveKey); - }, [location]); - - if (activeKey) { - return ( - - ); - } - return null; -} diff --git a/src/components/TasksForMyOpenProcesses.tsx b/src/components/TasksForMyOpenProcesses.tsx new file mode 100644 index 000000000..002f74089 --- /dev/null +++ b/src/components/TasksForMyOpenProcesses.tsx @@ -0,0 +1,142 @@ +import { useEffect, useState } from 'react'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; +import { Link, useSearchParams } from 'react-router-dom'; +import PaginationForTable from './PaginationForTable'; +import { + convertSecondsToFormattedDateTime, + getPageInfoFromSearchParams, + modifyProcessModelPath, +} from '../helpers'; +import HttpService from '../services/HttpService'; +import { PaginationObject } from '../interfaces'; + +const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5; +const paginationQueryParamPrefix = 'tasks_for_my_open_processes'; + +export default function MyOpenProcesses() { + const [searchParams] = useSearchParams(); + const [tasks, setTasks] = useState([]); + const [pagination, setPagination] = useState(null); + + useEffect(() => { + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + paginationQueryParamPrefix + ); + const setTasksFromResult = (result: any) => { + setTasks(result.results); + setPagination(result.pagination); + }; + HttpService.makeCallToBackend({ + path: `/tasks/for-my-open-processes?per_page=${perPage}&page=${page}`, + successCallback: setTasksFromResult, + }); + }, [searchParams]); + + const buildTable = () => { + const rows = tasks.map((row) => { + const rowToUse = row as any; + const taskUrl = `/tasks/${rowToUse.process_instance_id}/${rowToUse.task_id}`; + const modifiedProcessModelIdentifier = modifyProcessModelPath( + rowToUse.process_model_identifier + ); + return ( + + + + {rowToUse.process_model_display_name} + + + + + View {rowToUse.process_instance_id} + + + + {rowToUse.task_title} + + {rowToUse.process_instance_status} + {rowToUse.group_identifier || '-'} + + {convertSecondsToFormattedDateTime( + rowToUse.created_at_in_seconds + ) || '-'} + + + {convertSecondsToFormattedDateTime( + rowToUse.updated_at_in_seconds + ) || '-'} + + + + + + ); + }); + return ( + + + + + + + + + + + + + + {rows} +
Process ModelProcess InstanceTask NameProcess Instance StatusAssigned GroupProcess StartedProcess UpdatedActions
+ ); + }; + + const tasksComponent = () => { + if (pagination && pagination.total < 1) { + return null; + } + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + paginationQueryParamPrefix + ); + return ( + <> +

Tasks for my open processes

+ + + ); + }; + + if (pagination) { + return tasksComponent(); + } + return null; +} diff --git a/src/components/TasksWaitingForMe.tsx b/src/components/TasksWaitingForMe.tsx new file mode 100644 index 000000000..53079dd21 --- /dev/null +++ b/src/components/TasksWaitingForMe.tsx @@ -0,0 +1,143 @@ +import { useEffect, useState } from 'react'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; +import { Link, useSearchParams } from 'react-router-dom'; +import PaginationForTable from './PaginationForTable'; +import { + convertSecondsToFormattedDateTime, + getPageInfoFromSearchParams, + modifyProcessModelPath, +} from '../helpers'; +import HttpService from '../services/HttpService'; +import { PaginationObject } from '../interfaces'; + +const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5; + +export default function TasksWaitingForMe() { + const [searchParams] = useSearchParams(); + const [tasks, setTasks] = useState([]); + const [pagination, setPagination] = useState(null); + + useEffect(() => { + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + 'tasks_waiting_for_me' + ); + const setTasksFromResult = (result: any) => { + setTasks(result.results); + setPagination(result.pagination); + }; + HttpService.makeCallToBackend({ + path: `/tasks/for-me?per_page=${perPage}&page=${page}`, + successCallback: setTasksFromResult, + }); + }, [searchParams]); + + const buildTable = () => { + const rows = tasks.map((row) => { + const rowToUse = row as any; + const taskUrl = `/tasks/${rowToUse.process_instance_id}/${rowToUse.task_id}`; + const modifiedProcessModelIdentifier = modifyProcessModelPath( + rowToUse.process_model_identifier + ); + return ( + + + + {rowToUse.process_model_display_name} + + + + + View {rowToUse.process_instance_id} + + + + {rowToUse.task_title} + + {rowToUse.username} + {rowToUse.process_instance_status} + {rowToUse.group_identifier || '-'} + + {convertSecondsToFormattedDateTime( + rowToUse.created_at_in_seconds + ) || '-'} + + + {convertSecondsToFormattedDateTime( + rowToUse.updated_at_in_seconds + ) || '-'} + + + + + + ); + }); + return ( + + + + + + + + + + + + + + + {rows} +
Process ModelProcess InstanceTask NameProcess Started ByProcess Instance StatusAssigned GroupProcess StartedProcess UpdatedActions
+ ); + }; + + const tasksComponent = () => { + if (pagination && pagination.total < 1) { + return null; + } + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + 'tasks_waiting_for_me' + ); + return ( + <> +

Tasks waiting for me

+ + + ); + }; + + if (pagination) { + return tasksComponent(); + } + return null; +} diff --git a/src/components/TasksWaitingForMyGroups.tsx b/src/components/TasksWaitingForMyGroups.tsx new file mode 100644 index 000000000..a60f826b4 --- /dev/null +++ b/src/components/TasksWaitingForMyGroups.tsx @@ -0,0 +1,144 @@ +import { useEffect, useState } from 'react'; +// @ts-ignore +import { Button, Table } from '@carbon/react'; +import { Link, useSearchParams } from 'react-router-dom'; +import PaginationForTable from './PaginationForTable'; +import { + convertSecondsToFormattedDateTime, + getPageInfoFromSearchParams, + modifyProcessModelPath, +} from '../helpers'; +import HttpService from '../services/HttpService'; +import { PaginationObject } from '../interfaces'; + +const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5; +const paginationQueryParamPrefix = 'tasks_waiting_for_my_groups'; + +export default function TasksForWaitingForMyGroups() { + const [searchParams] = useSearchParams(); + const [tasks, setTasks] = useState([]); + const [pagination, setPagination] = useState(null); + + useEffect(() => { + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + paginationQueryParamPrefix + ); + const setTasksFromResult = (result: any) => { + setTasks(result.results); + setPagination(result.pagination); + }; + HttpService.makeCallToBackend({ + path: `/tasks/for-my-groups?per_page=${perPage}&page=${page}`, + successCallback: setTasksFromResult, + }); + }, [searchParams]); + + const buildTable = () => { + const rows = tasks.map((row) => { + const rowToUse = row as any; + const taskUrl = `/tasks/${rowToUse.process_instance_id}/${rowToUse.task_id}`; + const modifiedProcessModelIdentifier = modifyProcessModelPath( + rowToUse.process_model_identifier + ); + return ( + + + + {rowToUse.process_model_display_name} + + + + + View {rowToUse.process_instance_id} + + + + {rowToUse.task_title} + + {rowToUse.username} + {rowToUse.process_instance_status} + {rowToUse.group_identifier || '-'} + + {convertSecondsToFormattedDateTime( + rowToUse.created_at_in_seconds + ) || '-'} + + + {convertSecondsToFormattedDateTime( + rowToUse.updated_at_in_seconds + ) || '-'} + + + + + + ); + }); + return ( + + + + + + + + + + + + + + + {rows} +
Process ModelProcess InstanceTask NameProcess Started ByProcess Instance StatusAssigned GroupProcess StartedProcess UpdatedActions
+ ); + }; + + const tasksComponent = () => { + if (pagination && pagination.total < 1) { + return null; + } + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE, + undefined, + paginationQueryParamPrefix + ); + return ( + <> +

Tasks waiting for my groups

+ + + ); + }; + + if (pagination) { + return tasksComponent(); + } + return null; +} diff --git a/src/config.tsx b/src/config.tsx index 47ff5025a..5e7e96feb 100644 --- a/src/config.tsx +++ b/src/config.tsx @@ -18,5 +18,6 @@ export const PROCESS_STATUSES = [ // with time: yyyy-MM-dd HH:mm:ss export const DATE_TIME_FORMAT = 'yyyy-MM-dd HH:mm:ss'; +export const TIME_FORMAT_HOURS_MINUTES = 'HH:mm'; export const DATE_FORMAT = 'yyyy-MM-dd'; export const DATE_FORMAT_CARBON = 'Y-m-d'; diff --git a/src/contexts/Can.tsx b/src/contexts/Can.tsx new file mode 100644 index 000000000..ff446af87 --- /dev/null +++ b/src/contexts/Can.tsx @@ -0,0 +1,6 @@ +import { createContext } from 'react'; +import { Ability } from '@casl/ability'; +import { createContextualCan } from '@casl/react'; + +export const AbilityContext = createContext(new Ability()); +export const Can = createContextualCan(AbilityContext.Consumer); diff --git a/src/helpers.test.tsx b/src/helpers.test.tsx index 1031fc46b..5a0352b82 100644 --- a/src/helpers.test.tsx +++ b/src/helpers.test.tsx @@ -1,4 +1,4 @@ -import { convertSecondsToFormattedDate, slugifyString } from './helpers'; +import { convertSecondsToFormattedDateString, slugifyString } from './helpers'; test('it can slugify a string', () => { expect(slugifyString('hello---world_ and then Some such-')).toEqual( @@ -7,6 +7,6 @@ test('it can slugify a string', () => { }); test('it can keep the correct date when converting seconds to date', () => { - const dateString = convertSecondsToFormattedDate(1666325400); + const dateString = convertSecondsToFormattedDateString(1666325400); expect(dateString).toEqual('2022-10-21'); }); diff --git a/src/helpers.tsx b/src/helpers.tsx index 383c3e0a5..ab97c8dce 100644 --- a/src/helpers.tsx +++ b/src/helpers.tsx @@ -1,5 +1,9 @@ import { format } from 'date-fns'; -import { DATE_TIME_FORMAT, DATE_FORMAT } from './config'; +import { + DATE_TIME_FORMAT, + DATE_FORMAT, + TIME_FORMAT_HOURS_MINUTES, +} from './config'; import { DEFAULT_PER_PAGE, DEFAULT_PAGE, @@ -42,27 +46,72 @@ export const convertDateToSeconds = ( return null; }; +export const convertDateObjectToFormattedString = (dateObject: Date) => { + if (dateObject) { + return format(dateObject, DATE_FORMAT); + } + return null; +}; + +export const convertDateAndTimeStringsToDate = ( + dateString: string, + timeString: string +) => { + if (dateString && timeString) { + return new Date(`${dateString}T${timeString}`); + } + return null; +}; + +export const convertDateAndTimeStringsToSeconds = ( + dateString: string, + timeString: string +) => { + const dateObject = convertDateAndTimeStringsToDate(dateString, timeString); + if (dateObject) { + return convertDateToSeconds(dateObject); + } + return null; +}; + export const convertStringToDate = (dateString: string) => { - if (dateString) { - // add midnight time to the date so it c uses the correct date - // after converting to timezone - return new Date(`${dateString}T00:10:00`); + return convertDateAndTimeStringsToSeconds(dateString, '00:10:00'); +}; + +export const convertSecondsToDateObject = (seconds: number) => { + if (seconds) { + return new Date(seconds * 1000); } return null; }; export const convertSecondsToFormattedDateTime = (seconds: number) => { - if (seconds) { - const dateObject = new Date(seconds * 1000); + const dateObject = convertSecondsToDateObject(seconds); + if (dateObject) { return format(dateObject, DATE_TIME_FORMAT); } return null; }; -export const convertSecondsToFormattedDate = (seconds: number) => { - if (seconds) { - const dateObject = new Date(seconds * 1000); - return format(dateObject, DATE_FORMAT); +export const convertDateObjectToFormattedHoursMinutes = (dateObject: Date) => { + if (dateObject) { + return format(dateObject, TIME_FORMAT_HOURS_MINUTES); + } + return null; +}; + +export const convertSecondsToFormattedTimeHoursMinutes = (seconds: number) => { + const dateObject = convertSecondsToDateObject(seconds); + if (dateObject) { + return convertDateObjectToFormattedHoursMinutes(dateObject); + } + return null; +}; + +export const convertSecondsToFormattedDateString = (seconds: number) => { + const dateObject = convertSecondsToDateObject(seconds); + if (dateObject) { + return convertDateObjectToFormattedString(dateObject); } return null; }; @@ -79,11 +128,20 @@ export const objectIsEmpty = (obj: object) => { export const getPageInfoFromSearchParams = ( searchParams: any, defaultPerPage: string | number = DEFAULT_PER_PAGE, - defaultPage: string | number = DEFAULT_PAGE + defaultPage: string | number = DEFAULT_PAGE, + paginationQueryParamPrefix: string | null = null ) => { - const page = parseInt(searchParams.get('page') || defaultPage.toString(), 10); + const paginationQueryParamPrefixToUse = paginationQueryParamPrefix + ? `${paginationQueryParamPrefix}_` + : ''; + const page = parseInt( + searchParams.get(`${paginationQueryParamPrefixToUse}page`) || + defaultPage.toString(), + 10 + ); const perPage = parseInt( - searchParams.get('per_page') || defaultPerPage.toString(), + searchParams.get(`${paginationQueryParamPrefixToUse}per_page`) || + defaultPerPage.toString(), 10 ); @@ -139,3 +197,16 @@ export const getGroupFromModifiedModelId = (modifiedId: string) => { export const splitProcessModelId = (processModelId: string) => { return processModelId.split('/'); }; + +export const refreshAtInterval = ( + interval: number, + timeout: number, + func: Function +) => { + const intervalRef = setInterval(() => func(), interval * 1000); + const timeoutRef = setTimeout( + () => clearInterval(intervalRef), + timeout * 1000 + ); + return [intervalRef, timeoutRef]; +}; diff --git a/src/hooks/PermissionService.tsx b/src/hooks/PermissionService.tsx new file mode 100644 index 000000000..e8a40b962 --- /dev/null +++ b/src/hooks/PermissionService.tsx @@ -0,0 +1,48 @@ +// We may need to update usage of Ability when we update. +// They say they are going to rename PureAbility to Ability and remove the old class. +import { AbilityBuilder, Ability } from '@casl/ability'; +import { useContext, useEffect } from 'react'; +import { AbilityContext } from '../contexts/Can'; +import { PermissionCheckResponseBody, PermissionsToCheck } from '../interfaces'; +import HttpService from '../services/HttpService'; + +export const usePermissionFetcher = ( + permissionsToCheck: PermissionsToCheck +) => { + const ability = useContext(AbilityContext); + + useEffect(() => { + const processPermissionResult = (result: PermissionCheckResponseBody) => { + const oldRules = ability.rules; + const { can, cannot, rules } = new AbilityBuilder(Ability); + Object.keys(result.results).forEach((url: string) => { + const permissionVerbResults = result.results[url]; + Object.keys(permissionVerbResults).forEach((permissionVerb: string) => { + const hasPermission = permissionVerbResults[permissionVerb]; + if (hasPermission) { + can(permissionVerb, url); + } else { + cannot(permissionVerb, url); + } + }); + }); + oldRules.forEach((oldRule: any) => { + if (oldRule.inverted) { + cannot(oldRule.action, oldRule.subject); + } else { + can(oldRule.action, oldRule.subject); + } + }); + ability.update(rules); + }; + + HttpService.makeCallToBackend({ + path: `/permissions-check`, + httpMethod: 'POST', + successCallback: processPermissionResult, + postBody: { requests_to_check: permissionsToCheck }, + }); + }); + + return { ability }; +}; diff --git a/src/hooks/UriListForPermissions.tsx b/src/hooks/UriListForPermissions.tsx new file mode 100644 index 000000000..9c61234b2 --- /dev/null +++ b/src/hooks/UriListForPermissions.tsx @@ -0,0 +1,20 @@ +import { useParams } from 'react-router-dom'; + +export const useUriListForPermissions = () => { + const params = useParams(); + const targetUris = { + authenticationListPath: `/v1.0/authentications`, + messageInstanceListPath: '/v1.0/messages', + processGroupListPath: '/v1.0/process-groups', + processGroupShowPath: `/v1.0/process-groups/${params.process_group_id}`, + processInstanceActionPath: `/v1.0/process-models/${params.process_model_id}/process-instances`, + processInstanceListPath: '/v1.0/process-instances', + processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`, + processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`, + processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`, + processModelShowPath: `/v1.0/process-models/${params.process_model_id}`, + secretListPath: `/v1.0/secrets`, + }; + + return { targetUris }; +}; diff --git a/src/index.css b/src/index.css index c2e2e8028..0d267086b 100644 --- a/src/index.css +++ b/src/index.css @@ -5,21 +5,21 @@ color: white; } -h1{ - height: 36px; - font-family: 'IBM Plex Sans'; - font-style: normal; +h1 { font-weight: 400; font-size: 28px; line-height: 36px; color: #161616; - flex: none; - order: 0; - align-self: stretch; - flex-grow: 0; margin-bottom: 1em } +h2 { + font-weight: 400; + font-size: 20px; + line-height: 28px; + color: #161616; +} + .span-tag { color: black; } @@ -31,7 +31,7 @@ h1{ border: 1px solid #393939; } .cds--btn.button-white-background:hover { - background: #525252; + background: lightgrey; } .cds--breadcrumb-item a.cds--link:hover { @@ -71,7 +71,7 @@ h1{ } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + monospace; } .app-logo { @@ -182,9 +182,64 @@ h1.with-icons { } /* Json Web Form CSS Fix - Bootstrap now requries that each li have a "list-inline-item." Also have a PR - in on this with the react-jsonschema-form repo. This is just a patch fix to allow date inputs to layout a little more cleanly */ +in on this with the react-jsonschema-form repo. This is just a patch fix to allow date inputs to layout a little more cleanly */ .list-inline>li { display: inline-block; padding-right: 5px; padding-left: 5px; } + +.cds--tile.tile-process-group { + padding: 0px; + margin: 16px; + width: 354px; + height: 264px; + background: #F4F4F4; + order: 1; + float: left; +} + +.tile-process-group-content-container { + width: 354px; + height: 264px; + padding: 1em; + position: relative; +} + +.tile-process-group-display-name { + margin-top: 2em; + margin-bottom: 1em; + font-size: 20px; + line-height: 28px; + color: #161616; + order: 0; +} + +.tile-title-top { + margin-bottom: 2em; + font-size: 20px; + line-height: 28px; + color: #161616; + order: 0; +} + +.tile-description { + font-size: 14px; + line-height: 20px; + letter-spacing: 0.16px; + color: #161616; + order: 1; +} + +.tile-process-group-children-count { + font-size: 14px; + line-height: 20px; + letter-spacing: 0.16px; + color: #161616; + order: 1; +} + +.tile-pin-bottom { + position: absolute; + bottom: 1em; +} diff --git a/src/interfaces.ts b/src/interfaces.ts index 7c9cb0365..f4540f4fe 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -11,16 +11,18 @@ export interface RecentProcessModel { processModelDisplayName: string; } -export interface ProcessGroup { - id: string; - display_name: string; - description?: string | null; -} - -export interface ProcessFileReference { +export interface ProcessReference { id: string; // The unique id of the process or decision table. - name: string; // The process or decision table name. + name: string; // The process or decision Display name. + identifier: string; + display_name: string; + process_group_id: string; + process_model_id: string; type: string; // either "decision" or "process" + file_name: string; + has_lanes: boolean; + is_executable: boolean; + is_primary: boolean; } export interface ProcessFile { @@ -28,12 +30,17 @@ export interface ProcessFile { last_modified: string; name: string; process_model_id: string; - references: ProcessFileReference[]; + references: ProcessReference[]; size: number; type: string; file_contents?: string; } +export interface ProcessInstance { + id: number; + process_model_identifier: string; +} + export interface ProcessModel { id: string; description: string; @@ -42,6 +49,14 @@ export interface ProcessModel { files: ProcessFile[]; } +export interface ProcessGroup { + id: string; + display_name: string; + description?: string | null; + process_models?: ProcessModel[]; + process_groups?: ProcessGroup[]; +} + // tuple of display value and URL export type HotCrumbItem = [displayValue: string, url?: string]; @@ -70,3 +85,28 @@ export interface PaginationObject { export interface CarbonComboBoxSelection { selectedItem: ProcessModel; } + +export interface CarbonComboBoxProcessSelection { + selectedItem: ProcessReference; +} + +export interface PermissionsToCheck { + [key: string]: string[]; +} +export interface PermissionVerbResults { + [key: string]: boolean; +} +export interface PermissionCheckResult { + [key: string]: PermissionVerbResults; +} +export interface PermissionCheckResponseBody { + results: PermissionCheckResult; +} + +export interface FormField { + id: string; + title: string; + required: boolean; + type: string; + enum: string[]; +} diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx index 84609d663..91ae7ab08 100644 --- a/src/routes/AdminRoutes.tsx +++ b/src/routes/AdminRoutes.tsx @@ -20,10 +20,8 @@ import ReactFormEditor from './ReactFormEditor'; import ErrorContext from '../contexts/ErrorContext'; import ProcessInstanceLogList from './ProcessInstanceLogList'; import MessageInstanceList from './MessageInstanceList'; -import SecretList from './SecretList'; -import SecretNew from './SecretNew'; -import SecretShow from './SecretShow'; -import AuthenticationList from './AuthenticationList'; +import Configuration from './Configuration'; +import JsonSchemaFormBuilder from './JsonSchemaFormBuilder'; export default function AdminRoutes() { const location = useLocation(); @@ -110,10 +108,11 @@ export default function AdminRoutes() { /> } /> } /> - } /> - } /> - } /> - } /> + } /> + } + /> ); } diff --git a/src/routes/CompletedInstances.tsx b/src/routes/CompletedInstances.tsx new file mode 100644 index 000000000..237c21f3b --- /dev/null +++ b/src/routes/CompletedInstances.tsx @@ -0,0 +1,5 @@ +import MyCompletedInstances from '../components/MyCompletedInstances'; + +export default function CompletedInstances() { + return ; +} diff --git a/src/routes/Configuration.tsx b/src/routes/Configuration.tsx new file mode 100644 index 000000000..b2e30416d --- /dev/null +++ b/src/routes/Configuration.tsx @@ -0,0 +1,65 @@ +import { useContext, useEffect, useState } from 'react'; +import { Route, Routes, useLocation, useNavigate } from 'react-router-dom'; +// @ts-ignore +import { Tabs, TabList, Tab } from '@carbon/react'; +import { Can } from '@casl/react'; +import ErrorContext from '../contexts/ErrorContext'; +import SecretList from './SecretList'; +import SecretNew from './SecretNew'; +import SecretShow from './SecretShow'; +import AuthenticationList from './AuthenticationList'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; +import { PermissionsToCheck } from '../interfaces'; +import { usePermissionFetcher } from '../hooks/PermissionService'; + +export default function Configuration() { + const location = useLocation(); + const setErrorMessage = (useContext as any)(ErrorContext)[1]; + const [selectedTabIndex, setSelectedTabIndex] = useState(0); + const navigate = useNavigate(); + + const { targetUris } = useUriListForPermissions(); + const permissionRequestData: PermissionsToCheck = { + [targetUris.authenticationListPath]: ['GET'], + [targetUris.secretListPath]: ['GET'], + }; + const { ability } = usePermissionFetcher(permissionRequestData); + + useEffect(() => { + setErrorMessage(null); + let newSelectedTabIndex = 0; + if (location.pathname.match(/^\/admin\/configuration\/authentications\b/)) { + newSelectedTabIndex = 1; + } + setSelectedTabIndex(newSelectedTabIndex); + }, [location, setErrorMessage]); + + return ( + <> + + + + navigate('/admin/configuration/secrets')}> + Secrets + + + + navigate('/admin/configuration/authentications')} + > + Authentications + + + + +
+ + } /> + } /> + } /> + } /> + } /> + + + ); +} diff --git a/src/routes/CreateNewInstance.tsx b/src/routes/CreateNewInstance.tsx new file mode 100644 index 000000000..fbb3f8440 --- /dev/null +++ b/src/routes/CreateNewInstance.tsx @@ -0,0 +1,9 @@ +import ProcessModelListTiles from '../components/ProcessModelListTiles'; + +export default function CreateNewInstance() { + return ( + Process models available to you} + /> + ); +} diff --git a/src/routes/GroupedTasks.tsx b/src/routes/GroupedTasks.tsx new file mode 100644 index 000000000..a08959c5e --- /dev/null +++ b/src/routes/GroupedTasks.tsx @@ -0,0 +1,15 @@ +import TasksForMyOpenProcesses from '../components/TasksForMyOpenProcesses'; +import TasksWaitingForMe from '../components/TasksWaitingForMe'; +import TasksForWaitingForMyGroups from '../components/TasksWaitingForMyGroups'; + +export default function GroupedTasks() { + return ( + <> + +
+ +
+ + + ); +} diff --git a/src/routes/HomePageRoutes.tsx b/src/routes/HomePageRoutes.tsx new file mode 100644 index 000000000..420484515 --- /dev/null +++ b/src/routes/HomePageRoutes.tsx @@ -0,0 +1,67 @@ +import { useContext, useEffect, useState } from 'react'; +import { Route, Routes, useLocation, useNavigate } from 'react-router-dom'; +// @ts-ignore +import { Tabs, TabList, Tab } from '@carbon/react'; +import TaskShow from './TaskShow'; +import ErrorContext from '../contexts/ErrorContext'; +import MyTasks from './MyTasks'; +import GroupedTasks from './GroupedTasks'; +import CompletedInstances from './CompletedInstances'; +import CreateNewInstance from './CreateNewInstance'; + +export default function HomePageRoutes() { + const location = useLocation(); + const setErrorMessage = (useContext as any)(ErrorContext)[1]; + const [selectedTabIndex, setSelectedTabIndex] = useState(0); + const navigate = useNavigate(); + + useEffect(() => { + setErrorMessage(null); + let newSelectedTabIndex = 0; + if (location.pathname.match(/^\/tasks\/grouped\b/)) { + newSelectedTabIndex = 1; + } else if (location.pathname.match(/^\/tasks\/completed-instances\b/)) { + newSelectedTabIndex = 2; + } else if (location.pathname.match(/^\/tasks\/create-new-instance\b/)) { + newSelectedTabIndex = 3; + } + setSelectedTabIndex(newSelectedTabIndex); + }, [location, setErrorMessage]); + + const renderTabs = () => { + if (location.pathname.match(/^\/tasks\/\d+\/\b/)) { + return null; + } + return ( + <> + + + navigate('/tasks/my-tasks')}>My Tasks + navigate('/tasks/grouped')}>Grouped Tasks + navigate('/tasks/completed-instances')}> + Completed Instances + + navigate('/tasks/create-new-instance')}> + Create New Instance + + + + +
+ + ); + }; + + return ( + <> + {renderTabs()} + + } /> + } /> + } /> + } /> + } /> + } /> + + + ); +} diff --git a/src/routes/JsonSchemaFormBuilder.tsx b/src/routes/JsonSchemaFormBuilder.tsx new file mode 100644 index 000000000..c97e959a8 --- /dev/null +++ b/src/routes/JsonSchemaFormBuilder.tsx @@ -0,0 +1,250 @@ +import { useEffect, useState } from 'react'; +// @ts-ignore +import { Button, Select, SelectItem, TextInput } from '@carbon/react'; +import { useParams } from 'react-router-dom'; +import { FormField } from '../interfaces'; +import { modifyProcessModelPath, slugifyString } from '../helpers'; +import HttpService from '../services/HttpService'; + +export default function JsonSchemaFormBuilder() { + const params = useParams(); + const formFieldTypes = ['textbox', 'checkbox', 'select']; + + const [formTitle, setFormTitle] = useState(''); + const [formDescription, setFormDescription] = useState(''); + const [formId, setFormId] = useState(''); + const [formFields, setFormFields] = useState([]); + const [showNewFormField, setShowNewFormField] = useState(false); + const [formFieldSelectOptions, setFormFieldSelectOptions] = + useState(''); + const [formIdHasBeenUpdatedByUser, setFormIdHasBeenUpdatedByUser] = + useState(false); + const [formFieldIdHasBeenUpdatedByUser, setFormFieldIdHasBeenUpdatedByUser] = + useState(false); + const [showFormFieldSelectTextField, setShowFormFieldSelectTextField] = + useState(false); + + const [formFieldId, setFormFieldId] = useState(''); + const [formFieldTitle, setFormFieldTitle] = useState(''); + const [formFieldType, setFormFieldType] = useState(''); + + const modifiedProcessModelId = modifyProcessModelPath( + `${params.process_model_id}` + ); + + useEffect(() => {}, []); + + const renderFormJson = () => { + const formJson = { + title: formTitle, + description: formDescription, + properties: {}, + required: [], + }; + + formFields.forEach((formField: FormField) => { + let jsonSchemaFieldType = 'string'; + if (formField.type === 'checkbox') { + jsonSchemaFieldType = 'boolean'; + } + const formJsonObject: any = { + type: jsonSchemaFieldType, + title: formField.title, + }; + + if (formField.type === 'select') { + formJsonObject.enum = formField.enum; + } + (formJson.properties as any)[formField.id] = formJsonObject; + }); + + return JSON.stringify(formJson, null, 2); + }; + + const renderFormUiJson = () => { + const uiOrder = formFields.map((formField: FormField) => { + return formField.id; + }); + return JSON.stringify({ 'ui:order': uiOrder }, null, 2); + }; + + const onFormFieldTitleChange = (newFormFieldTitle: string) => { + console.log('newFormFieldTitle', newFormFieldTitle); + console.log( + 'setFormFieldIdHasBeenUpdatedByUser', + formFieldIdHasBeenUpdatedByUser + ); + if (!formFieldIdHasBeenUpdatedByUser) { + setFormFieldId(slugifyString(newFormFieldTitle)); + } + setFormFieldTitle(newFormFieldTitle); + }; + + const onFormTitleChange = (newFormTitle: string) => { + if (!formIdHasBeenUpdatedByUser) { + setFormId(slugifyString(newFormTitle)); + } + setFormTitle(newFormTitle); + }; + + const addFormField = () => { + const newFormField: FormField = { + id: formFieldId, + title: formFieldTitle, + required: false, + type: formFieldType, + enum: formFieldSelectOptions.split(','), + }; + + setFormFieldIdHasBeenUpdatedByUser(false); + setShowNewFormField(false); + setFormFields([...formFields, newFormField]); + }; + + const handleFormFieldTypeChange = (event: any) => { + setFormFieldType(event.srcElement.value); + + if (event.srcElement.value === 'select') { + setShowFormFieldSelectTextField(true); + } else { + setShowFormFieldSelectTextField(false); + } + }; + + const newFormFieldComponent = () => { + if (showNewFormField) { + return ( + <> + { + onFormFieldTitleChange(event.srcElement.value); + }} + /> + { + setFormFieldIdHasBeenUpdatedByUser(true); + setFormFieldId(event.srcElement.value); + }} + /> + + {showFormFieldSelectTextField ? ( + { + setFormFieldSelectOptions(event.srcElement.value); + }} + /> + ) : null} + + + ); + } + return null; + }; + + const formFieldArea = () => { + if (formFields.length > 0) { + return formFields.map((formField: FormField) => { + return

Form Field: {formField.id}

; + }); + } + return null; + }; + + const handleSaveCallback = (result: any) => { + console.log('result', result); + }; + + const uploadFile = (file: File) => { + const url = `/process-models/${modifiedProcessModelId}/files`; + const httpMethod = 'POST'; + const formData = new FormData(); + formData.append('file', file); + formData.append('fileName', file.name); + + HttpService.makeCallToBackend({ + path: url, + successCallback: handleSaveCallback, + httpMethod, + postBody: formData, + }); + }; + + const saveFile = () => { + const formJsonFileName = `${formId}-schema.json`; + const formUiJsonFileName = `${formId}-uischema.json`; + + uploadFile(new File([renderFormJson()], formJsonFileName)); + uploadFile(new File([renderFormUiJson()], formUiJsonFileName)); + }; + + const jsonFormArea = () => { + return ( + <> + + { + onFormTitleChange(event.srcElement.value); + }} + /> + { + setFormIdHasBeenUpdatedByUser(true); + setFormId(event.srcElement.value); + }} + /> + { + setFormDescription(event.srcElement.value); + }} + /> + + {formFieldArea()} + {newFormFieldComponent()} + + ); + }; + + return <>{jsonFormArea()}; +} diff --git a/src/routes/MessageInstanceList.tsx b/src/routes/MessageInstanceList.tsx index 89bd6ac97..3ead54625 100644 --- a/src/routes/MessageInstanceList.tsx +++ b/src/routes/MessageInstanceList.tsx @@ -5,7 +5,7 @@ import { Link, useParams, useSearchParams } from 'react-router-dom'; import PaginationForTable from '../components/PaginationForTable'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import { - convertSecondsToFormattedDate, + convertSecondsToFormattedDateString, getPageInfoFromSearchParams, modifyProcessModelPath, unModifyProcessModelPath, @@ -65,10 +65,12 @@ export default function MessageInstanceList() { {rowToUse.message_identifier} {rowToUse.message_type} - {rowToUse.failure_cause} + {rowToUse.failure_cause || '-'} {rowToUse.status} - {convertSecondsToFormattedDate(rowToUse.created_at_in_seconds)} + {convertSecondsToFormattedDateString( + rowToUse.created_at_in_seconds + )} ); @@ -94,14 +96,8 @@ export default function MessageInstanceList() { if (pagination) { const { page, perPage } = getPageInfoFromSearchParams(searchParams); - let queryParamString = ''; let breadcrumbElement = null; if (searchParams.get('process_instance_id')) { - queryParamString += `&process_group_id=${searchParams.get( - 'process_group_id' - )}&process_model_id=${searchParams.get( - 'process_model_id' - )}&process_instance_id=${searchParams.get('process_instance_id')}`; breadcrumbElement = ( ); diff --git a/src/routes/HomePage.tsx b/src/routes/MyTasks.tsx similarity index 86% rename from src/routes/HomePage.tsx rename to src/routes/MyTasks.tsx index 71fda73fd..c59c49f59 100644 --- a/src/routes/HomePage.tsx +++ b/src/routes/MyTasks.tsx @@ -6,30 +6,38 @@ import PaginationForTable from '../components/PaginationForTable'; import { getPageInfoFromSearchParams, modifyProcessModelPath, + refreshAtInterval, } from '../helpers'; import HttpService from '../services/HttpService'; import { PaginationObject, RecentProcessModel } from '../interfaces'; const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5; +const REFRESH_INTERVAL = 10; +const REFRESH_TIMEOUT = 600; -export default function HomePage() { +export default function MyTasks() { const [searchParams] = useSearchParams(); const [tasks, setTasks] = useState([]); const [pagination, setPagination] = useState(null); useEffect(() => { - const { page, perPage } = getPageInfoFromSearchParams( - searchParams, - PER_PAGE_FOR_TASKS_ON_HOME_PAGE - ); - const setTasksFromResult = (result: any) => { - setTasks(result.results); - setPagination(result.pagination); + const getTasks = () => { + const { page, perPage } = getPageInfoFromSearchParams( + searchParams, + PER_PAGE_FOR_TASKS_ON_HOME_PAGE + ); + const setTasksFromResult = (result: any) => { + setTasks(result.results); + setPagination(result.pagination); + }; + HttpService.makeCallToBackend({ + path: `/tasks?per_page=${perPage}&page=${page}`, + successCallback: setTasksFromResult, + }); }; - HttpService.makeCallToBackend({ - path: `/tasks?per_page=${perPage}&page=${page}`, - successCallback: setTasksFromResult, - }); + + getTasks(); + refreshAtInterval(REFRESH_INTERVAL, REFRESH_TIMEOUT, getTasks); }, [searchParams]); let recentProcessModels: RecentProcessModel[] = []; @@ -122,7 +130,7 @@ export default function HomePage() { }); return ( <> -

Processes I can start

+

Recently viewed process models

@@ -152,7 +160,6 @@ export default function HomePage() { perPageOptions={[2, PER_PAGE_FOR_TASKS_ON_HOME_PAGE, 25]} pagination={pagination} tableToDisplay={buildTable()} - path="/tasks" /> ); @@ -170,6 +177,7 @@ export default function HomePage() { return ( <> {tasksWaitingForMe} +
{relevantProcessModelSection} ); diff --git a/src/routes/ProcessGroupList.tsx b/src/routes/ProcessGroupList.tsx index e84ec5369..4c448f086 100644 --- a/src/routes/ProcessGroupList.tsx +++ b/src/routes/ProcessGroupList.tsx @@ -1,42 +1,34 @@ import { useEffect, useState } from 'react'; -import { Link, useNavigate, useSearchParams } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import { Button, - Table, - // ExpandableTile, - // TileAboveTheFoldContent, - // TileBelowTheFoldContent, - // TextInput, - // ClickableTile, // @ts-ignore } from '@carbon/react'; +import { Can } from '@casl/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; -import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; -import { - getPageInfoFromSearchParams, - modifyProcessModelPath, -} from '../helpers'; -import { CarbonComboBoxSelection, ProcessGroup } from '../interfaces'; +import { modifyProcessModelPath } from '../helpers'; +import { CarbonComboBoxSelection, PermissionsToCheck } from '../interfaces'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; +import { usePermissionFetcher } from '../hooks/PermissionService'; import ProcessModelSearch from '../components/ProcessModelSearch'; +import ProcessGroupListTiles from '../components/ProcessGroupListTiles'; -// Example process group json -// {'process_group_id': 'sure', 'display_name': 'Test Workflows', 'id': 'test_process_group'} export default function ProcessGroupList() { - const navigate = useNavigate(); const [searchParams] = useSearchParams(); + const navigate = useNavigate(); - const [processGroups, setProcessGroups] = useState([]); - const [pagination, setPagination] = useState(null); const [processModelAvailableItems, setProcessModelAvailableItems] = useState( [] ); + const { targetUris } = useUriListForPermissions(); + const permissionRequestData: PermissionsToCheck = { + [targetUris.processGroupListPath]: ['POST'], + }; + const { ability } = usePermissionFetcher(permissionRequestData); + useEffect(() => { - const setProcessGroupsFromResult = (result: any) => { - setProcessGroups(result.results); - setPagination(result.pagination); - }; const processResultForProcessModels = (result: any) => { const selectionArray = result.results.map((item: any) => { const label = `${item.id}`; @@ -45,13 +37,6 @@ export default function ProcessGroupList() { }); setProcessModelAvailableItems(selectionArray); }; - - const { page, perPage } = getPageInfoFromSearchParams(searchParams); - // for browsing - HttpService.makeCallToBackend({ - path: `/process-groups?per_page=${perPage}&page=${page}`, - successCallback: setProcessGroupsFromResult, - }); // for search box HttpService.makeCallToBackend({ path: `/process-models?per_page=1000`, @@ -59,66 +44,6 @@ export default function ProcessGroupList() { }); }, [searchParams]); - const buildTable = () => { - const rows = processGroups.map((row: ProcessGroup) => { - return ( - - - - ); - }); - return ( -
- - {(row as any).display_name} - -
- - - - - - {rows} -
Process Group
- ); - // const rows = processGroups.map((row: ProcessGroup) => { - // return ( - // - // - // {row.display_name} - // - // - // ); - // }); - // - // return
{rows}
; - }; - - const processGroupsDisplayArea = () => { - const { page, perPage } = getPageInfoFromSearchParams(searchParams); - let displayText = null; - if (processGroups?.length > 0) { - displayText = ( - <> -

Browse

- - - ); - } else { - displayText =

No Groups To Display

; - } - return displayText; - }; - const processModelSearchArea = () => { const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => { const processModel = selection.selectedItem; @@ -135,18 +60,21 @@ export default function ProcessGroupList() { ); }; - if (pagination) { + if (processModelAvailableItems) { return ( <> - -
+ + +
+
+

{processModelSearchArea()}
- {processGroupsDisplayArea()} + ); } diff --git a/src/routes/ProcessGroupShow.tsx b/src/routes/ProcessGroupShow.tsx index 57da58e72..3d6a0ee4f 100644 --- a/src/routes/ProcessGroupShow.tsx +++ b/src/routes/ProcessGroupShow.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { Link, useSearchParams, useParams } from 'react-router-dom'; // @ts-ignore import { Button, Table, Stack } from '@carbon/react'; +import { Can } from '@casl/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import PaginationForTable from '../components/PaginationForTable'; import HttpService from '../services/HttpService'; @@ -10,7 +11,15 @@ import { modifyProcessModelPath, unModifyProcessModelPath, } from '../helpers'; -import { ProcessGroup, ProcessModel } from '../interfaces'; +import { + PaginationObject, + PermissionsToCheck, + ProcessGroup, + ProcessModel, +} from '../interfaces'; +import { useUriListForPermissions } from '../hooks/UriListForPermissions'; +import { usePermissionFetcher } from '../hooks/PermissionService'; +import ProcessGroupListTiles from '../components/ProcessGroupListTiles'; export default function ProcessGroupShow() { const params = useParams(); @@ -18,9 +27,16 @@ export default function ProcessGroupShow() { const [processGroup, setProcessGroup] = useState(null); const [processModels, setProcessModels] = useState([]); - const [processGroups, setProcessGroups] = useState([]); - const [modelPagination, setModelPagination] = useState(null); - const [groupPagination, setGroupPagination] = useState(null); + const [modelPagination, setModelPagination] = + useState(null); + + const { targetUris } = useUriListForPermissions(); + const permissionRequestData: PermissionsToCheck = { + [targetUris.processGroupListPath]: ['POST'], + [targetUris.processGroupShowPath]: ['PUT'], + [targetUris.processModelCreatePath]: ['POST'], + }; + const { ability } = usePermissionFetcher(permissionRequestData); useEffect(() => { const { page, perPage } = getPageInfoFromSearchParams(searchParams); @@ -29,10 +45,6 @@ export default function ProcessGroupShow() { setProcessModels(result.results); setModelPagination(result.pagination); }; - const setProcessGroupFromResult = (result: any) => { - setProcessGroups(result.results); - setGroupPagination(result.pagination); - }; const processResult = (result: any) => { setProcessGroup(result); const unmodifiedProcessGroupId = unModifyProcessModelPath( @@ -42,10 +54,6 @@ export default function ProcessGroupShow() { path: `/process-models?process_group_identifier=${unmodifiedProcessGroupId}&per_page=${perPage}&page=${page}`, successCallback: setProcessModelFromResult, }); - HttpService.makeCallToBackend({ - path: `/process-groups?process_group_identifier=${unmodifiedProcessGroupId}&per_page=${perPage}&page=${page}`, - successCallback: setProcessGroupFromResult, - }); }; HttpService.makeCallToBackend({ path: `/process-groups/${params.process_group_id}`, @@ -58,7 +66,9 @@ export default function ProcessGroupShow() { return null; } const rows = processModels.map((row: ProcessModel) => { - const modifiedProcessModelId: String = modifyProcessModelPath((row as any).id); + const modifiedProcessModelId: String = modifyProcessModelPath( + (row as any).id + ); return ( @@ -75,7 +85,7 @@ export default function ProcessGroupShow() { }); return (
-

Process Models

+

Process Models

@@ -89,43 +99,7 @@ export default function ProcessGroupShow() { ); }; - const buildGroupTable = () => { - if (processGroup === null) { - return null; - } - const rows = processGroups.map((row: ProcessGroup) => { - const modifiedProcessGroupId: String = modifyProcessModelPath(row.id); - return ( - - - - - ); - }); - return ( -
-

Process Groups

-
- - {row.id} - - {row.display_name}
- - - - - - - {rows} -
Process Group IdDisplay Name
-
- ); - }; - - if (processGroup && groupPagination && modelPagination) { + if (processGroup && modelPagination) { const { page, perPage } = getPageInfoFromSearchParams(searchParams); const modifiedProcessGroupId = modifyProcessModelPath(processGroup.id); return ( @@ -136,43 +110,51 @@ export default function ProcessGroupShow() { ['', `process_group:${processGroup.id}`], ]} /> +

Process Group: {processGroup.display_name}

    - + + - Add a process group - - - + + + + +

    - + {/* eslint-disable-next-line sonarjs/no-gratuitous-expressions */} + {modelPagination && modelPagination.total > 0 && ( + + )}

    - Process Groups} />
diff --git a/src/routes/ProcessInstanceList.tsx b/src/routes/ProcessInstanceList.tsx index b7c057344..b6c08b213 100644 --- a/src/routes/ProcessInstanceList.tsx +++ b/src/routes/ProcessInstanceList.tsx @@ -1,477 +1,15 @@ -import { useContext, useEffect, useMemo, useState } from 'react'; -import { - Link, - useNavigate, - useParams, - useSearchParams, -} from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom'; -// @ts-ignore -import { Filter } from '@carbon/icons-react'; -import { - Button, - ButtonSet, - DatePicker, - DatePickerInput, - Table, - Grid, - Column, - MultiSelect, - TableHeader, - TableHead, - TableRow, - // @ts-ignore -} from '@carbon/react'; -import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config'; -import { - convertDateStringToSeconds, - convertSecondsToFormattedDate, - getPageInfoFromSearchParams, - getProcessModelFullIdentifierFromSearchParams, - modifyProcessModelPath, -} from '../helpers'; - -import PaginationForTable from '../components/PaginationForTable'; import 'react-datepicker/dist/react-datepicker.css'; -import ErrorContext from '../contexts/ErrorContext'; -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'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; +import ProcessInstanceListTable from '../components/ProcessInstanceListTable'; +import { getProcessModelFullIdentifierFromSearchParams } from '../helpers'; export default function ProcessInstanceList() { - const params = useParams(); const [searchParams] = useSearchParams(); - const navigate = useNavigate(); - - const [processInstances, setProcessInstances] = useState([]); - const [reportMetadata, setReportMetadata] = useState({}); - const [pagination, setPagination] = useState(null); - - const oneHourInSeconds = 3600; - const oneMonthInSeconds = oneHourInSeconds * 24 * 30; - const [startFrom, setStartFrom] = useState(''); - const [startTo, setStartTo] = useState(''); - const [endFrom, setEndFrom] = useState(''); - const [endTo, setEndTo] = useState(''); - const [showFilterOptions, setShowFilterOptions] = useState(false); - - const setErrorMessage = (useContext as any)(ErrorContext)[1]; - - const [processStatusAllOptions, setProcessStatusAllOptions] = useState( - [] - ); - const [processStatusSelection, setProcessStatusSelection] = useState< - string[] - >([]); - const [processModelAvailableItems, setProcessModelAvailableItems] = useState< - ProcessModel[] - >([]); - const [processModelSelection, setProcessModelSelection] = - useState(null); - - const parametersToAlwaysFilterBy = useMemo(() => { - return { - start_from: setStartFrom, - start_to: setStartTo, - end_from: setEndFrom, - end_to: setEndTo, - }; - }, [setStartFrom, setStartTo, setEndFrom, setEndTo]); - - const parametersToGetFromSearchParams = useMemo(() => { - return { - process_model_identifier: null, - process_status: null, - }; - }, []); - - // eslint-disable-next-line sonarjs/cognitive-complexity - useEffect(() => { - function setProcessInstancesFromResult(result: any) { - const processInstancesFromApi = result.results; - setProcessInstances(processInstancesFromApi); - setReportMetadata(result.report_metadata); - setPagination(result.pagination); - } - function getProcessInstances() { - const { page, perPage } = getPageInfoFromSearchParams(searchParams); - let queryParamString = `per_page=${perPage}&page=${page}`; - - Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => { - // @ts-expect-error TS(7053) FIXME: - const functionToCall = parametersToAlwaysFilterBy[paramName]; - const searchParamValue = searchParams.get(paramName); - if (searchParamValue) { - queryParamString += `&${paramName}=${searchParamValue}`; - const dateString = convertSecondsToFormattedDate( - searchParamValue as any - ); - functionToCall(dateString); - setShowFilterOptions(true); - } - }); - - Object.keys(parametersToGetFromSearchParams).forEach( - (paramName: string) => { - if (searchParams.get(paramName)) { - // @ts-expect-error TS(7053) FIXME: - const functionToCall = parametersToGetFromSearchParams[paramName]; - queryParamString += `&${paramName}=${searchParams.get(paramName)}`; - if (functionToCall !== null) { - functionToCall(searchParams.get(paramName) || ''); - } - setShowFilterOptions(true); - } - } - ); - HttpService.makeCallToBackend({ - path: `/process-instances?${queryParamString}`, - successCallback: setProcessInstancesFromResult, - }); - } - function processResultForProcessModels(result: any) { - const processModelFullIdentifier = - getProcessModelFullIdentifierFromSearchParams(searchParams); - const selectionArray = result.results.map((item: any) => { - const label = `${item.id}`; - Object.assign(item, { label }); - if (label === processModelFullIdentifier) { - setProcessModelSelection(item); - } - return item; - }); - setProcessModelAvailableItems(selectionArray); - - 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(processStatusOption); - } - return processStatusOption; - } - ); - setProcessStatusSelection(processStatusSelectedArray); - setProcessStatusAllOptions(processStatusAllOptionsArray); - - getProcessInstances(); - } - - // populate process model selection - HttpService.makeCallToBackend({ - path: `/process-models?per_page=1000`, - successCallback: processResultForProcessModels, - }); - }, [ - searchParams, - params, - oneMonthInSeconds, - oneHourInSeconds, - parametersToAlwaysFilterBy, - parametersToGetFromSearchParams, - ]); - - // does the comparison, but also returns false if either argument - // is not truthy and therefore not comparable. - const isTrueComparison = (param1: any, operation: any, param2: any) => { - if (param1 && param2) { - switch (operation) { - case '<': - return param1 < param2; - case '>': - return param1 > param2; - default: - return false; - } - } else { - return false; - } - }; - - const applyFilter = (event: any) => { - event.preventDefault(); - const { page, perPage } = getPageInfoFromSearchParams(searchParams); - let queryParamString = `per_page=${perPage}&page=${page}`; - - 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(endFromSeconds, '>', endToSeconds)) { - setErrorMessage({ - message: '"End date from" cannot be after "end date to"', - }); - return; - } - if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) { - setErrorMessage({ - message: '"Start date from" cannot be after "end date from"', - }); - return; - } - if (isTrueComparison(startToSeconds, '>', endToSeconds)) { - setErrorMessage({ - message: '"Start date to" cannot be after "end date to"', - }); - return; - } - - if (startFromSeconds) { - queryParamString += `&start_from=${startFromSeconds}`; - } - if (startToSeconds) { - queryParamString += `&start_to=${startToSeconds}`; - } - if (endFromSeconds) { - queryParamString += `&end_from=${endFromSeconds}`; - } - if (endToSeconds) { - queryParamString += `&end_to=${endToSeconds}`; - } - if (processStatusSelection.length > 0) { - queryParamString += `&process_status=${processStatusSelection}`; - } - - if (processModelSelection) { - queryParamString += `&process_model_identifier=${processModelSelection.id}`; - } - - setErrorMessage(null); - navigate(`/admin/process-instances?${queryParamString}`); - }; - - const dateComponent = ( - labelString: any, - name: any, - initialDate: any, - onChangeFunction: any - ) => { - return ( - - { - onChangeFunction(dateChangeEvent.srcElement.value); - }} - value={initialDate} - /> - - ); - }; - - const getSearchParamsAsQueryString = () => { - let queryParamString = ''; - Object.keys(parametersToAlwaysFilterBy).forEach((paramName) => { - const searchParamValue = searchParams.get(paramName); - if (searchParamValue) { - queryParamString += `&${paramName}=${searchParamValue}`; - } - }); - - Object.keys(parametersToGetFromSearchParams).forEach( - (paramName: string) => { - if (searchParams.get(paramName)) { - queryParamString += `&${paramName}=${searchParams.get(paramName)}`; - } - } - ); - return queryParamString; - }; - - const processStatusSearch = () => { - return ( - { - setProcessStatusSelection(selection.selectedItems); - }} - itemToString={(item: any) => { - return item || ''; - }} - selectionFeedback="top-after-reopen" - selectedItems={processStatusSelection} - /> - ); - }; - - const clearFilters = () => { - setProcessModelSelection(null); - setProcessStatusSelection([]); - setStartFrom(''); - setStartTo(''); - setEndFrom(''); - setEndTo(''); - }; - - const filterOptions = () => { - if (!showFilterOptions) { - return null; - } - return ( - <> - - - - setProcessModelSelection(selection.selectedItem) - } - processModels={processModelAvailableItems} - selectedItem={processModelSelection} - /> - - {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)} - - - - - - - - - - - - ); - }; - - const buildTable = () => { - const headerLabels: Record = { - id: 'Process Instance Id', - process_model_identifier: 'Process Model', - start_in_seconds: 'Start Time', - end_in_seconds: 'End Time', - status: 'Status', - spiff_step: 'SpiffWorkflow Step', - }; - const getHeaderLabel = (header: string) => { - return headerLabels[header] ?? header; - }; - const headers = (reportMetadata as any).columns.map((column: any) => { - // return {getHeaderLabel((column as any).Header)}; - return getHeaderLabel((column as any).Header); - }); - - const formatProcessInstanceId = (row: any, id: any) => { - const modifiedProcessModelId: String = modifyProcessModelPath( - row.process_model_identifier - ); - return ( - - {id} - - ); - }; - const formatProcessModelIdentifier = (_row: any, identifier: any) => { - return ( - - {identifier} - - ); - }; - const formatSecondsForDisplay = (_row: any, seconds: any) => { - return convertSecondsToFormattedDate(seconds) || '-'; - }; - const defaultFormatter = (_row: any, value: any) => { - return value; - }; - - const columnFormatters: Record = { - id: formatProcessInstanceId, - process_model_identifier: formatProcessModelIdentifier, - start_in_seconds: formatSecondsForDisplay, - end_in_seconds: formatSecondsForDisplay, - }; - const formattedColumn = (row: any, column: any) => { - const formatter = columnFormatters[column.accessor] ?? defaultFormatter; - const value = row[column.accessor]; - if (column.accessor === 'status') { - return ( - - {formatter(row, value)} - - ); - } - return {formatter(row, value)}; - }; - - const rows = processInstances.map((row: any) => { - const currentRow = (reportMetadata as any).columns.map((column: any) => { - return formattedColumn(row, column); - }); - return {currentRow}; - }); - - return ( - - - - {headers.map((header: any) => ( - {header} - ))} - - - {rows} -
- ); - }; - const processInstanceBreadcrumbElement = () => { const processModelFullIdentifier = getProcessModelFullIdentifierFromSearchParams(searchParams); @@ -496,47 +34,11 @@ export default function ProcessInstanceList() { const processInstanceTitleElement = () => { return

Process Instances

; }; - - const toggleShowFilterOptions = () => { - setShowFilterOptions(!showFilterOptions); - }; - - if (pagination) { - const { page, perPage } = getPageInfoFromSearchParams(searchParams); - return ( - <> - {processInstanceBreadcrumbElement()} - {processInstanceTitleElement()} - - - ); @@ -61,7 +61,7 @@ export default function ProcessInstanceReportList() { return (
{headerStuff} -

No reports found

+

No perspectives found

); } diff --git a/src/routes/ProcessInstanceReportNew.tsx b/src/routes/ProcessInstanceReportNew.tsx index 124be4daf..eb6d2a67f 100644 --- a/src/routes/ProcessInstanceReportNew.tsx +++ b/src/routes/ProcessInstanceReportNew.tsx @@ -56,7 +56,7 @@ export default function ProcessInstanceReportNew() { return ( <> -

Add Process Model

+

Add Process Instance Perspective