diff --git a/config/webpack.plugins.js b/config/webpack.plugins.js index 74c8324bc..0d63a21b6 100644 --- a/config/webpack.plugins.js +++ b/config/webpack.plugins.js @@ -76,6 +76,14 @@ const plugins = (dev = false, beta = false) => { Buffer: ['buffer', 'Buffer'], }), new ForkTsCheckerWebpackPlugin(), + /** + * Removes error for a missing logger function + * https://github.com/getsentry/sentry-javascript/issues/6596 + * https://docs.sentry.io/platforms/javascript/guides/react/configuration/tree-shaking/#tree-shaking-optional-code + */ + new webpack.DefinePlugin({ + __SENTRY_DEBUG__: false, + }), ...(dev ? [new ReactRefreshWebpackPlugin()] : []), ]; }; diff --git a/cypress/e2e/release-gate/favorite-services.cy.tsx b/cypress/e2e/release-gate/favorite-services.cy.tsx index 62559c286..c409bbb52 100644 --- a/cypress/e2e/release-gate/favorite-services.cy.tsx +++ b/cypress/e2e/release-gate/favorite-services.cy.tsx @@ -132,6 +132,6 @@ describe('Favorite-services', () => { } }); cy.wait(2000); - cy.get('.chr-c-favorite-service__tile').find('.pf-v5-u-mb-sm').should('contain', serviceName); + cy.get('.chr-c-favorite-service__tile').find('.pf-v5-u-pb-0').should('contain', serviceName); }); }); diff --git a/package-lock.json b/package-lock.json index e4e5807a0..f7b3c8e94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,18 +14,18 @@ "@data-driven-forms/react-form-renderer": "^3.20.2", "@formatjs/cli": "4.8.4", "@openshift/dynamic-plugin-sdk": "^3.0.0", - "@patternfly/patternfly": "^5.0.0", + "@patternfly/patternfly": "^5.0.4", "@patternfly/quickstarts": "^5.0.0", "@patternfly/react-charts": "^7.0.0", - "@patternfly/react-core": "^5.0.0", - "@patternfly/react-icons": "^5.0.0", - "@patternfly/react-tokens": "^5.0.0", + "@patternfly/react-core": "^5.0.1", + "@patternfly/react-icons": "^5.0.1", + "@patternfly/react-tokens": "^5.0.1", "@redhat-cloud-services/chrome": "^0.0.11", "@redhat-cloud-services/entitlements-client": "1.2.0", - "@redhat-cloud-services/frontend-components": "4.0.0-beta.3", - "@redhat-cloud-services/frontend-components-notifications": "4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-pdf-generator": "4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-utilities": "4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.10", + "@redhat-cloud-services/frontend-components-notifications": "^4.0.2", + "@redhat-cloud-services/frontend-components-pdf-generator": "4.0.1", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.1", "@redhat-cloud-services/host-inventory-client": "1.2.0", "@redhat-cloud-services/rbac-client": "1.2.0", "@scalprum/core": "0.5.1", @@ -65,7 +65,7 @@ "@openshift/dynamic-plugin-sdk-webpack": "^3.0.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.2.6", - "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.0-beta.0", + "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.2", "@redhat-cloud-services/types": "^0.0.22", "@simonsmith/cypress-image-snapshot": "^6.0.1", "@swc/core": "^1.3.76", @@ -126,7 +126,7 @@ "swc-loader": "^0.2.3", "terser-webpack-plugin": "^5.3.6", "typescript": "^4.9.5", - "url": "^0.11.0", + "url": "^0.11.3", "utility-types": "^3.10.0", "wait-on": "^7.0.1", "webpack": "^5.76.1", @@ -865,6 +865,19 @@ "node": ">=10.0.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz", + "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==", + "dependencies": { + "@emotion/memoize": "0.7.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz", + "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2739,9 +2752,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@patternfly/patternfly": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz", - "integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz", + "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA==" }, "node_modules/@patternfly/quickstarts": { "version": "5.0.0", @@ -2806,14 +2819,28 @@ "react-dom": "^17 || ^18" } }, - "node_modules/@patternfly/react-core": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.0.tgz", - "integrity": "sha512-kewRVFhLw0Dvt8250pqrO47sVRx8E93sMGZbHQomJnZdachYeQ9STnQTP2gvOBq/GPnMei0LZLv0T99g8mPE4w==", + "node_modules/@patternfly/react-component-groups": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@patternfly/react-component-groups/-/react-component-groups-1.0.17.tgz", + "integrity": "sha512-SeTnlmEyk9q/TxnLs2WCNuEhpD9iKdgArW+OnW6O/rm/VDtPAeJ7O+SYT0JeZDqtNzMvAb9D02GE06k+5urchQ==", "dependencies": { + "@patternfly/react-core": "^5.0.0", "@patternfly/react-icons": "^5.0.0", - "@patternfly/react-styles": "^5.0.0", - "@patternfly/react-tokens": "^5.0.0", + "react-jss": "^10.9.2" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, + "node_modules/@patternfly/react-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz", + "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==", + "dependencies": { + "@patternfly/react-icons": "^5.0.1", + "@patternfly/react-styles": "^5.0.1", + "@patternfly/react-tokens": "^5.0.1", "focus-trap": "7.4.3", "react-dropzone": "^14.2.3", "tslib": "^2.5.0" @@ -2824,18 +2851,18 @@ } }, "node_modules/@patternfly/react-icons": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.0.tgz", - "integrity": "sha512-GG5Y/UYl0h346MyDU9U650Csaq4Mxk8S6U8XC7ERk/xIrRr2RF67O2uY7zKBDMTNLYdBvPzgc2s3OMV1+d2/mg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz", + "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==", "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" } }, "node_modules/@patternfly/react-styles": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.0.tgz", - "integrity": "sha512-xbSCgjx+fPrXbIzUznwTFWtJEbzVS0Wn4zrejdKJYQTY+4YcuPlFkeq2tl3syzwGsaYMpHiFwQiTaKyTvlwtuw==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz", + "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w==" }, "node_modules/@patternfly/react-table": { "version": "5.0.0", @@ -2856,9 +2883,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.0.tgz", - "integrity": "sha512-to2CXIZ6WTuzBcjLZ+nXi5LhnYkSIDu3RBMRZwrplmECOoUWv87CC+2T0EVxtASRtpQfikjD2PDKMsif5i0BxQ==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz", + "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw==" }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", @@ -3026,11 +3053,12 @@ } }, "node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.0-beta.3.tgz", - "integrity": "sha512-+xU2FG2/NufxomDF98w3es+4HLvS1VeQ63KuBFPNm7/0HIJi5k57EMXOu3hYvhr2Hx5r1F6wdXLvgbAfskC3gw==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.10.tgz", + "integrity": "sha512-xYgHwtpkPYXXByMizbraIm+M9WXS65FDwA4wIJq/hzOAiVv4WtORVCRn3Ysul3wAKlXLB9Q+M6kzxXXcbc+v4g==", "dependencies": { - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", + "@patternfly/react-component-groups": "^1.0.17", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", "@redhat-cloud-services/types": "^0.0.24", "@scalprum/core": "^0.5.1", "@scalprum/react-core": "^0.5.1", @@ -3051,9 +3079,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components-config-utilities": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config-utilities/-/frontend-components-config-utilities-3.0.0-beta.0.tgz", - "integrity": "sha512-J+TMwVYwkw2025yUtvdbqoyhlShp0Ien49PmK4X6vfDsPQmYxf7MVnBuj4+MhaNbDOJO0FBVjM5iuPSIhORDUg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config-utilities/-/frontend-components-config-utilities-3.0.2.tgz", + "integrity": "sha512-GIF9AsatDIwysnO/Fvhnm2mPGyaHQMxCPmteLzKV5xS7ubBTB/eV/f24sGDKiyAkYGkFBPkWqUCYYEPLmnhj9A==", "dev": true, "dependencies": { "@openshift/dynamic-plugin-sdk-webpack": "^3.0.0", @@ -3135,28 +3163,28 @@ } }, "node_modules/@redhat-cloud-services/frontend-components-notifications": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-4.0.0-beta.0.tgz", - "integrity": "sha512-3zUKknmBNl94TjxtH7r5tau3ANpl3/KPyUwObPKE456+g3FRxiyVQUeqFGMYkPaK0E0QI7zpIvH/HDlBZiJNnA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-4.0.2.tgz", + "integrity": "sha512-xivlLFmlAhn+WNwaKuHXXQhSeVW+EkuApAErhvYanC5SZ32H9cIzp4aF61ZoLv7A1pjTSu/QcZ+BxvfTKCNrUQ==", "dependencies": { - "@redhat-cloud-services/frontend-components": "^4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.0", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", "redux-promise-middleware": "6.1.3" }, "peerDependencies": { "@patternfly/react-core": "^5.0.0", "@patternfly/react-icons": "^5.0.0", "prop-types": "^15.6.2", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-redux": ">=7.2.9", "redux": ">=4.2.0" } }, "node_modules/@redhat-cloud-services/frontend-components-pdf-generator": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-pdf-generator/-/frontend-components-pdf-generator-4.0.0-beta.0.tgz", - "integrity": "sha512-ykEu0tWtPocRs8zsIWRXTujOiamczd/3MDbCHRtbnIumwO4Ezn0oSoEYHYTm6m4yPCXJ0d5hi1qeTAljIuMtDA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-pdf-generator/-/frontend-components-pdf-generator-4.0.1.tgz", + "integrity": "sha512-FL8gDEGgs9xqtO0bcqLhtOzvmQa9b9JUg8ijrmojrxP8/PDVOl+yUQs34S9+mMIBaZb8RxwRtN85Slj3SKNYGA==", "dependencies": { "@patternfly/react-charts": "6.3.9", "@patternfly/react-core": "^5.0.0", @@ -3164,7 +3192,7 @@ "@patternfly/react-styles": "^5.0.0", "@patternfly/react-tokens": "^5.0.0", "@react-pdf/renderer": "^1.6.8", - "@redhat-cloud-services/frontend-components": "4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.0", "@scalprum/react-core": "^0.5.1", "react": "16.12.0", "react-dom": "16.12.0", @@ -3247,36 +3275,6 @@ "react": "^16.0.0 || ^17.0.0" } }, - "node_modules/@redhat-cloud-services/frontend-components-pdf-generator/node_modules/@redhat-cloud-services/frontend-components": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.0-beta.0.tgz", - "integrity": "sha512-H8uCZ3yI2M/Q+et9B8r6xAxzkxfjnfrfHAZ1se4I2ErGwHSgybN9+6qwoD1QNhtS8sNJXNtgue3G5qQuVebQKw==", - "dependencies": { - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", - "@redhat-cloud-services/types": "^0.0.24", - "@scalprum/core": "^0.5.1", - "@scalprum/react-core": "^0.5.1", - "sanitize-html": "^2.7.2" - }, - "peerDependencies": { - "@patternfly/react-core": "^5.0.0", - "@patternfly/react-icons": "^5.0.0", - "@patternfly/react-table": "^5.0.0", - "classnames": "^2.2.5", - "lodash": "^4.17.15", - "prop-types": "^15.6.2", - "react": "^18.0.0", - "react-content-loader": "^6.2.0", - "react-dom": "^18.0.0", - "react-redux": ">=7.0.0", - "react-router-dom": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/@redhat-cloud-services/frontend-components-pdf-generator/node_modules/@redhat-cloud-services/types": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-0.0.24.tgz", - "integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg==" - }, "node_modules/@redhat-cloud-services/frontend-components-pdf-generator/node_modules/d3-array": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", @@ -3656,9 +3654,9 @@ } }, "node_modules/@redhat-cloud-services/frontend-components-utilities": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.0-beta.0.tgz", - "integrity": "sha512-vM2ijQuSqCSQVopu+P2NAfeBScJGADZbo3cjX9AmD01cdOxA0DPvTL+04WvOVZCdYwBgw85MyOy9hNiVBPrwVQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.1.tgz", + "integrity": "sha512-ZoykyuNV944SXYbG2LnFeyQMOof1y8RqRM9K7T7AzC8n0D/C+NjVxDCoFD94mfs2WDEicWu+lNdV+xhF8Eg2TA==", "dependencies": { "@redhat-cloud-services/types": "^0.0.24", "@sentry/browser": "^5.30.0", @@ -3673,8 +3671,8 @@ "@patternfly/react-table": "^5.0.0", "@redhat-cloud-services/rbac-client": "^1.0.100", "cypress": ">=12.0.0 < 13.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-redux": ">=7.0.0", "react-router-dom": "^5.0.0 || ^6.0.0" } @@ -10925,6 +10923,16 @@ "node": ">= 8" } }, + "node_modules/css-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.10.0.tgz", + "integrity": "sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0" + } + }, "node_modules/css-loader": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", @@ -11117,6 +11125,15 @@ "node": ">=0.10.0" } }, + "node_modules/css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -14613,6 +14630,11 @@ "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.6.6.tgz", "integrity": "sha512-XtqmnT+b9n5MX+MsqluFAVTIenbtC25iskW0Z+jLd+awfhA+ZbWKWQMIvLJccGoa2bM1R6juWJ27cZxIFOmkWw==" }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -15138,6 +15160,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -18910,6 +18937,158 @@ "verror": "1.10.0" } }, + "node_modules/jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/jss" + } + }, + "node_modules/jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-compose": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.10.0.tgz", + "integrity": "sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-expand": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.10.0.tgz", + "integrity": "sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-extend": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.10.0.tgz", + "integrity": "sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-rule-value-observable": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.10.0.tgz", + "integrity": "sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "symbol-observable": "^1.2.0" + } + }, + "node_modules/jss-plugin-template": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.10.0.tgz", + "integrity": "sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "node_modules/jss-preset-default": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.10.0.tgz", + "integrity": "sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "jss-plugin-camel-case": "10.10.0", + "jss-plugin-compose": "10.10.0", + "jss-plugin-default-unit": "10.10.0", + "jss-plugin-expand": "10.10.0", + "jss-plugin-extend": "10.10.0", + "jss-plugin-global": "10.10.0", + "jss-plugin-nested": "10.10.0", + "jss-plugin-props-sort": "10.10.0", + "jss-plugin-rule-value-function": "10.10.0", + "jss-plugin-rule-value-observable": "10.10.0", + "jss-plugin-template": "10.10.0", + "jss-plugin-vendor-prefixer": "10.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -22110,6 +22289,11 @@ "react": ">=16.0.0" } }, + "node_modules/react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -22240,6 +22424,27 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.10.0.tgz", + "integrity": "sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@emotion/is-prop-valid": "^0.7.3", + "css-jss": "10.10.0", + "hoist-non-react-statics": "^3.2.0", + "is-in-browser": "^1.1.3", + "jss": "10.10.0", + "jss-preset-default": "10.10.0", + "prop-types": "^15.6.0", + "shallow-equal": "^1.2.0", + "theming": "^3.3.0", + "tiny-warning": "^1.0.2" + }, + "peerDependencies": { + "react": ">=16.8.6" + } + }, "node_modules/react-redux": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", @@ -23436,6 +23641,11 @@ "node": ">=8" } }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -24302,6 +24512,14 @@ "webpack": ">=2" } }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -24479,6 +24697,23 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/theming": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz", + "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==", + "dependencies": { + "hoist-non-react-statics": "^3.3.0", + "prop-types": "^15.5.8", + "react-display-name": "^0.2.4", + "tiny-warning": "^1.0.2" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.3" + } + }, "node_modules/throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -24511,6 +24746,11 @@ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", @@ -24989,13 +25229,13 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, "node_modules/url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, "dependencies": { "punycode": "^1.4.1", - "qs": "^6.11.0" + "qs": "^6.11.2" } }, "node_modules/url-parse": { @@ -27789,6 +28029,19 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@emotion/is-prop-valid": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.7.3.tgz", + "integrity": "sha512-uxJqm/sqwXw3YPA5GXX365OBcJGFtxUVkB6WyezqFHlNe9jqUWH5ur2O2M8dGBz61kn1g3ZBlzUunFQXQIClhA==", + "requires": { + "@emotion/memoize": "0.7.1" + } + }, + "@emotion/memoize": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.1.tgz", + "integrity": "sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==" + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -29258,9 +29511,9 @@ } }, "@patternfly/patternfly": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.2.tgz", - "integrity": "sha512-PB8+MLdYVgF1hIOxGmnVsZG+YHUX3RePe5W1oMS4gS00EmSgw1cobr1Qbpy/BqqS8/R9DRN4hZ2FKDT0d5tkFQ==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz", + "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA==" }, "@patternfly/quickstarts": { "version": "5.0.0", @@ -29311,29 +29564,39 @@ "victory-zoom-container": "^36.6.11" } }, - "@patternfly/react-core": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.0.tgz", - "integrity": "sha512-kewRVFhLw0Dvt8250pqrO47sVRx8E93sMGZbHQomJnZdachYeQ9STnQTP2gvOBq/GPnMei0LZLv0T99g8mPE4w==", + "@patternfly/react-component-groups": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@patternfly/react-component-groups/-/react-component-groups-1.0.17.tgz", + "integrity": "sha512-SeTnlmEyk9q/TxnLs2WCNuEhpD9iKdgArW+OnW6O/rm/VDtPAeJ7O+SYT0JeZDqtNzMvAb9D02GE06k+5urchQ==", "requires": { + "@patternfly/react-core": "^5.0.0", "@patternfly/react-icons": "^5.0.0", - "@patternfly/react-styles": "^5.0.0", - "@patternfly/react-tokens": "^5.0.0", + "react-jss": "^10.9.2" + } + }, + "@patternfly/react-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz", + "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==", + "requires": { + "@patternfly/react-icons": "^5.0.1", + "@patternfly/react-styles": "^5.0.1", + "@patternfly/react-tokens": "^5.0.1", "focus-trap": "7.4.3", "react-dropzone": "^14.2.3", "tslib": "^2.5.0" } }, "@patternfly/react-icons": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.0.tgz", - "integrity": "sha512-GG5Y/UYl0h346MyDU9U650Csaq4Mxk8S6U8XC7ERk/xIrRr2RF67O2uY7zKBDMTNLYdBvPzgc2s3OMV1+d2/mg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz", + "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==", "requires": {} }, "@patternfly/react-styles": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.0.tgz", - "integrity": "sha512-xbSCgjx+fPrXbIzUznwTFWtJEbzVS0Wn4zrejdKJYQTY+4YcuPlFkeq2tl3syzwGsaYMpHiFwQiTaKyTvlwtuw==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz", + "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w==" }, "@patternfly/react-table": { "version": "5.0.0", @@ -29350,9 +29613,9 @@ } }, "@patternfly/react-tokens": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.0.tgz", - "integrity": "sha512-to2CXIZ6WTuzBcjLZ+nXi5LhnYkSIDu3RBMRZwrplmECOoUWv87CC+2T0EVxtASRtpQfikjD2PDKMsif5i0BxQ==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz", + "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw==" }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", @@ -29478,11 +29741,12 @@ } }, "@redhat-cloud-services/frontend-components": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.0-beta.3.tgz", - "integrity": "sha512-+xU2FG2/NufxomDF98w3es+4HLvS1VeQ63KuBFPNm7/0HIJi5k57EMXOu3hYvhr2Hx5r1F6wdXLvgbAfskC3gw==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.10.tgz", + "integrity": "sha512-xYgHwtpkPYXXByMizbraIm+M9WXS65FDwA4wIJq/hzOAiVv4WtORVCRn3Ysul3wAKlXLB9Q+M6kzxXXcbc+v4g==", "requires": { - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", + "@patternfly/react-component-groups": "^1.0.17", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", "@redhat-cloud-services/types": "^0.0.24", "@scalprum/core": "^0.5.1", "@scalprum/react-core": "^0.5.1", @@ -29497,9 +29761,9 @@ } }, "@redhat-cloud-services/frontend-components-config-utilities": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config-utilities/-/frontend-components-config-utilities-3.0.0-beta.0.tgz", - "integrity": "sha512-J+TMwVYwkw2025yUtvdbqoyhlShp0Ien49PmK4X6vfDsPQmYxf7MVnBuj4+MhaNbDOJO0FBVjM5iuPSIhORDUg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-config-utilities/-/frontend-components-config-utilities-3.0.2.tgz", + "integrity": "sha512-GIF9AsatDIwysnO/Fvhnm2mPGyaHQMxCPmteLzKV5xS7ubBTB/eV/f24sGDKiyAkYGkFBPkWqUCYYEPLmnhj9A==", "dev": true, "requires": { "@openshift/dynamic-plugin-sdk-webpack": "^3.0.0", @@ -29559,19 +29823,19 @@ } }, "@redhat-cloud-services/frontend-components-notifications": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-4.0.0-beta.0.tgz", - "integrity": "sha512-3zUKknmBNl94TjxtH7r5tau3ANpl3/KPyUwObPKE456+g3FRxiyVQUeqFGMYkPaK0E0QI7zpIvH/HDlBZiJNnA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-notifications/-/frontend-components-notifications-4.0.2.tgz", + "integrity": "sha512-xivlLFmlAhn+WNwaKuHXXQhSeVW+EkuApAErhvYanC5SZ32H9cIzp4aF61ZoLv7A1pjTSu/QcZ+BxvfTKCNrUQ==", "requires": { - "@redhat-cloud-services/frontend-components": "^4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.0", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.0", "redux-promise-middleware": "6.1.3" } }, "@redhat-cloud-services/frontend-components-pdf-generator": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-pdf-generator/-/frontend-components-pdf-generator-4.0.0-beta.0.tgz", - "integrity": "sha512-ykEu0tWtPocRs8zsIWRXTujOiamczd/3MDbCHRtbnIumwO4Ezn0oSoEYHYTm6m4yPCXJ0d5hi1qeTAljIuMtDA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-pdf-generator/-/frontend-components-pdf-generator-4.0.1.tgz", + "integrity": "sha512-FL8gDEGgs9xqtO0bcqLhtOzvmQa9b9JUg8ijrmojrxP8/PDVOl+yUQs34S9+mMIBaZb8RxwRtN85Slj3SKNYGA==", "requires": { "@patternfly/react-charts": "6.3.9", "@patternfly/react-core": "^5.0.0", @@ -29579,7 +29843,7 @@ "@patternfly/react-styles": "^5.0.0", "@patternfly/react-tokens": "^5.0.0", "@react-pdf/renderer": "^1.6.8", - "@redhat-cloud-services/frontend-components": "4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.0", "@scalprum/react-core": "^0.5.1", "react": "16.12.0", "react-dom": "16.12.0", @@ -29653,23 +29917,6 @@ "scheduler": "^0.18.0" } }, - "@redhat-cloud-services/frontend-components": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components/-/frontend-components-4.0.0-beta.0.tgz", - "integrity": "sha512-H8uCZ3yI2M/Q+et9B8r6xAxzkxfjnfrfHAZ1se4I2ErGwHSgybN9+6qwoD1QNhtS8sNJXNtgue3G5qQuVebQKw==", - "requires": { - "@redhat-cloud-services/frontend-components-utilities": "^4.0.0-beta.0", - "@redhat-cloud-services/types": "^0.0.24", - "@scalprum/core": "^0.5.1", - "@scalprum/react-core": "^0.5.1", - "sanitize-html": "^2.7.2" - } - }, - "@redhat-cloud-services/types": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-0.0.24.tgz", - "integrity": "sha512-P50stc+mnWLycID46/AKmD/760r5N1eoam//O6MUVriqVorUdht7xkUL78aJZU1vw8WW6xlrDHwz3F6BM148qg==" - }, "d3-array": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", @@ -30036,9 +30283,9 @@ } }, "@redhat-cloud-services/frontend-components-utilities": { - "version": "4.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.0-beta.0.tgz", - "integrity": "sha512-vM2ijQuSqCSQVopu+P2NAfeBScJGADZbo3cjX9AmD01cdOxA0DPvTL+04WvOVZCdYwBgw85MyOy9hNiVBPrwVQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.1.tgz", + "integrity": "sha512-ZoykyuNV944SXYbG2LnFeyQMOof1y8RqRM9K7T7AzC8n0D/C+NjVxDCoFD94mfs2WDEicWu+lNdV+xhF8Eg2TA==", "requires": { "@redhat-cloud-services/types": "^0.0.24", "@sentry/browser": "^5.30.0", @@ -34436,6 +34683,16 @@ "which": "^2.0.1" } }, + "css-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/css-jss/-/css-jss-10.10.0.tgz", + "integrity": "sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0" + } + }, "css-loader": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", @@ -34587,6 +34844,15 @@ } } }, + "css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "requires": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -37210,6 +37476,11 @@ "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.6.6.tgz", "integrity": "sha512-XtqmnT+b9n5MX+MsqluFAVTIenbtC25iskW0Z+jLd+awfhA+ZbWKWQMIvLJccGoa2bM1R6juWJ27cZxIFOmkWw==" }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -37571,6 +37842,11 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -40424,6 +40700,154 @@ "verror": "1.10.0" } }, + "jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "jss-plugin-compose": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-compose/-/jss-plugin-compose-10.10.0.tgz", + "integrity": "sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-expand": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-expand/-/jss-plugin-expand-10.10.0.tgz", + "integrity": "sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-extend": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-extend/-/jss-plugin-extend-10.10.0.tgz", + "integrity": "sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-rule-value-observable": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.10.0.tgz", + "integrity": "sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "symbol-observable": "^1.2.0" + } + }, + "jss-plugin-template": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-template/-/jss-plugin-template-10.10.0.tgz", + "integrity": "sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "jss-preset-default": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-10.10.0.tgz", + "integrity": "sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "jss-plugin-camel-case": "10.10.0", + "jss-plugin-compose": "10.10.0", + "jss-plugin-default-unit": "10.10.0", + "jss-plugin-expand": "10.10.0", + "jss-plugin-extend": "10.10.0", + "jss-plugin-global": "10.10.0", + "jss-plugin-nested": "10.10.0", + "jss-plugin-props-sort": "10.10.0", + "jss-plugin-rule-value-function": "10.10.0", + "jss-plugin-rule-value-observable": "10.10.0", + "jss-plugin-template": "10.10.0", + "jss-plugin-vendor-prefixer": "10.10.0" + } + }, "jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -42807,6 +43231,11 @@ "integrity": "sha512-6ONbFX+Hi3SHuP66JB8CPvJn372pj+qwltJV0J8z/8MFrq98I1cbFdZuhDWeQXu3CFxiiDTXJn7DFxx2ZvrO7g==", "requires": {} }, + "react-display-name": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/react-display-name/-/react-display-name-0.2.5.tgz", + "integrity": "sha512-I+vcaK9t4+kypiSgaiVWAipqHRXYmZIuAiS8vzFvXHHXVigg/sMKwlRgLy6LH2i3rmP+0Vzfl5lFsFRwF1r3pg==" + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -42907,6 +43336,24 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-10.10.0.tgz", + "integrity": "sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "@emotion/is-prop-valid": "^0.7.3", + "css-jss": "10.10.0", + "hoist-non-react-statics": "^3.2.0", + "is-in-browser": "^1.1.3", + "jss": "10.10.0", + "jss-preset-default": "10.10.0", + "prop-types": "^15.6.0", + "shallow-equal": "^1.2.0", + "theming": "^3.3.0", + "tiny-warning": "^1.0.2" + } + }, "react-redux": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", @@ -43791,6 +44238,11 @@ "kind-of": "^6.0.2" } }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -44465,6 +44917,11 @@ "dev": true, "requires": {} }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -44592,6 +45049,17 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "theming": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/theming/-/theming-3.3.0.tgz", + "integrity": "sha512-u6l4qTJRDaWZsqa8JugaNt7Xd8PPl9+gonZaIe28vAhqgHMIG/DOyFPqiKN/gQLQYj05tHv+YQdNILL4zoiAVA==", + "requires": { + "hoist-non-react-statics": "^3.3.0", + "prop-types": "^15.5.8", + "react-display-name": "^0.2.4", + "tiny-warning": "^1.0.2" + } + }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -44624,6 +45092,11 @@ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", @@ -44982,13 +45455,13 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, "url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, "requires": { "punycode": "^1.4.1", - "qs": "^6.11.0" + "qs": "^6.11.2" }, "dependencies": { "punycode": { diff --git a/package.json b/package.json index 63cc8429a..2655dcfba 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@openshift/dynamic-plugin-sdk-webpack": "^3.0.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.2.6", - "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.0-beta.0", + "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.2", "@redhat-cloud-services/types": "^0.0.22", "@simonsmith/cypress-image-snapshot": "^6.0.1", "@swc/core": "^1.3.76", @@ -114,7 +114,7 @@ "swc-loader": "^0.2.3", "terser-webpack-plugin": "^5.3.6", "typescript": "^4.9.5", - "url": "^0.11.0", + "url": "^0.11.3", "utility-types": "^3.10.0", "wait-on": "^7.0.1", "webpack": "^5.76.1", @@ -128,18 +128,18 @@ "@data-driven-forms/react-form-renderer": "^3.20.2", "@formatjs/cli": "4.8.4", "@openshift/dynamic-plugin-sdk": "^3.0.0", - "@patternfly/patternfly": "^5.0.0", + "@patternfly/patternfly": "^5.0.4", "@patternfly/quickstarts": "^5.0.0", "@patternfly/react-charts": "^7.0.0", - "@patternfly/react-core": "^5.0.0", - "@patternfly/react-icons": "^5.0.0", - "@patternfly/react-tokens": "^5.0.0", + "@patternfly/react-core": "^5.0.1", + "@patternfly/react-icons": "^5.0.1", + "@patternfly/react-tokens": "^5.0.1", "@redhat-cloud-services/chrome": "^0.0.11", "@redhat-cloud-services/entitlements-client": "1.2.0", - "@redhat-cloud-services/frontend-components": "4.0.0-beta.3", - "@redhat-cloud-services/frontend-components-notifications": "4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-pdf-generator": "4.0.0-beta.0", - "@redhat-cloud-services/frontend-components-utilities": "4.0.0-beta.0", + "@redhat-cloud-services/frontend-components": "^4.0.10", + "@redhat-cloud-services/frontend-components-notifications": "^4.0.2", + "@redhat-cloud-services/frontend-components-pdf-generator": "4.0.1", + "@redhat-cloud-services/frontend-components-utilities": "^4.0.1", "@redhat-cloud-services/host-inventory-client": "1.2.0", "@redhat-cloud-services/rbac-client": "1.2.0", "@scalprum/core": "0.5.1", diff --git a/src/components/AllServices/allServicesLinks.ts b/src/components/AllServices/allServicesLinks.ts index 488c1b594..81aefe870 100644 --- a/src/components/AllServices/allServicesLinks.ts +++ b/src/components/AllServices/allServicesLinks.ts @@ -1,7 +1,9 @@ import AllServicesIcons from './AllServicesIcons'; +import AllServicesDropdownIcons from '../AllServicesDropdown/AllServicesDropdownIcons'; export type AllServicesLink = { href: string; + icon?: keyof typeof AllServicesDropdownIcons; title: string; subtitle?: string; description?: string; diff --git a/src/components/AllServicesDropdown/AllServicesDropdownIcons.ts b/src/components/AllServicesDropdown/AllServicesDropdownIcons.ts new file mode 100644 index 000000000..4d5d5eb3a --- /dev/null +++ b/src/components/AllServicesDropdown/AllServicesDropdownIcons.ts @@ -0,0 +1,31 @@ +import ACSIcon from './icon-acs'; +import AnsibleIcon from './icon-ansible'; +import AppServicesIcon from './icon-app-services'; +import DataScienceIcon from './icon-data-science'; +import EdgeIcon from './icon-edge'; +import InsightsIcon from './icon-insights'; +import OpenShiftIcon from './icon-openshift'; +import PlaceholderIcon from './icon-placeholder'; +import QuayIoIcon from './icon-quay-io'; +import RHIcon from './icon-rh'; +import ServicesIcon from './icon-services'; +import SubscriptionsIcon from './icon-subscriptions'; +import TrustedContentIcon from './icon-trusted-content'; + +const AllServicesDropdownIcons = { + ACSIcon, + AnsibleIcon, + AppServicesIcon, + DataScienceIcon, + EdgeIcon, + InsightsIcon, + OpenShiftIcon, + PlaceholderIcon, + QuayIoIcon, + RHIcon, + ServicesIcon, + SubscriptionsIcon, + TrustedContentIcon, +}; + +export default AllServicesDropdownIcons; diff --git a/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx b/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx index a33c8a3f6..e12d35fad 100644 --- a/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx +++ b/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx @@ -9,18 +9,18 @@ import StarIcon from '@patternfly/react-icons/dist/dynamic/icons/star-icon'; import ExternalLinkAltIcon from '@patternfly/react-icons/dist/dynamic/icons/external-link-alt-icon'; import { AllServicesLinkProps } from '../AllServices/AllServicesLink'; +import AllServicesDropdownIcons from './AllServicesDropdownIcons'; import ChromeLink from '../ChromeLink'; -import { bundleMapping } from '../../hooks/useBundle'; import classNames from 'classnames'; import useFavoritePagesWrapper from '../../hooks/useFavoritePagesWrapper'; import { AllServicesDropdownContext } from './common'; export type AllServicesGalleryLinkProps = AllServicesLinkProps; -const AllServicesGalleryLink = ({ href, title, description, isExternal, subtitle }: AllServicesGalleryLinkProps) => { - const bundle = bundleMapping[href.split('/')[1]]; +const AllServicesGalleryLink = ({ href, title, icon, description, isExternal }: AllServicesGalleryLinkProps) => { const { favoritePage, unfavoritePage, favoritePages } = useFavoritePagesWrapper(); const { onLinkClick } = useContext(AllServicesDropdownContext); + const TitleIcon = icon ? AllServicesDropdownIcons[icon] : null; const handleFavoriteToggle = (pathname: string, favorite?: boolean) => { if (favorite) { @@ -44,7 +44,10 @@ const AllServicesGalleryLink = ({ href, title, description, isExternal, subtitle > - {title} + {TitleIcon && } + +
{title}
+
{isExternal ? ( @@ -73,15 +76,7 @@ const AllServicesGalleryLink = ({ href, title, description, isExternal, subtitle
- {/* - if subtitle is not set use bundle - - do not show bundle if the card title matches bundle title - */} - {subtitle || (bundle !== title ? bundle : null)} - - {description ?? ''} - + {description ?? ''}
diff --git a/src/components/AllServicesDropdown/AllServicesGallerySection.tsx b/src/components/AllServicesDropdown/AllServicesGallerySection.tsx index 1f2c3c272..6656114b1 100644 --- a/src/components/AllServicesDropdown/AllServicesGallerySection.tsx +++ b/src/components/AllServicesDropdown/AllServicesGallerySection.tsx @@ -1,5 +1,5 @@ import { Gallery } from '@patternfly/react-core/dist/dynamic/layouts/Gallery'; -import { Title } from '@patternfly/react-core/dist/dynamic/components/Title'; +import { Label } from '@patternfly/react-core/dist/dynamic/components/Label'; import React from 'react'; import { AllServicesGroup } from '../AllServices/allServicesLinks'; @@ -13,9 +13,7 @@ const AllServicesGallerySection = ({ title, links }: AllServicesGallerySectionPr } return (
- - {title} - +
{links.map((link, index) => ( diff --git a/src/components/AllServicesDropdown/icon-acs.tsx b/src/components/AllServicesDropdown/icon-acs.tsx new file mode 100644 index 000000000..1704653c7 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-acs.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +const ACSIcon = () => { + return ( + + + + + + + + + + ); +}; +export default ACSIcon; diff --git a/src/components/AllServicesDropdown/icon-ansible.tsx b/src/components/AllServicesDropdown/icon-ansible.tsx new file mode 100644 index 000000000..baf9f78cd --- /dev/null +++ b/src/components/AllServicesDropdown/icon-ansible.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +const AnsibleIcon = () => { + return ( + + + + + + + + + + ); +}; +export default AnsibleIcon; diff --git a/src/components/AllServicesDropdown/icon-app-services.tsx b/src/components/AllServicesDropdown/icon-app-services.tsx new file mode 100644 index 000000000..40b89163f --- /dev/null +++ b/src/components/AllServicesDropdown/icon-app-services.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +const AppServicesIcon = () => { + return ( + + + + + + + + + + + ); +}; +export default AppServicesIcon; diff --git a/src/components/AllServicesDropdown/icon-data-science.tsx b/src/components/AllServicesDropdown/icon-data-science.tsx new file mode 100644 index 000000000..9b5e1a2b9 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-data-science.tsx @@ -0,0 +1,47 @@ +import React from 'react'; + +const DataScienceIcon = () => { + return ( + + + + + + + + + + + + + + + ); +}; +export default DataScienceIcon; diff --git a/src/components/AllServicesDropdown/icon-edge.tsx b/src/components/AllServicesDropdown/icon-edge.tsx new file mode 100644 index 000000000..56d049c10 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-edge.tsx @@ -0,0 +1,73 @@ +import React from 'react'; + +const EdgeIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; +export default EdgeIcon; diff --git a/src/components/AllServicesDropdown/icon-insights.tsx b/src/components/AllServicesDropdown/icon-insights.tsx new file mode 100644 index 000000000..8cd4435d4 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-insights.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +const InsightsIcon = () => { + return ( + + + + + + + + + + ); +}; +export default InsightsIcon; diff --git a/src/components/AllServicesDropdown/icon-openshift.tsx b/src/components/AllServicesDropdown/icon-openshift.tsx new file mode 100644 index 000000000..45ba09de7 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-openshift.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +const OpenShiftIcon = () => { + return ( + + + + + + + + + + + + + ); +}; +export default OpenShiftIcon; diff --git a/src/components/AllServicesDropdown/icon-placeholder.tsx b/src/components/AllServicesDropdown/icon-placeholder.tsx new file mode 100644 index 000000000..fc2e4ae81 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-placeholder.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +const PlaceholderIcon = () => { + return ( + + + + + + + + + + + + ); +}; +export default PlaceholderIcon; diff --git a/src/components/AllServicesDropdown/icon-quay-io.tsx b/src/components/AllServicesDropdown/icon-quay-io.tsx new file mode 100644 index 000000000..62336b0ce --- /dev/null +++ b/src/components/AllServicesDropdown/icon-quay-io.tsx @@ -0,0 +1,48 @@ +import React from 'react'; + +const QuayIoIcon = () => { + return ( + + + + + + + + + + + + + + + + + + ); +}; +export default QuayIoIcon; diff --git a/src/components/AllServicesDropdown/icon-rh.tsx b/src/components/AllServicesDropdown/icon-rh.tsx new file mode 100644 index 000000000..56f97f81f --- /dev/null +++ b/src/components/AllServicesDropdown/icon-rh.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +const RHIcon = () => { + return ( + + + + + + + + + + + ); +}; +export default RHIcon; diff --git a/src/components/AllServicesDropdown/icon-services.tsx b/src/components/AllServicesDropdown/icon-services.tsx new file mode 100644 index 000000000..7cd6d85c9 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-services.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +const ServicesIcon = () => { + return ( + + + + + + + + + ); +}; +export default ServicesIcon; diff --git a/src/components/AllServicesDropdown/icon-subscriptions.tsx b/src/components/AllServicesDropdown/icon-subscriptions.tsx new file mode 100644 index 000000000..e646e97a5 --- /dev/null +++ b/src/components/AllServicesDropdown/icon-subscriptions.tsx @@ -0,0 +1,44 @@ +import React from 'react'; + +const SubscriptionsIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + ); +}; +export default SubscriptionsIcon; diff --git a/src/components/AllServicesDropdown/icon-trusted-content.tsx b/src/components/AllServicesDropdown/icon-trusted-content.tsx new file mode 100644 index 000000000..0e36a540b --- /dev/null +++ b/src/components/AllServicesDropdown/icon-trusted-content.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +const TrustedContentIcon = () => { + return ( + + + + + + + + + + + + ); +}; +export default TrustedContentIcon; diff --git a/src/components/AppFilter/useAppFilter.ts b/src/components/AppFilter/useAppFilter.ts index 6b59cd25d..476bf3cdd 100644 --- a/src/components/AppFilter/useAppFilter.ts +++ b/src/components/AppFilter/useAppFilter.ts @@ -12,7 +12,7 @@ export type AppFilterBucket = { links: NavItem[]; }; -const previewBundles = ['business-services', 'subscriptions']; +const previewBundles = ['subscriptions']; export const requiredBundles = [ 'application-services', @@ -23,6 +23,7 @@ export const requiredBundles = [ 'settings', 'iam', 'quay', + 'business-services', ...(!isProd() ? previewBundles : isBeta() ? previewBundles : []), ]; diff --git a/src/components/FavoriteServices/LandingNavFavorites.tsx b/src/components/FavoriteServices/LandingNavFavorites.tsx index 9fbd7dff7..0ae113256 100644 --- a/src/components/FavoriteServices/LandingNavFavorites.tsx +++ b/src/components/FavoriteServices/LandingNavFavorites.tsx @@ -1,4 +1,4 @@ -import { Card, CardBody } from '@patternfly/react-core/dist/dynamic/components/Card'; +import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core/dist/dynamic/components/Card'; import { Flex, FlexItem } from '@patternfly/react-core/dist/dynamic/layouts/Flex'; import { Gallery, GalleryItem } from '@patternfly/react-core/dist/dynamic/layouts/Gallery'; import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon'; @@ -32,17 +32,11 @@ const LandingNavFavorites = () => { return favoritedServices.slice((page - 1) * perPage, page * perPage).map((favorite, index) => ( - - - - - {favorite.name} - - - {getBundle(favorite.pathname)} - - - + + + {favorite.name} + + {getBundle(favorite.pathname)} @@ -84,7 +78,9 @@ const LandingNavFavorites = () => { ) : ( - {buildFavorites()} + + {buildFavorites()} + )} diff --git a/src/components/Feedback/FeedbackModal.tsx b/src/components/Feedback/FeedbackModal.tsx index e01fac42b..82b142c96 100644 --- a/src/components/Feedback/FeedbackModal.tsx +++ b/src/components/Feedback/FeedbackModal.tsx @@ -22,8 +22,10 @@ import FeedbackSuccess from './FeedbackSuccess'; import messages from '../../locales/Messages'; import FeedbackError from './FeedbackError'; -import './Feedback.scss'; import InternalChromeContext from '../../utils/internalChromeContext'; +import LibtJWTContext from '../LibJWTContext'; +import { createSupportCase } from '../../utils/createCase'; +import './Feedback.scss'; export type FeedbackModalProps = { user: DeepRequired; @@ -46,6 +48,7 @@ const FeedbackModal = memo(({ user }: FeedbackModalProps) => { const dispatch = useDispatch(); const [modalPage, setModalPage] = useState('feedbackHome'); const { getEnvironment } = useContext(InternalChromeContext); + const libjwt = useContext(LibtJWTContext); const env = getEnvironment(); const isAvailable = env === 'prod' || env === 'stage'; const setIsModalOpen = (isOpen: boolean) => dispatch(toggleFeedbackModal(isOpen)); @@ -73,13 +76,7 @@ const FeedbackModal = memo(({ user }: FeedbackModalProps) => { {intl.formatMessage(messages.describeBugUrgentCases)}
- { - window.open('https://access.redhat.com/support/cases/#/case/new/open-case?caseCreate=true', '_blank'); - }} - > + createSupportCase(user.identity, libjwt)}> {intl.formatMessage(messages.openSupportCase)} diff --git a/src/components/Header/HeaderTests/ToolbarToggle.test.js b/src/components/Header/HeaderTests/ToolbarToggle.test.js index 02c6a71ce..c2e47d903 100644 --- a/src/components/Header/HeaderTests/ToolbarToggle.test.js +++ b/src/components/Header/HeaderTests/ToolbarToggle.test.js @@ -29,39 +29,39 @@ describe('ToolbarToggle', () => { clickSpy.mockReset(); }); - it('should render correctly', () => { + it('should render correctly', async () => { const { container } = render(); const toggleButton = container.querySelector('#foo'); expect(toggleButton).toBeTruthy(); - act(() => { + await act(async () => { fireEvent.click(toggleButton); }); expect(container.querySelector('div')).toMatchSnapshot(); }); - it('should open/close menu correctly', () => { + it('should open/close menu correctly', async () => { const { container } = render(); const toggleButton = container.querySelector('#foo'); expect(toggleButton).toBeTruthy(); - act(() => { + await act(async () => { fireEvent.click(toggleButton); }); expect(container.querySelectorAll('.pf-v5-c-menu__list-item')).toHaveLength(2); - act(() => { + await act(async () => { fireEvent.click(toggleButton); }); expect(container.querySelectorAll('.pf-v5-c-menu__list-item')).toHaveLength(0); }); - it('should call onClick menu item callback', () => { + it('should call onClick menu item callback', async () => { const { container } = render(); const toggleButton = container.querySelector('#foo'); - act(() => { + await act(async () => { fireEvent.click(toggleButton); }); const actionButton = container.querySelector('button.pf-v5-c-menu__item'); expect(actionButton).toBeTruthy(); - act(() => { + await act(async () => { fireEvent.click(actionButton); }); expect(clickSpy).toHaveBeenCalled(); diff --git a/src/components/Header/HeaderTests/Tools.test.js b/src/components/Header/HeaderTests/Tools.test.js index 4137e3a3d..414dc2734 100644 --- a/src/components/Header/HeaderTests/Tools.test.js +++ b/src/components/Header/HeaderTests/Tools.test.js @@ -26,7 +26,7 @@ describe('Tools', () => { await act(async () => { container = render( - state)}> + state)}> diff --git a/src/components/Header/HeaderTests/__snapshots__/ToolbarToggle.test.js.snap b/src/components/Header/HeaderTests/__snapshots__/ToolbarToggle.test.js.snap index 268169d50..ec837b4cb 100644 --- a/src/components/Header/HeaderTests/__snapshots__/ToolbarToggle.test.js.snap +++ b/src/components/Header/HeaderTests/__snapshots__/ToolbarToggle.test.js.snap @@ -6,7 +6,10 @@ exports[`ToolbarToggle should render correctly 1`] = ` data-ouia-component-id="OUIA-Generated-Dropdown-1" data-ouia-component-type="PF5/Dropdown" data-ouia-safe="true" - style="position: absolute; left: 0px; top: 0px; z-index: 9999; min-width: 0px;" + data-popper-escaped="true" + data-popper-placement="bottom-end" + data-popper-reference-hidden="true" + style="position: absolute; left: 0px; top: 0px; z-index: 9999; min-width: 0px; transform: translate(0px, 0px);" >
{ ( diff --git a/src/components/Header/Tools.tsx b/src/components/Header/Tools.tsx index 5c0d70753..dc37dcb95 100644 --- a/src/components/Header/Tools.tsx +++ b/src/components/Header/Tools.tsx @@ -82,7 +82,7 @@ const Tools = () => { }); const { xs } = useWindowWidth(); const user = useSelector(({ chrome: { user } }: ReduxState) => user!); - const unreadNotifications = useSelector(({ chrome: { notifications } }: ReduxState) => notifications?.data?.filter((isRead) => !isRead) || []); + const unreadNotifications = useSelector(({ chrome: { notifications } }: ReduxState) => notifications.data.some((item) => !item.read)); const isDrawerExpanded = useSelector(({ chrome: { notifications } }: ReduxState) => notifications?.isExpanded); const dispatch = useDispatch(); const libjwt = useContext(LibtJWTContext); @@ -131,33 +131,33 @@ const Tools = () => { /* list out the items for the about menu */ const aboutMenuDropdownItems = [ { - title: `${intl.formatMessage(messages.apiDocumentation)}`, + title: intl.formatMessage(messages.apiDocumentation), onClick: () => window.open('https://developers.redhat.com/api-catalog/', '_blank'), isHidden: isITLessEnv, }, { - title: `${intl.formatMessage(messages.openSupportCase)}`, + title: intl.formatMessage(messages.openSupportCase), onClick: () => createSupportCase(user.identity, libjwt), isDisabled: window.location.href.includes('/application-services') && !isRhosakEntitled, isHidden: isITLessEnv, }, { - title: `${intl.formatMessage(messages.statusPage)}`, + title: intl.formatMessage(messages.statusPage), onClick: () => window.open('https://status.redhat.com/', '_blank'), isHidden: isITLessEnv, }, { - title: `${intl.formatMessage(messages.supportOptions)}`, + title: intl.formatMessage(messages.supportOptions), url: isITLessEnv ? 'https://redhatgov.servicenowservices.com/css' : 'https://access.redhat.com/support', }, { - title: `${intl.formatMessage(messages.insightsRhelDocumentation)}`, + title: intl.formatMessage(messages.insightsRhelDocumentation), onClick: () => window.open('https://access.redhat.com/documentation/en-us/red_hat_insights', '_blank'), isHidden: getSection() !== 'insights' || isITLessEnv, }, { - title: `${intl.formatMessage(messages.demoMode)}`, + title: intl.formatMessage(messages.demoMode), onClick: () => cookie.set('cs_demo', 'true') && window.location.reload(), isHidden: !isDemoAcc, }, @@ -240,16 +240,18 @@ const Tools = () => { {!xs && } {isNotificationsEnabled && ( - - dispatch(toggleNotificationsDrawer())} - aria-label="Notifications" - isExpanded={isDrawerExpanded} - > - - + + + dispatch(toggleNotificationsDrawer())} + aria-label="Notifications" + isExpanded={isDrawerExpanded} + > + + + )} {localStorage.getItem('chrome:darkmode') === 'true' && ( diff --git a/src/components/NotificationsDrawer/DrawerPanelContent.test.tsx b/src/components/NotificationsDrawer/DrawerPanelContent.test.tsx new file mode 100644 index 000000000..9b448420e --- /dev/null +++ b/src/components/NotificationsDrawer/DrawerPanelContent.test.tsx @@ -0,0 +1,176 @@ +import React from 'react'; +import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { Provider } from 'react-redux'; +import configureMockStore, { MockStore } from 'redux-mock-store'; +import DrawerPanel from './DrawerPanelContent'; +import { BrowserRouter } from 'react-router-dom'; +import { markAllNotificationsAsRead, markAllNotificationsAsUnread, markNotificationAsRead, markNotificationAsUnread } from '../../redux/actions'; +import { readTestData, testData } from './notificationDrawerUtils'; + +const mockStore = configureMockStore(); + +const stateWithNotifications = { + chrome: { + notifications: { + data: testData, + isExpanded: true, + count: 3, + }, + }, +}; + +const stateWithoutNotifications = { + chrome: { + notifications: { + data: [], + isExpanded: true, + count: 0, + }, + }, +}; + +const stateWithReadNotifications = { + chrome: { + notifications: { + data: readTestData, + isExpanded: true, + count: 2, + }, + }, +}; + +const renderComponent = (store: MockStore) => { + return render( + + + + + + + + ); +}; + +describe('Drawer panel functionality', () => { + test('Renders the drawer panel empty successfully. ', () => { + const store = mockStore(stateWithoutNotifications); + + const renderedResult = renderComponent(store); + expect(renderedResult.getByText('Notifications')).toBeInTheDocument(); + }); + + test('Renders notification drawer with notifications successfully', () => { + const store = mockStore(stateWithNotifications); + + const renderedResult = renderComponent(store); + expect(renderedResult.getByText('Test Notification 1')).toBeInTheDocument(); + }); + + test('Marking notification as read successfully', async () => { + const store = mockStore(stateWithNotifications); + + const renderedResult = renderComponent(store); + + const checkbox = renderedResult.getAllByRole('checkbox'); + + await act(async () => { + fireEvent.click(checkbox[0]); + }); + + const actions = store.getActions(); + + await waitFor(() => { + expect(actions).toContainEqual(markNotificationAsRead('1')); + }); + }); + + test('Mark notification as unread successfully', async () => { + const store = mockStore(stateWithReadNotifications); + + const renderedResult = renderComponent(store); + + const checkbox = renderedResult.getAllByRole('checkbox'); + + await act(async () => { + fireEvent.click(checkbox[0]); + }); + + const actions = store.getActions(); + + await waitFor(() => { + expect(actions).toContainEqual(markNotificationAsUnread('1')); + }); + }); + + test('Mark all notifications as read successfully', async () => { + const store = mockStore(stateWithNotifications); + + const renderedResult = renderComponent(store); + + const actionMenuButton = renderedResult.getByRole('button', { name: /Notifications actions dropdown/i }); + + await act(async () => { + fireEvent.click(actionMenuButton); + }); + + const actionDropdownItems = await renderedResult.getAllByRole('menuitem'); + + await act(async () => { + fireEvent.click(actionDropdownItems[0]); + }); + + const actions = store.getActions(); + + await waitFor(() => { + expect(actions).toContainEqual(markAllNotificationsAsRead()); + }); + }); + + test('Mark all notifications as unread successfully', async () => { + const store = mockStore(stateWithReadNotifications); + + const renderedResult = renderComponent(store); + + const actionMenuButton = renderedResult.getByRole('button', { name: /Notifications actions dropdown/i }); + + await act(async () => { + fireEvent.click(actionMenuButton); + }); + + const actionDropdownItems = await renderedResult.getAllByRole('menuitem'); + + act(() => { + fireEvent.click(actionDropdownItems[1]); + }); + + const actions = store.getActions(); + + await waitFor(() => { + expect(actions).toContainEqual(markAllNotificationsAsUnread()); + }); + }); + + test('Select filter successfully', async () => { + const store = mockStore(stateWithNotifications); + + const renderedResult = renderComponent(store); + + const filterMenuButton = renderedResult.getByRole('button', { name: /Notifications filter/i }); + + await act(async () => { + fireEvent.click(filterMenuButton); + }); + + const filterMenuItems = await renderedResult.getAllByRole('menuitem'); + + await act(async () => { + fireEvent.click(filterMenuItems[2]); + }); + + const filteredNotification = await renderedResult.getAllByRole('listitem'); + + await waitFor(() => { + expect(filteredNotification.length === 1); + }); + }); +}); diff --git a/src/components/NotificationsDrawer/DrawerPanelContent.tsx b/src/components/NotificationsDrawer/DrawerPanelContent.tsx index bdf629598..936fddaad 100644 --- a/src/components/NotificationsDrawer/DrawerPanelContent.tsx +++ b/src/components/NotificationsDrawer/DrawerPanelContent.tsx @@ -189,6 +189,7 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { onClick={() => setIsFilterDropdownOpen(!isFilterDropdownOpen)} id="notifications-filter-toggle" variant="plain" + aria-label="Notifications filter" > @@ -199,7 +200,6 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { position: PopoverPosition.right, }} id="notifications-filter-dropdown" - aria-label="Notifications filter" > {filterDropdownItems()} @@ -210,6 +210,7 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { onClick={() => setIsDropdownOpen(!isDropdownOpen)} variant="plain" id="notifications-actions-toggle" + aria-label="Notifications actions dropdown" isFullWidth > diff --git a/src/components/NotificationsDrawer/NotificationItem.tsx b/src/components/NotificationsDrawer/NotificationItem.tsx index dabf6fbd4..3ad2edb4c 100644 --- a/src/components/NotificationsDrawer/NotificationItem.tsx +++ b/src/components/NotificationsDrawer/NotificationItem.tsx @@ -38,7 +38,7 @@ const NotificationItem: React.FC = ({ notification, onNav return ( - + { user: { username: 'foo', first_name: 'foo', last_name: 'foo', is_org_admin: false, is_internal: false }, }, }, + notifications: { data: [] }, activeApp: 'some-app', activeLocation: 'some-location', appId: 'app-id', diff --git a/src/components/RootApp/ScalprumRoot.tsx b/src/components/RootApp/ScalprumRoot.tsx index 0e458d8a9..748ad05cf 100644 --- a/src/components/RootApp/ScalprumRoot.tsx +++ b/src/components/RootApp/ScalprumRoot.tsx @@ -1,6 +1,7 @@ import React, { Suspense, lazy, memo, useCallback, useContext, useEffect, useMemo, useRef } from 'react'; +import axios from 'axios'; import { ScalprumProvider, ScalprumProviderProps } from '@scalprum/react-core'; -import { shallowEqual, useSelector, useStore } from 'react-redux'; +import { shallowEqual, useDispatch, useSelector, useStore } from 'react-redux'; import { Route, Routes } from 'react-router-dom'; import { HelpTopic, HelpTopicContext } from '@patternfly/quickstarts'; import isEqual from 'lodash/isEqual'; @@ -29,6 +30,7 @@ import chromeApiWrapper from './chromeApiWrapper'; import { ITLess } from '../../utils/common'; import InternalChromeContext from '../../utils/internalChromeContext'; import useChromeServiceEvents from '../../hooks/useChromeServiceEvents'; +import { populateNotifications } from '../../redux/actions'; const ProductSelection = lazy(() => import('../Stratosphere/ProductSelection')); @@ -46,6 +48,7 @@ export type ScalprumRootProps = FooterProps & { const ScalprumRoot = memo( ({ config, helpTopicsAPI, quickstartsAPI, cookieElement, setCookieElement, ...props }: ScalprumRootProps) => { const { setFilteredHelpTopics } = useContext(HelpTopicContext); + const dispatch = useDispatch(); const internalFilteredTopics = useRef([]); const { analytics } = useContext(SegmentContext); @@ -56,6 +59,15 @@ const ScalprumRoot = memo( // initialize WS event handling useChromeServiceEvents(); + async function getNotifications() { + try { + const notifications = await axios.get('/api/notifications/v1/notifications/drawer'); + dispatch(populateNotifications(notifications.data?.data || [])); + } catch (error) { + console.error('Unable to get Notifications ', error); + } + } + const { setActiveTopic } = useHelpTopicManager(helpTopicsAPI); function isStringArray(arr: EnableTopicsArgs): arr is string[] { @@ -91,6 +103,8 @@ const ScalprumRoot = memo( useEffect(() => { // prepare webpack module sharing scope overrides updateSharedScope(); + // get notifications drawer api + getNotifications(); const unregister = chromeHistory.listen(historyListener); return () => { if (typeof unregister === 'function') { diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 8804ecea0..4481db2e5 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -33,6 +33,14 @@ const redirects = [ path: '/subscriptions', to: '/subscriptions/overview', }, + { + path: '/business-services', + to: '/business-services/hybrid-committed-spend', + }, + { + path: '/docs', + to: '/docs/api', + }, ]; export type RoutesProps = { diff --git a/src/hooks/useChromeServiceEvents.ts b/src/hooks/useChromeServiceEvents.ts index 136447a5d..41709b6f8 100644 --- a/src/hooks/useChromeServiceEvents.ts +++ b/src/hooks/useChromeServiceEvents.ts @@ -1,8 +1,10 @@ import { useEffect, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { useFlag } from '@unleash/proxy-client-react'; +import { UPDATE_NOTIFICATIONS } from '../redux/action-types'; import { getEncodedToken, setCookie } from '../jwt/jwt'; +import { NotificationsPayload } from '../redux/store'; const NOTIFICATION_DRAWER = 'notifications.drawer'; const SAMPLE_EVENT = 'sample.type'; @@ -14,12 +16,7 @@ type SamplePayload = { foo: string; }; -type NotificationPayload = { - title: string; - description: string; -}; - -type Payload = NotificationPayload | SamplePayload; +type Payload = NotificationsPayload | SamplePayload; interface GenericEvent { type: EventTypes; data: T; @@ -34,15 +31,17 @@ const useChromeServiceEvents = () => { const dispatch = useDispatch(); const isNotificationsEnabled = useFlag('platform.chrome.notifications-drawer'); - const handlerMap: { [key in EventTypes]: (payload: Payload) => void } = useMemo( + const handlerMap: { [key in EventTypes]: (payload: GenericEvent) => void } = useMemo( () => ({ - [NOTIFICATION_DRAWER]: (data: Payload) => dispatch({ type: 'foo', payload: data }), - [SAMPLE_EVENT]: (data: Payload) => console.log('Received sample payload', data), + [NOTIFICATION_DRAWER]: (data: GenericEvent) => { + dispatch({ type: UPDATE_NOTIFICATIONS, payload: data }); + }, + [SAMPLE_EVENT]: (data: GenericEvent) => console.log('Received sample payload', data), }), [] ); - function handleEvent(type: EventTypes, data: Payload): void { + function handleEvent(type: EventTypes, data: GenericEvent): void { handlerMap[type](data); } @@ -63,7 +62,7 @@ const useChromeServiceEvents = () => { try { const payload = JSON.parse(data); if (isGenericEvent(payload)) { - handleEvent(payload.type, payload.data); + handleEvent(payload.type, payload); } else { throw new Error(`Unable to handle event type: ${event.type}. The payload does not have required shape! ${event}`); } diff --git a/src/redux/action-types.ts b/src/redux/action-types.ts index 1e2dfee27..16b3f49fb 100644 --- a/src/redux/action-types.ts +++ b/src/redux/action-types.ts @@ -41,8 +41,10 @@ export const CLEAR_QUICKSTARTS = '@@chrome/clear-quickstarts'; export const SET_GATEWAY_ERROR = '@@chrome/set-gateway-error'; export const TOGGLE_NOTIFICATIONS_DRAWER = '@@chrome/toggle-notifications-drawer'; +export const POPULATE_NOTIFICATIONS = '@@chrome/populate-notifications'; export const MARK_NOTIFICATION_AS_READ = '@@chrome/mark-notification-as-read'; export const MARK_NOTIFICATION_AS_UNREAD = '@@chrome/mark-notification-as-unread'; export const MARK_ALL_NOTIFICATION_AS_READ = '@@chrome/mark-all-notification-as-read'; export const MARK_ALL_NOTIFICATION_AS_UNREAD = '@@chrome/mark-all-notification-as-unread'; +export const UPDATE_NOTIFICATIONS = '@@chrome/update-notifications'; diff --git a/src/redux/actions.ts b/src/redux/actions.ts index fb46f0101..351283917 100644 --- a/src/redux/actions.ts +++ b/src/redux/actions.ts @@ -3,7 +3,7 @@ import { getAllSIDs, getAllTags, getAllWorkloads } from '../components/GlobalFil import type { TagFilterOptions, TagPagination } from '../components/GlobalFilter/tagsApi'; import type { ChromeUser } from '@redhat-cloud-services/types'; import type { ChromeModule, FlagTagsFilter, NavDOMEvent, NavItem, Navigation } from '../@types/types'; -import type { AccessRequest } from './store'; +import type { AccessRequest, NotificationData, NotificationsPayload } from './store'; import type { QuickStart } from '@patternfly/quickstarts'; import type { ThreeScaleError } from '../utils/responseInterceptors'; @@ -207,12 +207,14 @@ export const toggleNotificationsDrawer = () => ({ type: actionTypes.TOGGLE_NOTIFICATIONS_DRAWER, }); -export const markNotificationAsRead = (id: number) => ({ +export const populateNotifications = (data: NotificationData[]) => ({ type: actionTypes.POPULATE_NOTIFICATIONS, payload: { data } }); + +export const markNotificationAsRead = (id: string) => ({ type: actionTypes.MARK_NOTIFICATION_AS_READ, payload: id, }); -export const markNotificationAsUnread = (id: number) => ({ +export const markNotificationAsUnread = (id: string) => ({ type: actionTypes.MARK_NOTIFICATION_AS_UNREAD, payload: id, }); @@ -224,3 +226,8 @@ export const markAllNotificationsAsRead = () => ({ export const markAllNotificationsAsUnread = () => ({ type: actionTypes.MARK_ALL_NOTIFICATION_AS_UNREAD, }); + +export const updateNotifications = (payload: NotificationsPayload) => ({ + type: actionTypes.UPDATE_NOTIFICATIONS, + payload, +}); diff --git a/src/redux/chromeReducers.ts b/src/redux/chromeReducers.ts index 83d149abf..d01f3e627 100644 --- a/src/redux/chromeReducers.ts +++ b/src/redux/chromeReducers.ts @@ -4,7 +4,7 @@ import { REQUESTS_COUNT, REQUESTS_DATA } from '../utils/consts'; import { ChromeModule, NavItem, Navigation } from '../@types/types'; import { ITLess, generateRoutesList, highlightItems, isBeta, levelArray } from '../utils/common'; import { ThreeScaleError } from '../utils/responseInterceptors'; -import { AccessRequest, ChromeState, NotificationData } from './store'; +import { AccessRequest, ChromeState, NotificationData, NotificationsPayload } from './store'; export function contextSwitcherBannerReducer(state: ChromeState): ChromeState { return { @@ -344,7 +344,17 @@ export function toggleNotificationsReducer(state: ChromeState) { }; } -export function markNotificationAsRead(state: ChromeState, { payload }: { payload: number }): ChromeState { +export function populateNotificationsReducer(state: ChromeState, { payload: { data } }: { payload: { data: NotificationData[] } }) { + return { + ...state, + notifications: { + ...state.notifications, + data, + }, + }; +} + +export function markNotificationAsRead(state: ChromeState, { payload }: { payload: string }): ChromeState { return { ...state, notifications: { @@ -357,7 +367,7 @@ export function markNotificationAsRead(state: ChromeState, { payload }: { payloa }; } -export function markNotificationAsUnread(state: ChromeState, { payload }: { payload: number }): ChromeState { +export function markNotificationAsUnread(state: ChromeState, { payload }: { payload: string }): ChromeState { return { ...state, notifications: { @@ -391,3 +401,13 @@ export function markAllNotificationsAsUnread(state: ChromeState): ChromeState { }, }; } + +export function updateNotificationsReducer(state: ChromeState, { payload }: { payload: NotificationsPayload }) { + return { + ...state, + notifications: { + ...state.notifications, + data: [...state.notifications.data, payload.data], + }, + }; +} diff --git a/src/redux/index.ts b/src/redux/index.ts index 8b745ba48..402987f0e 100644 --- a/src/redux/index.ts +++ b/src/redux/index.ts @@ -22,6 +22,7 @@ import { onPageAction, onPageObjectId, onRegisterModule, + populateNotificationsReducer, populateQuickstartsReducer, setGatewayError, setPendoFeedbackFlag, @@ -29,6 +30,7 @@ import { toggleDebuggerModal, toggleFeedbackModal, toggleNotificationsReducer, + updateNotificationsReducer, } from './chromeReducers'; import { globalFilterDefaultState, @@ -67,6 +69,7 @@ import { MARK_NOTIFICATION_AS_READ, MARK_NOTIFICATION_AS_UNREAD, MARK_REQUEST_NOTIFICATION_SEEN, + POPULATE_NOTIFICATIONS, POPULATE_QUICKSTARTS_CATALOG, REGISTER_MODULE, SET_GATEWAY_ERROR, @@ -78,6 +81,7 @@ import { TOGGLE_NOTIFICATIONS_DRAWER, UPDATE_ACCESS_REQUESTS_NOTIFICATIONS, UPDATE_DOCUMENT_TITLE_REDUCER, + UPDATE_NOTIFICATIONS, USER_LOGIN, } from './action-types'; import { ChromeState, GlobalFilterState, ReduxState } from './store'; @@ -108,10 +112,12 @@ const reducers = { [SET_GATEWAY_ERROR]: setGatewayError, [CLEAR_QUICKSTARTS]: clearQuickstartsReducer, [TOGGLE_NOTIFICATIONS_DRAWER]: toggleNotificationsReducer, + [POPULATE_NOTIFICATIONS]: populateNotificationsReducer, [MARK_NOTIFICATION_AS_READ]: markNotificationAsRead, [MARK_NOTIFICATION_AS_UNREAD]: markNotificationAsUnread, [MARK_ALL_NOTIFICATION_AS_READ]: markAllNotificationsAsRead, [MARK_ALL_NOTIFICATION_AS_UNREAD]: markAllNotificationsAsUnread, + [UPDATE_NOTIFICATIONS]: updateNotificationsReducer, }; const globalFilter = { diff --git a/src/redux/store.d.ts b/src/redux/store.d.ts index a72375108..beff48101 100644 --- a/src/redux/store.d.ts +++ b/src/redux/store.d.ts @@ -12,7 +12,7 @@ export type InternalNavigation = { export type AccessRequest = { request_id: string; created: string; seen: boolean }; export type NotificationData = { - id: number; + id: string; title: string; description: string; read: boolean; @@ -26,6 +26,17 @@ export type Notifications = { count: number; }; +export type NotificationsPayload = { + data: NotificationData; + source: string; + // cloud events sub protocol metadata + datacontenttype: string; + specversion: string; + // a type field used to identify message purpose + type: string; + time: string; +}; + export type ChromeState = { contextSwitcherOpen: boolean; activeApp?: string; @@ -68,7 +79,7 @@ export type ChromeState = { }; documentTitle?: string; gatewayError?: ThreeScaleError; - notifications?: Notifications; + notifications: Notifications; }; export type GlobalFilterWorkloads = { diff --git a/src/utils/createCase.ts b/src/utils/createCase.ts index b1f9e3243..a4016a50f 100644 --- a/src/utils/createCase.ts +++ b/src/utils/createCase.ts @@ -77,7 +77,9 @@ export async function createSupportCase( } ) { const currentProduct = registerProduct() || 'Other'; - const { src_hash, app_name } = await getProductData(); + const productData = await getProductData(); + // a temporary fallback to getUrl() until all apps are redeployed, which will fix getProductData() - remove after some time + const { src_hash, app_name } = { src_hash: productData?.src_hash, app_name: productData?.app_name ?? getUrl('app') }; const portalUrl = `${getEnvDetails()?.portal}`; const caseUrl = `${portalUrl}${HYDRA_ENDPOINT}`;