From 7f3b59603509abe9097624fbb665838fa16f3ad0 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Fri, 15 Mar 2024 11:08:33 -0400 Subject: [PATCH 01/46] display configure events if user has write perms --- .../DrawerPanelContent.tsx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/NotificationsDrawer/DrawerPanelContent.tsx b/src/components/NotificationsDrawer/DrawerPanelContent.tsx index ba7266c59..d916d6c04 100644 --- a/src/components/NotificationsDrawer/DrawerPanelContent.tsx +++ b/src/components/NotificationsDrawer/DrawerPanelContent.tsx @@ -27,6 +27,7 @@ import NotificationItem from './NotificationItem'; import { markAllNotificationsAsRead, markAllNotificationsAsUnread, toggleNotificationsDrawer } from '../../redux/actions'; import { filterConfig } from './notificationDrawerUtils'; import ChromeAuthContext from '../../auth/ChromeAuthContext'; +import InternalChromeContext from '../../utils/internalChromeContext'; export type DrawerPanelProps = { innerRef: React.Ref; @@ -64,6 +65,26 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { const notifications = useSelector(({ chrome: { notifications } }: ReduxState) => notifications?.data || []); const auth = useContext(ChromeAuthContext); const isOrgAdmin = auth?.user?.identity?.user?.is_org_admin; + const { getUserPermissions } = useContext(InternalChromeContext); + const [hasWritePermission, setHasWritePermission] = useState(false); + + useEffect(() => { + let mounted = true; + const fetchPermissions = async () => { + const permissions = await getUserPermissions?.('integrations'); + if (mounted) { + setHasWritePermission( + permissions?.some((item) => + ['integrations:*:*', 'integrations:endpoints:write'].includes((typeof item === 'string' && item) || item?.permission) + ) + ); + } + }; + fetchPermissions(); + return () => { + mounted = false; + }; + }, []); useEffect(() => { const modifiedNotifications = (activeFilters || []).reduce( @@ -115,7 +136,7 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { View event log , - isOrgAdmin && ( + (isOrgAdmin || hasWritePermission) && ( onNavigateTo('/settings/notifications/configure-events')}> Configure notification settings From f90dd2db8f1d36d613259c9f6cddc633393dbab4 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Mon, 18 Mar 2024 15:25:26 -0400 Subject: [PATCH 02/46] use correct permissions --- .../NotificationsDrawer/DrawerPanelContent.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/NotificationsDrawer/DrawerPanelContent.tsx b/src/components/NotificationsDrawer/DrawerPanelContent.tsx index d916d6c04..849341d9b 100644 --- a/src/components/NotificationsDrawer/DrawerPanelContent.tsx +++ b/src/components/NotificationsDrawer/DrawerPanelContent.tsx @@ -66,16 +66,18 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { const auth = useContext(ChromeAuthContext); const isOrgAdmin = auth?.user?.identity?.user?.is_org_admin; const { getUserPermissions } = useContext(InternalChromeContext); - const [hasWritePermission, setHasWritePermission] = useState(false); + const [hasNotificationsPermissions, setHasNotificationsPermissions] = useState(false); useEffect(() => { let mounted = true; const fetchPermissions = async () => { - const permissions = await getUserPermissions?.('integrations'); + const permissions = await getUserPermissions?.('notifications'); if (mounted) { - setHasWritePermission( + setHasNotificationsPermissions( permissions?.some((item) => - ['integrations:*:*', 'integrations:endpoints:write'].includes((typeof item === 'string' && item) || item?.permission) + ['notifications:*:*', 'notifications:notifications:read', 'notifications:notifications:write'].includes( + (typeof item === 'string' && item) || item?.permission + ) ) ); } @@ -136,7 +138,7 @@ const DrawerPanelBase = ({ innerRef }: DrawerPanelProps) => { View event log , - (isOrgAdmin || hasWritePermission) && ( + (isOrgAdmin || hasNotificationsPermissions) && ( onNavigateTo('/settings/notifications/configure-events')}> Configure notification settings From 9e3cd0c5bc9a80e295c996cffce3923d1ad46633 Mon Sep 17 00:00:00 2001 From: epwinchell <1287144+epwinchell@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:00:24 -0400 Subject: [PATCH 03/46] Favorites widget styling fix (#2797) --- src/components/FavoriteServices/DashboardFavorites.scss | 3 +++ src/components/FavoriteServices/DashboardFavorites.tsx | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 src/components/FavoriteServices/DashboardFavorites.scss diff --git a/src/components/FavoriteServices/DashboardFavorites.scss b/src/components/FavoriteServices/DashboardFavorites.scss new file mode 100644 index 000000000..f9a2f6866 --- /dev/null +++ b/src/components/FavoriteServices/DashboardFavorites.scss @@ -0,0 +1,3 @@ +.widget-favorites { + column-width: 300px; +} diff --git a/src/components/FavoriteServices/DashboardFavorites.tsx b/src/components/FavoriteServices/DashboardFavorites.tsx index b0f6de28f..68f2534ac 100644 --- a/src/components/FavoriteServices/DashboardFavorites.tsx +++ b/src/components/FavoriteServices/DashboardFavorites.tsx @@ -10,6 +10,8 @@ import { Link } from 'react-router-dom'; import ServiceIcon from './ServiceIcon'; +import './DashboardFavorites.scss'; + const DashboardFavorites = () => { const favoritedServices = useFavoritedServices(); @@ -21,12 +23,7 @@ const DashboardFavorites = () => { ) : ( - + {favoritedServices.map((favorite, index) => ( From 618e892f1d5d58b2de6c8501f2aa7cdda268dcd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 19:40:35 +0000 Subject: [PATCH 04/46] Bump webpack-dev-middleware from 5.3.3 to 5.3.4 Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 337b5a659..23bf7bbf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29318,9 +29318,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", From 0dcfcbfee4e6ed6c0b6a112c27add10a4c1e4e93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 08:03:58 +0000 Subject: [PATCH 05/46] Bump follow-redirects from 1.15.4 to 1.15.6 Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23bf7bbf2..5bcfd7d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15873,9 +15873,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", From 25725e3a62fcfb5e96db4ad037d0d8f0273d8ca0 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 25 Mar 2024 09:38:00 +0100 Subject: [PATCH 06/46] Use current pathname in uickstarts timeout. --- src/utils/useNavigation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/useNavigation.ts b/src/utils/useNavigation.ts index b446a6ebf..c73763ece 100644 --- a/src/utils/useNavigation.ts +++ b/src/utils/useNavigation.ts @@ -87,7 +87,7 @@ const useNavigation = () => { navigate( { ...activeLocation.current, - pathname: newPathname.replace(/^\/(beta|preview)\//, '/'), + pathname: window.location.pathname.replace(/^\/(beta|preview)\//, '/'), search: appendQSSearch(window.location.search, activeQSId.current), }, { From 1a86346b1e68ef6f06b4b043f56d37a4ab1cbd72 Mon Sep 17 00:00:00 2001 From: Karel Hala Date: Tue, 26 Mar 2024 17:01:30 +0100 Subject: [PATCH 07/46] Enable feedback on subs pages --- src/components/Header/Header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index b75e90cb4..8ff7ff068 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -26,7 +26,7 @@ const FeedbackRoute = () => { const paths = localStorage.getItem('chrome:experimental:feedback') === 'true' ? ['*'] - : ['/', 'insights/*', 'settings/*', 'openshift/*', 'application-services/*', 'ansible/*', 'edge/*']; + : ['/', 'insights/*', 'settings/*', 'openshift/*', 'application-services/*', 'ansible/*', 'edge/*', 'subscriptions/*']; return ( {paths.map((path) => ( From 14eb59bd0c5723f118ddf54077c2861d97bfaadd Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 28 Mar 2024 11:01:32 +0100 Subject: [PATCH 08/46] Add requestPDF api method --- package-lock.json | 8 ++--- package.json | 2 +- src/chrome/create-chrome.ts | 2 ++ src/pdf/requestPdf.ts | 60 +++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/pdf/requestPdf.ts diff --git a/package-lock.json b/package-lock.json index 5bcfd7d85..4e4d3b006 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.3.0", "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4", - "@redhat-cloud-services/types": "^1.0.6", + "@redhat-cloud-services/types": "^1.0.7", "@simonsmith/cypress-image-snapshot": "^8.1.2", "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29", @@ -5220,9 +5220,9 @@ } }, "node_modules/@redhat-cloud-services/types": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.6.tgz", - "integrity": "sha512-2esuuvW2aM03IOWlMSxqKkGVAjeL9YrS7cBx814nuqBV4SNyC/JxVBUJ8TsjDACRp4jRINWBF27YqZcX7flzLg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.7.tgz", + "integrity": "sha512-+10LrAlXuzn8VaS+CuzLjU04Pd0GrrqrOxEWzjapdXKLbjBKBorzIEX8CJmuDXPkHJd9zyJ92+1/4dX8lswuZg==", "dev": true }, "node_modules/@remix-run/router": { diff --git a/package.json b/package.json index a5f755333..7cc23f176 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.3.0", "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4", - "@redhat-cloud-services/types": "^1.0.6", + "@redhat-cloud-services/types": "^1.0.7", "@simonsmith/cypress-image-snapshot": "^8.1.2", "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29", diff --git a/src/chrome/create-chrome.ts b/src/chrome/create-chrome.ts index c8dfd4713..a81bf7d28 100644 --- a/src/chrome/create-chrome.ts +++ b/src/chrome/create-chrome.ts @@ -35,6 +35,7 @@ import { getVisibilityFunctions } from '../utils/VisibilitySingleton'; import { ChromeAuthContextValue } from '../auth/ChromeAuthContext'; import qe from '../utils/iqeEnablement'; import { RegisterModulePayload } from '../state/atoms/chromeModuleAtom'; +import requestPdf from '../pdf/requestPdf'; export type CreateChromeContextConfig = { useGlobalFilter: (callback: (selectedTags?: FlagTagsFilter) => any) => ReturnType; @@ -194,6 +195,7 @@ export const createChromeContext = ({ store, }, enablePackagesDebug: () => warnDuplicatePkg(), + requestPdf, }; return api; }; diff --git a/src/pdf/requestPdf.ts b/src/pdf/requestPdf.ts new file mode 100644 index 000000000..5952b93fe --- /dev/null +++ b/src/pdf/requestPdf.ts @@ -0,0 +1,60 @@ +import axios from 'axios'; + +const downloadPDF = async (url: string, filename = 'report.pdf') => { + const resp = await fetch(url); + if (!resp.ok) { + const result = await resp.json(); + console.error(result); + throw new Error('Failed to download PDF. Check console for more details.'); + } + + const blob = await resp.blob(); + const hiddenLink: HTMLAnchorElement | undefined = document.createElement('a'); + hiddenLink.href = window.URL.createObjectURL(blob); + hiddenLink.download = filename; + + document.body.appendChild(hiddenLink); + hiddenLink.click(); + hiddenLink.remove(); +}; + +const pollStatus = async (statusID: string) => { + return new Promise<{ status: string; filepath: string }>((resolve, reject) => { + const interval = setInterval(async () => { + try { + const { + data: { status: data }, + } = await axios.get<{ status: { status: string; filepath: string } }>(`/api/crc-pdf-generator/v2/status/${statusID}`); + if (data.status === 'Generated') { + clearInterval(interval); + resolve(data); + } + + if (data.status.includes('Failed')) { + clearInterval(interval); + reject(new Error(data.status)); + } + } catch (error) { + clearInterval(interval); + reject(error); + } + }, 10000); + }); +}; + +const requestPdf = async (options: { service: string; template: string; filename?: string; [key: string]: any }) => { + const { filename, ...rest } = options; + try { + const { + data: { statusID }, + } = await axios.post<{ statusID: string }>(`/api/crc-pdf-generator/v2/create`, rest); + const { status } = await pollStatus(statusID); + if (status === 'Generated') { + downloadPDF(`/api/crc-pdf-generator/v2/download/${statusID}`, filename); + } + } catch (error) { + console.log(error); + } +}; + +export default requestPdf; From d4d0f5fe34e2210aafc05586d3bcda276a0ef2fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:59:09 +0000 Subject: [PATCH 09/46] Bump express from 4.18.2 to 4.19.2 Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e4d3b006..0811f16eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11926,13 +11926,13 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -11940,7 +11940,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -12842,9 +12842,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -15398,17 +15398,17 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -24759,9 +24759,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", From f6a16abeb6e2f8203097b29aa5cc13c966e4c1e8 Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Thu, 28 Mar 2024 14:24:40 -0500 Subject: [PATCH 10/46] add ai technology icon --- .../icon-ai-technology.tsx | 40 +++++++++++++++++++ .../FavoriteServices/ServiceIcon.tsx | 3 ++ 2 files changed, 43 insertions(+) create mode 100644 src/components/AllServicesDropdown/icon-ai-technology.tsx diff --git a/src/components/AllServicesDropdown/icon-ai-technology.tsx b/src/components/AllServicesDropdown/icon-ai-technology.tsx new file mode 100644 index 000000000..5327fc23e --- /dev/null +++ b/src/components/AllServicesDropdown/icon-ai-technology.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +const AITechnologyIcon = () => { + return ( + + + + + + + + + + + + + ); +}; + +export default AITechnologyIcon; diff --git a/src/components/FavoriteServices/ServiceIcon.tsx b/src/components/FavoriteServices/ServiceIcon.tsx index 818b75cb4..536c2fc1c 100644 --- a/src/components/FavoriteServices/ServiceIcon.tsx +++ b/src/components/FavoriteServices/ServiceIcon.tsx @@ -1,5 +1,6 @@ import React from 'react'; import PlaceholderIcon from '../AllServicesDropdown/icon-placeholder'; +import AITechnologyIcon from '../AllServicesDropdown/icon-ai-technology'; import ACSIcon from '../AllServicesDropdown/icon-acs'; import AnsibleIcon from '../AllServicesDropdown/icon-ansible'; import AppServicesIcon from '../AllServicesDropdown/icon-app-services'; @@ -29,6 +30,7 @@ import AutomationIcon from '@patternfly/react-icons/dist/dynamic/icons/automatio import BellIcon from '@patternfly/react-icons/dist/dynamic/icons/bell-icon'; export enum FavorableIcons { + AITechnologyIcon = 'AITechnologyIcon', ACSIcon = 'ACSIcon', AnsibleIcon = 'AnsibleIcon', AppServicesIcon = 'AppServicesIcon', @@ -60,6 +62,7 @@ export enum FavorableIcons { } const iconEnum: { [key in FavorableIcons]: React.ComponentType } = { + AITechnologyIcon, ACSIcon, AnsibleIcon, AppServicesIcon, From 655dbf8d82a5128982c26479c73f77d12f29d708 Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Fri, 29 Mar 2024 11:22:59 -0500 Subject: [PATCH 11/46] update app feedback text --- locales/translation-template.json | 4 ++-- src/locales/Messages.ts | 4 ++-- src/locales/data.json | 2 +- src/locales/translations.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locales/translation-template.json b/locales/translation-template.json index 79194ddc4..03ef10fc6 100644 --- a/locales/translation-template.json +++ b/locales/translation-template.json @@ -382,8 +382,8 @@ "description": "Use" }, "useAccountNumber": { - "defaultMessage": "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number.", - "description": "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number." + "defaultMessage": "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here.", + "description": "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here." }, "useFeatureInBeta": { "defaultMessage": "Use feature in preview", diff --git a/src/locales/Messages.ts b/src/locales/Messages.ts index 280314e9c..7ef3f4462 100644 --- a/src/locales/Messages.ts +++ b/src/locales/Messages.ts @@ -335,9 +335,9 @@ export default defineMessages({ useAccountNumber: { id: 'useAccountNumber', description: - "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number.", + "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here.", defaultMessage: - "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number.", + "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here.", }, accountNumber: { id: 'accountNumber', diff --git a/src/locales/data.json b/src/locales/data.json index 44ec3d6f6..bdf4e6c00 100644 --- a/src/locales/data.json +++ b/src/locales/data.json @@ -96,7 +96,7 @@ "tryUsingDifferentAccount": "Try using different account", "unableToLoadQuickstartsContent": "Unable to load the quickstarts content.", "use": "Use", - "useAccountNumber": "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number.", + "useAccountNumber": "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here.", "useFeatureInBeta": "Use feature in preview", "userPreferences": "User Preferences", "userResearchTeam": "User Research Team", diff --git a/src/locales/translations.json b/src/locales/translations.json index 495cfd5ac..b1cf380e3 100644 --- a/src/locales/translations.json +++ b/src/locales/translations.json @@ -95,7 +95,7 @@ "tryUsingDifferentAccount": "Try using different account", "unableToLoadQuickstartsContent": "Unable to load the quickstarts content.", "use": "Use", - "useAccountNumber": "Use this number when contacting Red Hat for support. If you don't have any active subscriptions, you will not have an account number.", + "useAccountNumber": "Use this number when contacting Red Hat for support. If you've never had a subscription in your account, you may not see an account number here.", "useFeatureInBeta": "Use feature in preview", "userPreferences": "User Preferences", "userResearchTeam": "User Research Team", From 338458f42f3383b8e30270651688c10ac45e3fdb Mon Sep 17 00:00:00 2001 From: Adonis Puente Date: Fri, 29 Mar 2024 16:54:53 -0400 Subject: [PATCH 12/46] Update sentry api keys --- src/utils/sentry.ts | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/utils/sentry.ts b/src/utils/sentry.ts index c252fd10f..d4d00b56d 100644 --- a/src/utils/sentry.ts +++ b/src/utils/sentry.ts @@ -43,30 +43,11 @@ function initSentry() { let API_KEY; switch (appDetails.app.group) { - case 'insights': - API_KEY = 'https://8b6372cad9604745ae3606bc4adc0060@o271843.ingest.sentry.io/1484024'; - break; - case 'landing': - API_KEY = 'https://d12a17c4a80b43888b30c306d7eb38b4@o271843.ingest.sentry.io/1484026'; - break; - case 'ansible': - API_KEY = 'https://03f062e075954433a296e71f243239fd@o271843.ingest.sentry.io/1769648'; - break; - case 'settings': - API_KEY = 'https://1002f82b7a444d48bc4c98d0b52f2155@o271843.ingest.sentry.io/5216681'; - break; - case 'cost-management': - API_KEY = 'https://61d5da651248485fb89216773932666b@o271843.ingest.sentry.io/5216676'; - break; - case 'migrations': - API_KEY = 'https://9dd048c85e524290b67ad98ff96c53ae@o271843.ingest.sentry.io/5216677'; - break; - case 'subscriptions': - API_KEY = 'https://4bbe4ac7e9fa4507803de69f9453ce5d@o271843.ingest.sentry.io/5216678'; - break; - case 'user-preferences': - API_KEY = 'https://eb32b0236ce045c9b0b9dcc7351c36bb@o271843.ingest.sentry.io/5216687'; + case 'advisor': + API_KEY = 'https://f8eb44de949e487e853185c09340f3cf@o490301.ingest.us.sentry.io/4505397435367424'; break; + default: + API_KEY = 'https://8b6372cad9604745ae3606bc4adc0060@o271843.ingest.sentry.io/1484024'; } // dsn: key From 51ff0737ffe96503bddf04c7b86bbe79f7bc4297 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Tue, 2 Apr 2024 11:19:46 +0200 Subject: [PATCH 13/46] Update request PDF response. --- src/pdf/requestPdf.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pdf/requestPdf.ts b/src/pdf/requestPdf.ts index 5952b93fe..90f3f0533 100644 --- a/src/pdf/requestPdf.ts +++ b/src/pdf/requestPdf.ts @@ -50,10 +50,11 @@ const requestPdf = async (options: { service: string; template: string; filename } = await axios.post<{ statusID: string }>(`/api/crc-pdf-generator/v2/create`, rest); const { status } = await pollStatus(statusID); if (status === 'Generated') { - downloadPDF(`/api/crc-pdf-generator/v2/download/${statusID}`, filename); + return downloadPDF(`/api/crc-pdf-generator/v2/download/${statusID}`, filename); } } catch (error) { console.log(error); + throw new Error('Failed to generate PDF. Check console for more details.'); } }; From 213c86510402207cb73d7302359a16d4ce798280 Mon Sep 17 00:00:00 2001 From: Georgii Karataev Date: Tue, 30 Jan 2024 13:27:46 +0100 Subject: [PATCH 14/46] Update notes on local deployment --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 19b2cf354..a793e204b 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,21 @@ To run a script you have to install dependencies `npm install`. Then you are fre 3. Open browser at `https://stage.foo.redhat.com:1337/` or Open browser at `https://stage.foo.redhat.com:1337/preview`. -### Running chrome as a host application. +### Running chrome with other applications locally -As with any application, chrome can be a host application for others. You can configure the `routes` object in the `webpack.config.js` file as described in the proxy config [docs](https://github.com/RedHatInsights/frontend-components/tree/master/packages/config#routes). +You can spin chrome locally together with other applications. Use `LOCAL_APPS` to list the locally deployed applications. -#### Example +#### Example 1 (using LOCAL_APPS) + +For illustration, to deploy Advisor together with Insights Chrome, you would require to + +1. Run Advisor on any available port with `npm run start -- --port=8004` or `npm run start:beta -- --port=8004`, +2. Run Chrome and list the Advisor's port: `LOCAL_APPS=advisor:8004:http npm run dev` or `LOCAL_APPS=advisor:8004:http npm run dev:beta`. + +#### Example 2 (using devServer route) + +You can also specify deployed applications through devServer.routes field: -For illustration, to locally deploy Advisor for OpenShift together with Insights Chrome, you would require to 1. Run Advisor with `--port=8004` (or any other available port number), 2. Update the webpack config in the following way: ``` From 477993f6c8392fe4572ea2c25a075de3b0899a2a Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 8 Apr 2024 08:55:51 +0200 Subject: [PATCH 15/46] Allow feedback for user with org id --- src/components/Header/Header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 8ff7ff068..808d4baa5 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -64,7 +64,7 @@ export const Header = ({ breadcrumbsProps }: { breadcrumbsProps?: Breadcrumbspro - {user?.identity?.account_number && !isITLessEnv && ReactDOM.createPortal(, document.body)} + {user?.identity?.org_id && !isITLessEnv && ReactDOM.createPortal(, document.body)} {user && isActivationPath && } From 30e2dd31383ba52c66a0492b833328b631a211c8 Mon Sep 17 00:00:00 2001 From: Aneela Chagarlamudi Date: Tue, 9 Apr 2024 20:52:27 +0200 Subject: [PATCH 16/46] Add demo api origins to allowed auth --- src/utils/iqeEnablement.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/iqeEnablement.ts b/src/utils/iqeEnablement.ts index 183db4f57..b1fc97603 100644 --- a/src/utils/iqeEnablement.ts +++ b/src/utils/iqeEnablement.ts @@ -12,7 +12,11 @@ let xhrResults: XMLHttpRequest[] = []; let fetchResults: Record = {}; const DENIED_CROSS_CHECK = 'Access denied from RBAC on cross-access check'; -const AUTH_ALLOWED_ORIGINS = [location.origin, /https:\/\/api(?:\.[a-z]+)?\.openshift(?:[a-z]+)?\.com/]; +const AUTH_ALLOWED_ORIGINS = [ + location.origin, + /https:\/\/api(?:\.[a-z]+)?\.openshift(?:[a-z]+)?\.com/, + /https:\/\/api?\.demo-experience(?:\.[a-z]+)?\.demo?\.redhat?\.com/, +]; const AUTH_EXCLUDED_URLS = [/https:\/\/api(?:\.[a-z]+)?\.openshift(?:[a-z]+)?\.com\/api\/upgrades_info/]; const isExcluded = (target: string) => { From 6e12f31528a0e1aa5278d6ca9dc0d45a54f1353d Mon Sep 17 00:00:00 2001 From: Aneela Chagarlamudi Date: Wed, 10 Apr 2024 10:35:32 +0200 Subject: [PATCH 17/46] Add regional ocm api instances --- src/utils/iqeEnablement.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/iqeEnablement.ts b/src/utils/iqeEnablement.ts index b1fc97603..90c8ce146 100644 --- a/src/utils/iqeEnablement.ts +++ b/src/utils/iqeEnablement.ts @@ -16,6 +16,7 @@ const AUTH_ALLOWED_ORIGINS = [ location.origin, /https:\/\/api(?:\.[a-z]+)?\.openshift(?:[a-z]+)?\.com/, /https:\/\/api?\.demo-experience(?:\.[a-z]+)?\.demo?\.redhat?\.com/, + /https:\/\/api?\.aws?\.ap-southeast-1(?:\.[a-z]+)?\.openshift?\.com/, ]; const AUTH_EXCLUDED_URLS = [/https:\/\/api(?:\.[a-z]+)?\.openshift(?:[a-z]+)?\.com\/api\/upgrades_info/]; From c1d3ecbd0889c078aa5881819b9a9fd906002b3f Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Wed, 3 Apr 2024 11:20:57 +0200 Subject: [PATCH 18/46] Embed VA --- src/components/RootApp/ScalprumRoot.test.js | 4 +++ src/components/Routes/VirtualAssistant.tsx | 27 ++++++++++++++++++++ src/components/Routes/virtual-assistant.scss | 10 ++++++++ src/layouts/DefaultLayout.tsx | 2 ++ 4 files changed, 43 insertions(+) create mode 100644 src/components/Routes/VirtualAssistant.tsx create mode 100644 src/components/Routes/virtual-assistant.scss diff --git a/src/components/RootApp/ScalprumRoot.test.js b/src/components/RootApp/ScalprumRoot.test.js index c0c39b887..8f65705f0 100644 --- a/src/components/RootApp/ScalprumRoot.test.js +++ b/src/components/RootApp/ScalprumRoot.test.js @@ -123,6 +123,10 @@ describe('ScalprumRoot', () => { manifestLocation: '/bar', appName: 'foo', }, + virtualAssistant: { + manifestLocation: '/virtual-assistant', + appName: 'baz', + }, }; mockStore = configureStore(); initialState = { diff --git a/src/components/Routes/VirtualAssistant.tsx b/src/components/Routes/VirtualAssistant.tsx new file mode 100644 index 000000000..ca2d14d70 --- /dev/null +++ b/src/components/Routes/VirtualAssistant.tsx @@ -0,0 +1,27 @@ +import React, { Fragment } from 'react'; +import { Route, Routes } from 'react-router-dom'; +import { ScalprumComponent } from '@scalprum/react-core'; + +import './virtual-assistant.scss'; + +const viableRoutes = ['/', '/insights/*', '/settings/*', '/subscriptions/overview/*', '/subscriptions/inventory/*', '/subscriptions/usage/*']; + +const VirtualAssistant = () => { + return ( + + {viableRoutes.map((route) => ( + + } /> + + } + /> + ))} + + ); +}; + +export default VirtualAssistant; diff --git a/src/components/Routes/virtual-assistant.scss b/src/components/Routes/virtual-assistant.scss new file mode 100644 index 000000000..fd4f0cf22 --- /dev/null +++ b/src/components/Routes/virtual-assistant.scss @@ -0,0 +1,10 @@ +.astro__virtual-assistant { + position: fixed; + bottom: var(--pf-global--spacer--lg); + right: var(--pf-global--spacer--lg); + z-index: 1000; + @media screen and (max-width: 768px) { + bottom: 0; + right: 0; + } +} diff --git a/src/layouts/DefaultLayout.tsx b/src/layouts/DefaultLayout.tsx index bb1f063fd..cec77bcf2 100644 --- a/src/layouts/DefaultLayout.tsx +++ b/src/layouts/DefaultLayout.tsx @@ -28,6 +28,7 @@ import { NavigationProps } from '../components/Navigation'; import { getUrl } from '../hooks/useBundle'; import { useFlag } from '@unleash/proxy-client-react'; import ChromeAuthContext from '../auth/ChromeAuthContext'; +import VirtualAssistant from '../components/Routes/VirtualAssistant'; type ShieldedRootProps = { hideNav?: boolean; @@ -99,6 +100,7 @@ const DefaultLayout: React.FC = ({ hasBanner, selectedAccoun )} + {Footer} From 5ffec93c6c5727215b4b6d68386f85e79348f9b0 Mon Sep 17 00:00:00 2001 From: radekkaluzik <51480040+radekkaluzik@users.noreply.github.com> Date: Thu, 11 Apr 2024 13:28:22 +0200 Subject: [PATCH 19/46] Add help icon with hover-over text next to the filter by tags drop down on Insights pages (#2768) --- .../GroupFilterInputGroup.cy.tsx | 35 ++++++++ .../GlobalFilter/GlobalFilterMenu.tsx | 47 ++--------- .../GlobalFilter/GroupFilterInputGroup.tsx | 84 +++++++++++++++++++ src/locales/Messages.ts | 31 +++++++ 4 files changed, 155 insertions(+), 42 deletions(-) create mode 100644 cypress/component/GroupFilterInputGroup/GroupFilterInputGroup.cy.tsx create mode 100644 src/components/GlobalFilter/GroupFilterInputGroup.tsx diff --git a/cypress/component/GroupFilterInputGroup/GroupFilterInputGroup.cy.tsx b/cypress/component/GroupFilterInputGroup/GroupFilterInputGroup.cy.tsx new file mode 100644 index 000000000..7e2bedfd0 --- /dev/null +++ b/cypress/component/GroupFilterInputGroup/GroupFilterInputGroup.cy.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { IntlProvider } from 'react-intl'; +import GroupFilterInputGroup from '../../../src/components/GlobalFilter/GroupFilterInputGroup'; + +const initialProps = { + isDisabled: false, + filter: { + onChange: () => null, + }, + setIsOpen: () => null, + selectedTags: { + key: {}, + }, +}; + +describe('', () => { + it('should open Popover with Tags help', () => { + function openPopover() { + cy.get('[aria-label="Tags help"]').click(); + cy.contains('Tags').should('exist'); + } + cy.mount( + + + + ); + + openPopover(); + }); +}); diff --git a/src/components/GlobalFilter/GlobalFilterMenu.tsx b/src/components/GlobalFilter/GlobalFilterMenu.tsx index 74d123d74..d43132f14 100644 --- a/src/components/GlobalFilter/GlobalFilterMenu.tsx +++ b/src/components/GlobalFilter/GlobalFilterMenu.tsx @@ -1,5 +1,5 @@ -import React, { FormEvent, Fragment, MouseEventHandler, useContext, useMemo } from 'react'; -import { Group, GroupFilter, GroupType } from '@redhat-cloud-services/frontend-components/ConditionalFilter'; +import React, { Fragment, useContext, useMemo } from 'react'; +import { Group, GroupType } from '@redhat-cloud-services/frontend-components/ConditionalFilter'; import { useIntl } from 'react-intl'; import messages from '../../locales/Messages'; @@ -19,6 +19,7 @@ import { updateSelected } from './globalFilterApi'; import { fetchAllTags } from '../../redux/actions'; import { FlagTagsFilter } from '../../@types/types'; import ChromeAuthContext from '../../auth/ChromeAuthContext'; +import GroupFilterInputGroup from './GroupFilterInputGroup'; export type GlobalFilterMenuGroupKeys = GroupType; @@ -41,9 +42,6 @@ export type FilterMenuGroup = { items: FilterMenuItem[]; }; -/** Create unique hotjar event for selected tags */ -const generateGlobalFilterEvent = (isChecked: boolean, value?: string) => `global_filter_tag_${isChecked ? 'uncheck' : 'check'}_${value}`; - export type SelectedTags = { [key: string]: { [key: string]: @@ -99,6 +97,7 @@ export const GlobalFilterDropdown: React.FunctionComponent (!allowed || isDisabled ? Tooltip : ({ children }: { children: any }) => {children}), [allowed, isDisabled] ); + return ( @@ -114,43 +113,7 @@ export const GlobalFilterDropdown: React.FunctionComponent - ({ - ...group, - items: group.items?.map((item) => ({ - ...item, - onClick: ( - e: FormEvent | MouseEventHandler | undefined, - selected: any, - group: number | undefined, - currItem: boolean | undefined, - groupName: string | undefined, - itemName: string - ) => { - generateGlobalFilterEvent( - (selected?.[groupName as string]?.[itemName as string] as Group)?.isSelected as boolean, - item.value - ); - // item.onClick?.(e, selected, group, currItem, groupName, itemName); - }, - })), - })) || ([] as unknown as any) - } - onChange={filter.onChange} - placeholder={intl.formatMessage(messages.filterByTags)} - isFilterable - onFilter={filter.onFilter || (() => undefined)} - filterBy={filter.filterBy as string} - showMoreTitle={intl.formatMessage(messages.showMore)} - onShowMore={() => setIsOpen(true)} - showMoreOptions={{ - isLoadButton: true, - }} - /> + ) : ( diff --git a/src/components/GlobalFilter/GroupFilterInputGroup.tsx b/src/components/GlobalFilter/GroupFilterInputGroup.tsx new file mode 100644 index 000000000..733bb8023 --- /dev/null +++ b/src/components/GlobalFilter/GroupFilterInputGroup.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import { useIntl } from 'react-intl'; +import messages from '../../locales/Messages'; +import { FilterMenuItemOnChange } from '@redhat-cloud-services/frontend-components/ConditionalFilter/groupFilterConstants'; +import { Group } from '@redhat-cloud-services/frontend-components/ConditionalFilter'; +import { GroupFilter } from '@redhat-cloud-services/frontend-components/ConditionalFilter'; +import { Button, InputGroup, InputGroupItem, Popover, PopoverPosition } from '@patternfly/react-core'; +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons'; +import { FlagTagsFilter } from '../../@types/types'; + +export type GroupFilterInputGroupProps = { + isDisabled: boolean; + filter: { + filterBy?: string | number; + onFilter?: (value: string) => void; + groups?: Group[]; + onChange: FilterMenuItemOnChange; + }; + setIsOpen: (callback?: ((origValue?: boolean) => void) | boolean) => void; + hotjarEventEmitter?: ((eventType: string, eventName: string) => void) | (() => void); + selectedTags: FlagTagsFilter; +}; + +const GroupFilterInputGroup: React.FunctionComponent = ({ filter, isDisabled, selectedTags, setIsOpen }) => { + const intl = useIntl(); + + return ( + + + undefined)} + filterBy={filter.filterBy as string} + showMoreTitle={intl.formatMessage(messages.showMore)} + onShowMore={() => setIsOpen(true)} + showMoreOptions={{ + isLoadButton: true, + }} + /> + + + {intl.formatMessage(messages.filterByTagsPopoverHeader)}} + bodyContent={ +
+ {intl.formatMessage(messages.filterByTagsPopoverContent1)}{' '} + + {intl.formatMessage(messages.filterByTagsPopoverSatelliteLink)} + + {intl.formatMessage(messages.filterByTagsPopoverContent2)}{' '} + + {intl.formatMessage(messages.filterByTagsPopoverCCGLink)} + {' '} + {intl.formatMessage(messages.filterByTagsPopoverContent3)} +
+ } + appendTo={() => document.body} + > + +
+
+
+ ); +}; + +export default GroupFilterInputGroup; diff --git a/src/locales/Messages.ts b/src/locales/Messages.ts index 7ef3f4462..b8f264e16 100644 --- a/src/locales/Messages.ts +++ b/src/locales/Messages.ts @@ -469,6 +469,37 @@ export default defineMessages({ description: 'Placeholder to indicate ', defaultMessage: 'Filter by tags', }, + filterByTagsPopoverHeader: { + id: 'filterByTagsPopoverHeader', + description: 'Popover Header', + defaultMessage: 'Tags', + }, + filterByTagsPopoverCCGLink: { + id: 'filterByTagsPopoverCCGLink', + description: 'Client Configuration Guide link', + defaultMessage: 'Client Configuration Guide', + }, + filterByTagsPopoverSatelliteLink: { + id: 'filterByTagsPopoverSatelliteLink', + description: 'Installing the Satellite inventory upload plugin link', + defaultMessage: 'imported', + }, + filterByTagsPopoverContent1: { + id: 'filterByTagsPopoverContent1', + description: 'Popover Help Content', + defaultMessage: + 'Tagging can be used to classify further and organize your hosts shown within the Insights inventory. If connected to a Satellite, tags from that Satellite can be', + }, + filterByTagsPopoverContent2: { + id: 'filterByTagsPopoverContent2', + description: 'Popover Help Content', + defaultMessage: '. Additionally, you can define your own tags via the Insights-Client configuration. Please see our', + }, + filterByTagsPopoverContent3: { + id: 'filterByTagsPopoverContent3', + description: 'Popover Help Content', + defaultMessage: 'for more details. Please note that Workload tags are automatically added by the Insights service.', + }, reportABug: { id: 'reportABug', description: 'Report a bug', From 61f453202a44c80a3846acbd1f8e45ef2f9160e1 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 11 Apr 2024 14:04:27 +0200 Subject: [PATCH 20/46] Remove insights from VA routes. --- src/components/Routes/VirtualAssistant.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Routes/VirtualAssistant.tsx b/src/components/Routes/VirtualAssistant.tsx index ca2d14d70..285b9eaa5 100644 --- a/src/components/Routes/VirtualAssistant.tsx +++ b/src/components/Routes/VirtualAssistant.tsx @@ -4,7 +4,7 @@ import { ScalprumComponent } from '@scalprum/react-core'; import './virtual-assistant.scss'; -const viableRoutes = ['/', '/insights/*', '/settings/*', '/subscriptions/overview/*', '/subscriptions/inventory/*', '/subscriptions/usage/*']; +const viableRoutes = ['/', '/settings/*', '/subscriptions/overview/*', '/subscriptions/inventory/*', '/subscriptions/usage/*']; const VirtualAssistant = () => { return ( From ff1d94d6a19aacaff13b31fd0d317e2512a049d1 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Fri, 12 Apr 2024 09:23:46 +0200 Subject: [PATCH 21/46] Disable obsolete landing page e2e test --- cypress/e2e/release-gate/landing-page.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/release-gate/landing-page.cy.ts b/cypress/e2e/release-gate/landing-page.cy.ts index 5f60b7ff9..f2a11a3a8 100644 --- a/cypress/e2e/release-gate/landing-page.cy.ts +++ b/cypress/e2e/release-gate/landing-page.cy.ts @@ -1,4 +1,5 @@ -describe('Landing page', () => { +// Landing page has changed +describe.skip('Landing page', () => { it('visit landing page', () => { cy.login(); From 5467df8c76fad37dd54c9699e87a5fe9715cb1d8 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 25 Mar 2024 09:10:59 +0100 Subject: [PATCH 22/46] Use parsed services.json from chrome-service. --- .../AllServicesDropdown.cy.tsx | 4 +- .../AllServicesPage/AllServicesPage.cy.tsx | 2 +- cypress/component/DefaultLayout.cy.js | 2 +- .../helptopics/HelpTopicManager.cy.tsx | 2 +- .../AllServices/allServicesLinks.ts | 4 +- .../AllServicesDropdown/AllServicesMenu.tsx | 2 +- src/hooks/useAllLinks.ts | 104 +++++++++ src/hooks/useAllServices.ts | 218 ++++-------------- src/hooks/useFavoritedServices.ts | 4 +- 9 files changed, 165 insertions(+), 177 deletions(-) create mode 100644 src/hooks/useAllLinks.ts diff --git a/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx b/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx index e18557b5c..f68fb6004 100644 --- a/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx +++ b/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx @@ -29,7 +29,7 @@ describe('', () => { cy.contains('Test link').click(); cy.contains('All services').should('not.exist'); } - cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services.json', [ + cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services-generated.json', [ { id: 'testSection', description: 'Test section description', @@ -90,7 +90,7 @@ describe('', () => { }); it('should automatically minimize tabs after clicking on small screen', () => { - cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services.json', [ + cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services-generated.json', [ { id: 'testSection', description: 'Test section description', diff --git a/cypress/component/AllServicesPage/AllServicesPage.cy.tsx b/cypress/component/AllServicesPage/AllServicesPage.cy.tsx index 03a55d685..850feba23 100644 --- a/cypress/component/AllServicesPage/AllServicesPage.cy.tsx +++ b/cypress/component/AllServicesPage/AllServicesPage.cy.tsx @@ -12,7 +12,7 @@ import { ChromeUser } from '@redhat-cloud-services/types'; describe('', () => { beforeEach(() => { // mock chrome and scalprum generic requests - cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services.json', { + cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services-generated.json', { status: 200, fixture: 'services.json', }); diff --git a/cypress/component/DefaultLayout.cy.js b/cypress/component/DefaultLayout.cy.js index 852fd3758..f992f9413 100644 --- a/cypress/component/DefaultLayout.cy.js +++ b/cypress/component/DefaultLayout.cy.js @@ -105,7 +105,7 @@ describe('', () => { cy.intercept('GET', '/config/chrome/*-navigation.json*', { navItems: [], }); - cy.intercept('GET', '/api/chrome-service/v1/static/stable/stage/services/services.json', []); + cy.intercept('GET', '/api/chrome-service/v1/static/stable/stage/services/services-generated.json', []); }); it('render correctly with few nav items', () => { diff --git a/cypress/component/helptopics/HelpTopicManager.cy.tsx b/cypress/component/helptopics/HelpTopicManager.cy.tsx index f0f754768..ae4c97b91 100644 --- a/cypress/component/helptopics/HelpTopicManager.cy.tsx +++ b/cypress/component/helptopics/HelpTopicManager.cy.tsx @@ -165,7 +165,7 @@ describe('HelpTopicManager', () => { cy.intercept('GET', '/api/chrome-service/v1/static/stable/stage/navigation/*-navigation.json?ts=*', { navItems: [], }); - cy.intercept('GET', '/api/chrome-service/v1/static/stable/stage/services/services.json', []); + cy.intercept('GET', '/api/chrome-service/v1/static/stable/stage/services/services-generated.json', []); }); it.only('should switch help topics drawer content', () => { diff --git a/src/components/AllServices/allServicesLinks.ts b/src/components/AllServices/allServicesLinks.ts index e8b4636ac..91b30f665 100644 --- a/src/components/AllServices/allServicesLinks.ts +++ b/src/components/AllServices/allServicesLinks.ts @@ -27,9 +27,9 @@ export type AllServicesSection = { }; export const isAllServicesGroup = (item: unknown): item is AllServicesGroup => { - return (item as AllServicesGroup).isGroup === true; + return (item as AllServicesGroup)?.isGroup === true; }; export function isAllServicesLink(item: unknown): item is AllServicesLink { - return !!(item as AllServicesLink).href; + return !!(item as AllServicesLink)?.href; } diff --git a/src/components/AllServicesDropdown/AllServicesMenu.tsx b/src/components/AllServicesDropdown/AllServicesMenu.tsx index 65a97dd32..a9b0e9edf 100644 --- a/src/components/AllServicesDropdown/AllServicesMenu.tsx +++ b/src/components/AllServicesDropdown/AllServicesMenu.tsx @@ -119,7 +119,7 @@ const AllServicesMenu = ({ setIsOpen, isOpen, menuRef, linkSections, favoritedSe {activeTabKey === FAVORITE_TAB_ID ? 'Favorites' : selectedService.title} - + {activeTabKey === FAVORITE_TAB_ID ? ( diff --git a/src/hooks/useAllLinks.ts b/src/hooks/useAllLinks.ts new file mode 100644 index 000000000..a383dae0c --- /dev/null +++ b/src/hooks/useAllLinks.ts @@ -0,0 +1,104 @@ +import { useEffect, useState } from 'react'; +import { BundleNav, BundleNavigation, NavItem } from '../@types/types'; +import fetchNavigationFiles from '../utils/fetchNavigationFiles'; +import { evaluateVisibility } from '../utils/isNavItemVisible'; +import { isExpandableNav } from '../utils/common'; + +const getFirstChildRoute = (routes: NavItem[] = []): NavItem | undefined => { + const firstLeaf = routes.find((item) => !item.expandable && item.href); + if (firstLeaf) { + return firstLeaf; + } + let childRoute: NavItem | undefined; + const nestedItems = firstLeaf ? [] : routes.filter((item) => item.expandable); + // make sure to find first deeply nested item + nestedItems.every((item) => { + childRoute = getFirstChildRoute(item.routes); + return !childRoute; + }); + + return childRoute; +}; + +const handleBundleResponse = (bundle: Omit & Partial>): BundleNav => { + const flatLinks = bundle?.navItems?.reduce<(NavItem | NavItem[])[]>((acc, { navItems, routes, expandable, ...rest }) => { + // item is a group + + if (navItems) { + acc.push(...handleBundleResponse({ ...rest, navItems }).links); + return acc; + } + + if (typeof expandable !== 'undefined' && typeof routes !== 'undefined' && typeof rest.id !== 'undefined') { + const childRoute = getFirstChildRoute(routes); + if (childRoute) { + const expandableLink = { + ...childRoute, + title: rest.title, + description: rest.description, + id: rest.id, + }; + acc.push(...routes, expandableLink); + // return acc; + } + } + + // item is an expandable section + if (typeof expandable !== 'undefined' && typeof routes !== 'undefined') { + // console.log('rest:', { ...rest, routes }); + acc.push(...handleBundleResponse({ ...rest, navItems: routes }).links); + return acc; + } + + // regular NavItem + acc.push(rest); + return acc; + }, []); + const bundleFirstLink = getFirstChildRoute(bundle.navItems); + if (bundleFirstLink && bundle.id) { + const bundleLink: NavItem = { + ...bundleFirstLink, + title: bundle.title, + id: bundle.id, + description: bundle.description, + }; + flatLinks.push(bundleLink); + } + return { id: bundle.id, title: bundle.title, links: (flatLinks || []).flat() }; +}; + +const getNavLinks = (navItems: NavItem[]): NavItem[] => { + const links: NavItem[] = []; + navItems.forEach((item) => { + if (isExpandableNav(item)) { + links.concat(getNavLinks(item.routes)); + } else if (item.groupId && item.navItems) { + links.concat(getNavLinks(item.navItems)); + } else { + links.push(item); + } + }); + return links; +}; + +const fetchNavigation = async () => { + const bundlesNavigation = await fetchNavigationFiles().then((data) => data.map(handleBundleResponse)); + const parsedBundles = await Promise.all( + bundlesNavigation.map(async (bundleNav) => ({ + ...bundleNav, + links: (await Promise.all(bundleNav.links.map(evaluateVisibility))).filter(({ isHidden }) => !isHidden), + })) + ); + const allLinks = parsedBundles.map(({ links }) => getNavLinks(links)).flat(); + return allLinks; +}; + +const useAllLinks = () => { + const [allLinks, setAllLinks] = useState([]); + useEffect(() => { + fetchNavigation().then(setAllLinks); + }, []); + return allLinks; +}; + +export default useAllLinks; diff --git a/src/hooks/useAllServices.ts b/src/hooks/useAllServices.ts index ad27653bb..3ff4df3ad 100644 --- a/src/hooks/useAllServices.ts +++ b/src/hooks/useAllServices.ts @@ -1,6 +1,6 @@ import axios, { AxiosResponse } from 'axios'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { BundleNav, BundleNavigation, NavItem } from '../@types/types'; +import { NavItem } from '../@types/types'; import { AllServicesGroup, AllServicesLink, @@ -8,8 +8,7 @@ import { isAllServicesGroup, isAllServicesLink, } from '../components/AllServices/allServicesLinks'; -import { getChromeStaticPathname, isExpandableNav } from '../utils/common'; -import fetchNavigationFiles from '../utils/fetchNavigationFiles'; +import { getChromeStaticPathname } from '../utils/common'; import { evaluateVisibility } from '../utils/isNavItemVisible'; export type AvailableLinks = { @@ -20,94 +19,13 @@ const allServicesFetchCache: { [qeury: string]: Promise< AxiosResponse< (Omit & { - links: (string | AllServicesLink | AllServicesGroup)[]; + links: (AllServicesLink | AllServicesGroup)[]; })[] > >; } = {}; -const getFirstChildRoute = (routes: NavItem[] = []): NavItem | undefined => { - const firstLeaf = routes.find((item) => !item.expandable && item.href); - if (firstLeaf) { - return firstLeaf; - } - let childRoute: NavItem | undefined; - const nestedItems = firstLeaf ? [] : routes.filter((item) => item.expandable); - // make sure to find first deeply nested item - nestedItems.every((item) => { - childRoute = getFirstChildRoute(item.routes); - return !childRoute; - }); - - return childRoute; -}; - -const handleBundleResponse = (bundle: Omit & Partial>): BundleNav => { - const flatLinks = bundle?.navItems?.reduce<(NavItem | NavItem[])[]>((acc, { navItems, routes, expandable, ...rest }) => { - // item is a group - if (navItems) { - return [ - ...acc, - ...handleBundleResponse({ - ...rest, - navItems, - }).links, - ]; - } - - if (expandable && routes && rest.id) { - const childRoute = getFirstChildRoute(routes); - if (childRoute) { - const expandableLink = { - ...childRoute, - title: rest.title, - description: rest.description, - id: rest.id, - }; - return [...acc, ...routes, expandableLink]; - } - } - - // item is an expandable section - if (expandable && routes) { - return [...acc, ...routes]; - } - - // regular NavItem - return [...acc, rest]; - }, []); - const bundleFirstLink = getFirstChildRoute(bundle.navItems); - if (bundleFirstLink && bundle.id) { - const bundleLink: NavItem = { - ...bundleFirstLink, - title: bundle.title, - id: bundle.id, - description: bundle.description, - }; - flatLinks.push(bundleLink); - } - return { id: bundle.id, title: bundle.title, links: (flatLinks || []).flat() }; -}; - -const parseBundlesToObject = (items: NavItem[]): AvailableLinks => - items?.reduce((acc, curr) => { - // make sure nested structures are parsed as well - if (curr.expandable && curr.routes) { - return { - ...acc, - ...parseBundlesToObject(curr.routes), - }; - } - - return curr.id - ? { - ...acc, - [curr.id]: curr, - } - : acc; - }, {}); - -const matchStrings = (value: string, searchTerm: string): boolean => { +const matchStrings = (value = '', searchTerm: string): boolean => { // convert strings to lowercase and remove any white spaces return value.toLocaleLowerCase().replace(/\s/gm, '').includes(searchTerm.toLocaleLowerCase().replace(/\s/gm, '')); }; @@ -155,65 +73,61 @@ const filterAllServicesSections = (allServicesLinks: AllServicesSection[], filte }, []); }; -const findNavItems = ( - items: (string | AllServicesLink | AllServicesGroup)[] = [], - availableLinks: { id?: string; title?: string; items: AvailableLinks }[] -): (AllServicesLink | AllServicesGroup)[] => - items - .map((item) => { - if (isAllServicesGroup(item)) { - return { - ...item, - links: findNavItems(item.links, availableLinks), - }; - } else if (isAllServicesLink(item)) { - return item; +type EnhancedSection = AllServicesSection & { linksQue?: Promise[] }; + +const evaluateLinksVisibility = async (sections: AllServicesSection[]): Promise => { + const que: EnhancedSection[] = []; + sections.forEach((section) => { + const newLinksQue = section.links.map(async (link) => { + if (isAllServicesGroup(link)) { + const nestedLinksQue = await link.links.map(evaluateVisibility); + const links = await Promise.all(nestedLinksQue); + return { ...link, links }; + } else if (isAllServicesLink(link)) { + return evaluateVisibility(link); } - if (typeof item !== 'string') { - return item; + }); + que.push({ ...section, linksQue: newLinksQue }); + }); + + const groupQue = await Promise.all(que); + for (const section of groupQue) { + const links = await Promise.all(section.linksQue ?? []); + section.links = []; + links.forEach((link) => { + if ((isAllServicesGroup(link) || isAllServicesLink(link)) && !(link as NavItem).isHidden) { + if (isAllServicesGroup(link)) { + section.links.push({ ...link, links: link.links.filter((item) => !(item as NavItem).isHidden) }); + } else { + section.links.push(link); + } } - const [bundle, nav] = item.split('.'); - const currBundle = availableLinks.find(({ id }) => id === bundle)?.items || {}; - return Object.values(currBundle).find(({ id }) => id === nav); - }) - .filter(Boolean) as (AllServicesLink | AllServicesGroup)[]; + }); + delete section.linksQue; + } + + return groupQue; +}; const useAllServices = () => { - const [{ ready, error, availableSections, allLinks }, setState] = useState<{ + const [{ ready, error, availableSections }, setState] = useState<{ error: boolean; ready: boolean; - allLinks: NavItem[]; availableSections: AllServicesSection[]; }>({ ready: false, - allLinks: [], error: false, availableSections: [], }); const isMounted = useRef(false); const [filterValue, setFilterValue] = useState(''); - // TODO: move constant once the AppFilter is fully replaced - const fetchNavigation = useCallback( - () => - fetchNavigationFiles() - .then((data) => data.map(handleBundleResponse)) - .then((data) => - Promise.all( - data.map(async (bundleNav) => ({ - ...bundleNav, - links: (await Promise.all(bundleNav.links.map(evaluateVisibility))).filter(({ isHidden }) => !isHidden), - })) - ) - ), - [] - ); const fetchSections = useCallback(async () => { - const query = `${getChromeStaticPathname('services')}/services.json`; + const query = `${getChromeStaticPathname('services')}/services-generated.json`; let request = allServicesFetchCache[query]; if (!request) { request = axios.get< (Omit & { - links: (string | AllServicesLink | AllServicesGroup)[]; + links: (AllServicesLink | AllServicesGroup)[]; })[] >(query); allServicesFetchCache[query] = request; @@ -222,47 +136,28 @@ const useAllServices = () => { const response = await request; // clear the cache delete allServicesFetchCache[query]; - return response.data; + + return evaluateLinksVisibility(response.data); }, []); + const setNavigation = useCallback(async () => { - const bundleItems = await fetchNavigation(); const sections = await fetchSections(); if (isMounted.current) { - const availableLinks = bundleItems.map((bundle) => { - return { - ...bundle, - items: parseBundlesToObject(bundle.links?.flat()), - }; - }); - const allLinks = availableLinks.flatMap((bundle) => bundle.links.flatMap((link) => (isExpandableNav(link) ? link.routes : link))); - const availableSections = sections - .reduce((acc, { links, ...rest }) => { - return [ - ...acc, - { - ...rest, - links: findNavItems(links, availableLinks).filter(Boolean), - }, - ]; - }, []) - .filter(({ links }: AllServicesSection) => { - if (links?.length === 0) { - return false; - } + const availableSections = sections.filter(({ links }: AllServicesSection) => { + if (links?.length === 0) { + return false; + } - return links.filter((item) => isAllServicesLink(item) || (isAllServicesGroup(item) && item.links.length !== 0)).flat().length !== 0; - }); + return links.filter((item) => isAllServicesLink(item) || (isAllServicesGroup(item) && item.links.length !== 0)).flat().length !== 0; + }); setState((prev) => ({ ...prev, - allLinks, availableSections, ready: true, - // no links means all bundle requests have failed - error: availableLinks.flatMap(({ items }) => Object.keys(items || {})).length === 0, })); } - }, [fetchSections, fetchNavigation]); + }, [fetchSections]); useEffect(() => { isMounted.current = true; setNavigation(); @@ -273,26 +168,13 @@ const useAllServices = () => { const linkSections = useMemo(() => filterAllServicesSections(availableSections, filterValue), [ready, filterValue]); - // Provide a flat list of all available links - const servicesLinks = useMemo( - () => - linkSections - .flatMap(({ links }) => links as (AllServicesGroup | AllServicesLink)[]) - .flatMap((item) => (isAllServicesGroup(item) ? item.links : item)) - .flat(), - [linkSections] - ); - return { linkSections, - allLinks, - servicesLinks, error, ready, availableSections, filterValue, setFilterValue, - findNavItems, }; }; diff --git a/src/hooks/useFavoritedServices.ts b/src/hooks/useFavoritedServices.ts index 98ab41317..b5f2683ff 100644 --- a/src/hooks/useFavoritedServices.ts +++ b/src/hooks/useFavoritedServices.ts @@ -6,10 +6,12 @@ import { NavItem, Navigation } from '../@types/types'; import { findNavLeafPath } from '../utils/common'; import useFavoritePagesWrapper from './useFavoritePagesWrapper'; import { isAllServicesLink } from '../components/AllServices/allServicesLinks'; +import useAllLinks from './useAllLinks'; const useFavoritedServices = () => { const { favoritePages } = useFavoritePagesWrapper(); - const { allLinks, availableSections } = useAllServices(); + const { availableSections } = useAllServices(); + const allLinks = useAllLinks(); const [bundles, setBundles] = useState([]); const fakeBundle: NavItem[] = useMemo(() => { From 6a30dfdacd9356f4093ae19ab31ef4741615ab3d Mon Sep 17 00:00:00 2001 From: Filip Hlavac Date: Mon, 15 Apr 2024 15:03:38 +0200 Subject: [PATCH 23/46] Add ouiaIds to all services tabs --- src/components/AllServicesDropdown/AllServicesTabs.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/AllServicesDropdown/AllServicesTabs.tsx b/src/components/AllServicesDropdown/AllServicesTabs.tsx index ecb65b396..b88990a85 100644 --- a/src/components/AllServicesDropdown/AllServicesTabs.tsx +++ b/src/components/AllServicesDropdown/AllServicesTabs.tsx @@ -78,6 +78,7 @@ const AllServicesTabs = ({ ouiaId={'all-services-tabs'} > { handleTabClick?.(e, FAVORITE_TAB_ID); }} @@ -95,6 +96,7 @@ const AllServicesTabs = ({ {/* The tabs children type is busted and does not accept array. Hence the fragment wrapper */} {linkSections.map((section, index) => ( {section.title}} From 39c311eda556e53d7c1100394608ee4c030ffa8b Mon Sep 17 00:00:00 2001 From: Filip Hlavac Date: Mon, 15 Apr 2024 15:22:10 +0200 Subject: [PATCH 24/46] Add ouia id to all services toggle --- src/components/AllServicesDropdown/AllServicesDropdown.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/AllServicesDropdown/AllServicesDropdown.tsx b/src/components/AllServicesDropdown/AllServicesDropdown.tsx index bf391792f..a251ed3f5 100644 --- a/src/components/AllServicesDropdown/AllServicesDropdown.tsx +++ b/src/components/AllServicesDropdown/AllServicesDropdown.tsx @@ -69,6 +69,7 @@ const AllServicesDropdown = () => { const toggle = ( Date: Wed, 17 Apr 2024 12:09:31 +0200 Subject: [PATCH 25/46] Send preview context value to unleash. --- src/components/FeatureFlags/FeatureFlagsProvider.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/FeatureFlags/FeatureFlagsProvider.tsx b/src/components/FeatureFlags/FeatureFlagsProvider.tsx index a9b03fbee..efe3de727 100644 --- a/src/components/FeatureFlags/FeatureFlagsProvider.tsx +++ b/src/components/FeatureFlags/FeatureFlagsProvider.tsx @@ -4,6 +4,7 @@ import { DeepRequired } from 'utility-types'; import { captureException } from '@sentry/react'; import * as Sentry from '@sentry/react'; import ChromeAuthContext, { ChromeAuthContextValue } from '../../auth/ChromeAuthContext'; +import { isBeta } from '../../utils/common'; const config: IFlagProvider['config'] = { url: `${document.location.origin}/api/featureflags/v0`, @@ -67,6 +68,11 @@ const FeatureFlagsProvider: React.FC = ({ children }) = new UnleashClient({ ...config, context: { + // TODO: instead of the isBeta, use the internal chrome state + // the unleash context is not generic, look for issue/PR in the unleash repo or create one + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + 'platform.chrome.ui.preview': isBeta(), userId: user?.identity.internal?.account_id, ...(user ? { From 48d1f36482af74ccc9e491f94b0e16188820317a Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 18 Apr 2024 11:02:01 +0200 Subject: [PATCH 26/46] Use link title based default document titles. --- src/components/RootApp/ScalprumRoot.tsx | 3 +++ src/hooks/useTabName.ts | 32 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/hooks/useTabName.ts diff --git a/src/components/RootApp/ScalprumRoot.tsx b/src/components/RootApp/ScalprumRoot.tsx index 7133d4715..3ded2a6e1 100644 --- a/src/components/RootApp/ScalprumRoot.tsx +++ b/src/components/RootApp/ScalprumRoot.tsx @@ -34,6 +34,7 @@ import { populateNotifications } from '../../redux/actions'; import useTrackPendoUsage from '../../hooks/useTrackPendoUsage'; import ChromeAuthContext from '../../auth/ChromeAuthContext'; import { onRegisterModuleWriteAtom } from '../../state/atoms/chromeModuleAtom'; +import useTabName from '../../hooks/useTabName'; const ProductSelection = lazy(() => import('../Stratosphere/ProductSelection')); @@ -64,6 +65,8 @@ const ScalprumRoot = memo( useChromeServiceEvents(); // track pendo usage useTrackPendoUsage(); + // setting default tab title + useTabName(); async function getNotifications() { try { diff --git a/src/hooks/useTabName.ts b/src/hooks/useTabName.ts new file mode 100644 index 000000000..b33ef0eba --- /dev/null +++ b/src/hooks/useTabName.ts @@ -0,0 +1,32 @@ +import { useAtomValue } from 'jotai'; +import { useLocation } from 'react-router-dom'; + +import { activeModuleAtom } from '../state/atoms/activeModuleAtom'; +import useBreadcrumbsLinks from './useBreadcrumbsLinks'; +import useBundle from './useBundle'; +import { useEffect, useMemo } from 'react'; + +const useTabName = () => { + const { bundleTitle } = useBundle(); + const activeModule = useAtomValue(activeModuleAtom); + const { pathname } = useLocation(); + const fragments = useBreadcrumbsLinks(); + + const title = useMemo(() => { + const fragmentsWithoutBundle = fragments + .slice(1) // remove the bundle + .slice(-2) // limit to closest link parent + .map(({ title }) => title); + // toReversed is not properly supported in all envs we run this code + fragmentsWithoutBundle.reverse(); + return `${fragmentsWithoutBundle.join(' - ')} | ${bundleTitle}`; + }, [activeModule, pathname, fragments]); + useEffect(() => { + // sometimes the nav files are not loaded yet and the first section is empty + if (title.split(' | ')?.[0].length > 1) { + document.title = title; + } + }, [title]); +}; + +export default useTabName; From 3faa5581b4d035d03eb9e172a6ddba5426e068bc Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Fri, 19 Apr 2024 10:25:48 +0200 Subject: [PATCH 27/46] Add orgId to unleash context. --- src/components/FeatureFlags/FeatureFlagsProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/FeatureFlags/FeatureFlagsProvider.tsx b/src/components/FeatureFlags/FeatureFlagsProvider.tsx index efe3de727..f51a3f2a6 100644 --- a/src/components/FeatureFlags/FeatureFlagsProvider.tsx +++ b/src/components/FeatureFlags/FeatureFlagsProvider.tsx @@ -74,6 +74,7 @@ const FeatureFlagsProvider: React.FC = ({ children }) = // @ts-ignore 'platform.chrome.ui.preview': isBeta(), userId: user?.identity.internal?.account_id, + orgId: user?.identity.internal?.org_id, ...(user ? { properties: { From a3561eb3c34cc672bd0fb7d06a3236fbe0526699 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 22 Apr 2024 13:20:01 +0200 Subject: [PATCH 28/46] Update PF to 5.3 --- package-lock.json | 618 ++++++++++++++++--------- package.json | 12 +- src/components/GlobalFilter/tagsApi.ts | 2 +- 3 files changed, 394 insertions(+), 238 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0811f16eb..116cc7c4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,12 +14,12 @@ "@data-driven-forms/react-form-renderer": "^3.22.1", "@formatjs/cli": "4.8.4", "@openshift/dynamic-plugin-sdk": "^5.0.1", - "@patternfly/patternfly": "^5.2.1", - "@patternfly/quickstarts": "5.2.0-prerelease.3", - "@patternfly/react-charts": "^7.1.2", - "@patternfly/react-core": "^5.2.1", - "@patternfly/react-icons": "^5.2.1", - "@patternfly/react-tokens": "^5.2.1", + "@patternfly/patternfly": "^5.3.0", + "@patternfly/quickstarts": "^5.3.0", + "@patternfly/react-charts": "^7.3.0", + "@patternfly/react-core": "^5.3.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "@redhat-cloud-services/chrome": "^1.0.9", "@redhat-cloud-services/entitlements-client": "1.2.0", "@redhat-cloud-services/frontend-components": "^4.2.2", @@ -1967,6 +1967,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, "optional": true, "engines": { "node": ">=0.1.90" @@ -2070,6 +2071,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", + "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -2098,6 +2100,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -2128,6 +2131,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, "dependencies": { "debug": "^3.1.0", "lodash.once": "^4.1.1" @@ -2137,6 +2141,7 @@ "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" } @@ -4106,14 +4111,14 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@patternfly/patternfly": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.2.1.tgz", - "integrity": "sha512-n5xFjyj1J4eIFZ7XeU6K44POKRAuDlO5yALPbn084y+jPy1j861AaQ+zIUbzCi4IzBlHrvoXVKij7p1zy7Ditg==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.3.0.tgz", + "integrity": "sha512-93uWA15bOJDgu8NF2iReWbbNtWdtM+v7iaDpK33mJChgej+whiFpGLtQPI2jFk1aVW3rDpbt4qm4OaNinpzSsg==" }, "node_modules/@patternfly/quickstarts": { - "version": "5.2.0-prerelease.3", - "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.2.0-prerelease.3.tgz", - "integrity": "sha512-WNBKV841bNAr4oty31w2vrTvh+PdNvMnT7RbdpYGwW3ubgr9Za2r/ZH2qO4cJPdnMfjTySzhXTVKxFtMlIsoDg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.3.0.tgz", + "integrity": "sha512-2+nKrLag8z8p9d9caQvlSMqcMGkfd8uRl54SGykpjkdp7UDT6VER/nsb4gAZkJA7udrY+yJ8EockNFY6eCiGbA==", "dependencies": { "@patternfly/react-catalog-view-extension": "^5.0.0", "dompurify": "^2.2.6", @@ -4140,32 +4145,32 @@ } }, "node_modules/@patternfly/react-charts": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.1.2.tgz", - "integrity": "sha512-lNusTmvNoLKyJdq6mOMMb2AwEYz9RXLicbPwvW/98ILKOB9UTbHYobVbHF1hqj2fj05uwhGbjtiTP5XZsmXiJg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.3.0.tgz", + "integrity": "sha512-J6d/bFolI3zUOvJoK4lEveNeXZeJNfBq+iXgQ/mImESyW0H7MSebMcVB4d+NC6JX0QykuaOEn/7YMJMU9K73tw==", "dependencies": { - "@patternfly/react-styles": "^5.1.2", - "@patternfly/react-tokens": "^5.1.2", + "@patternfly/react-styles": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "hoist-non-react-statics": "^3.3.0", - "lodash": "^4.17.19", + "lodash": "^4.17.21", "tslib": "^2.5.0", - "victory-area": "^36.6.11", - "victory-axis": "^36.6.11", - "victory-bar": "^36.6.11", - "victory-box-plot": "^36.6.11", - "victory-chart": "^36.6.11", - "victory-core": "^36.6.11", - "victory-create-container": "^36.6.11", - "victory-cursor-container": "^36.6.11", - "victory-group": "^36.6.11", - "victory-legend": "^36.6.11", - "victory-line": "^36.6.11", - "victory-pie": "^36.6.11", - "victory-scatter": "^36.6.11", - "victory-stack": "^36.6.11", - "victory-tooltip": "^36.6.11", - "victory-voronoi-container": "^36.6.11", - "victory-zoom-container": "^36.6.11" + "victory-area": "^36.9.1", + "victory-axis": "^36.9.1", + "victory-bar": "^36.9.1", + "victory-box-plot": "^36.9.1", + "victory-chart": "^36.9.1", + "victory-core": "^36.9.1", + "victory-create-container": "^36.9.1", + "victory-cursor-container": "^36.9.1", + "victory-group": "^36.9.1", + "victory-legend": "^36.9.1", + "victory-line": "^36.9.1", + "victory-pie": "^36.9.1", + "victory-scatter": "^36.9.1", + "victory-stack": "^36.9.1", + "victory-tooltip": "^36.9.1", + "victory-voronoi-container": "^36.9.1", + "victory-zoom-container": "^36.9.1" }, "peerDependencies": { "react": "^17 || ^18", @@ -4197,13 +4202,13 @@ } }, "node_modules/@patternfly/react-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.2.1.tgz", - "integrity": "sha512-SWQHALhcjxjmwcIJ6V3tG6V7a2M0WkkUbc6F8mSPk6l9q6j3f+WvZ9HqgzVA+h+Q12UbtIrlQvgUx7pAxZekkg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.3.0.tgz", + "integrity": "sha512-nMf8yrul3u+4+ch7IMsE+/3Rzmor8/yEUk8zzD9bYGRxjwniu1RqCF8NdgPvMw2C7Hz7xtpwsgXDfG4n8qd12g==", "dependencies": { - "@patternfly/react-icons": "^5.2.1", - "@patternfly/react-styles": "^5.2.1", - "@patternfly/react-tokens": "^5.2.1", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-styles": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "focus-trap": "7.5.2", "react-dropzone": "^14.2.3", "tslib": "^2.5.0" @@ -4214,18 +4219,18 @@ } }, "node_modules/@patternfly/react-icons": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.2.1.tgz", - "integrity": "sha512-aeJ0X+U2NDe8UmI5eQiT0iuR/wmUq97UkDtx3HoZcpRb9T6eUBfysllxjRqHS8rOOspdU8OWq+CUhQ/E2ZDibg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-oBdaK4Gz7yivNE7jQg46sPzfZakg7oxo5aSMLc0N6haOmDEegiTurNex+h+/z0oBPqzZC+cIQRaBeXEgXGwc9Q==", "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" } }, "node_modules/@patternfly/react-styles": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.2.1.tgz", - "integrity": "sha512-GT96hzI1QenBhq6Pfc51kxnj9aVLjL1zSLukKZXcYVe0HPOy0BFm90bT1Fo4e/z7V9cDYw4SqSX1XLc3O4jsTw==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.3.0.tgz", + "integrity": "sha512-/EdkURW+v7Rzw/CiEqL+NfGtLvLMGIwOEyDhvlMDbRip2usGw4HLZv3Bep0cJe29zOeY27cDVZDM1HfyXLebtw==" }, "node_modules/@patternfly/react-table": { "version": "5.1.2", @@ -4245,9 +4250,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.2.1.tgz", - "integrity": "sha512-8GYz/jnJTGAWUJt5eRAW5dtyiHPKETeFJBPGHaUQnvi/t1ZAkoy8i4Kd/RlHsDC7ktiu813SKCmlzwBwldAHKg==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.3.0.tgz", + "integrity": "sha512-24ZY5hgwt11InW3XtINM5p9Fo1hDiVor6Q4uphPZh8Mt89AsZZw1UweTaGg54I0Ah2Wzv6rkQy51LX7tZtIwjQ==" }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.11", @@ -5138,23 +5143,23 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@redhat-cloud-services/frontend-components-utilities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.2.tgz", - "integrity": "sha512-LUAaJwpi8EmyrNrGum53HcSpO0rrwvXkdEmaXjfooRlvVtLz8twsjaiM2jFfqWXbZMq43gQufn/wy8nquRoq6w==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/frontend-components-utilities/-/frontend-components-utilities-4.0.10.tgz", + "integrity": "sha512-SAMXD9ciFk8aDXjt+9FnaY6VP+6RTuNswFn7a+TNROBIa0CNqb7O0x5y0gZs/Pc67xrbuxF9K5RG98qwLGdNOQ==", "dependencies": { + "@redhat-cloud-services/rbac-client": "^1.0.100", "@redhat-cloud-services/types": "^0.0.24", "@sentry/browser": "^5.30.0", "awesome-debounce-promise": "^2.1.0", - "axios": "^0.27.2", + "axios": "^0.28.1", "commander": "^2.20.3", "mkdirp": "^1.0.4", + "p-all": "^5.0.0", "react-content-loader": "^6.2.0" }, "peerDependencies": { "@patternfly/react-core": "^5.0.0", "@patternfly/react-table": "^5.0.0", - "@redhat-cloud-services/rbac-client": "^1.0.100", - "cypress": ">=12.0.0 < 14.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": ">=7.0.0", @@ -5166,15 +5171,6 @@ "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-utilities/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, "node_modules/@redhat-cloud-services/frontend-components-utilities/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -9268,9 +9264,9 @@ } }, "node_modules/@types/d3-path": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz", - "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" }, "node_modules/@types/d3-scale": { "version": "4.0.8", @@ -9684,12 +9680,14 @@ "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==" + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true }, "node_modules/@types/sizzle": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", - "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==" + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true }, "node_modules/@types/sockjs": { "version": "0.3.36", @@ -9760,6 +9758,7 @@ "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, "optional": true, "dependencies": { "@types/node": "*" @@ -10911,6 +10910,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -10996,6 +10996,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, "engines": { "node": ">=6" } @@ -11004,6 +11005,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, "dependencies": { "type-fest": "^0.21.3" }, @@ -11030,6 +11032,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -11087,6 +11090,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, "funding": [ { "type": "github", @@ -11260,6 +11264,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -11281,6 +11286,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, "engines": { "node": ">=0.8" } @@ -11376,6 +11382,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { "node": ">=8" } @@ -11383,7 +11390,8 @@ "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true }, "node_modules/asynciterator.prototype": { "version": "1.0.0", @@ -11403,6 +11411,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, "engines": { "node": ">= 4.0.0" } @@ -11467,6 +11476,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, "engines": { "node": "*" } @@ -11474,12 +11484,13 @@ "node_modules/aws4": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true }, "node_modules/axios": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.0.tgz", - "integrity": "sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz", + "integrity": "sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -11844,6 +11855,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -11917,7 +11929,8 @@ "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==" + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true }, "node_modules/bluebird": { "version": "3.7.1", @@ -12192,6 +12205,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, "engines": { "node": "*" } @@ -12226,6 +12240,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, "engines": { "node": ">=6" } @@ -12336,7 +12351,8 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true }, "node_modules/chalk": { "version": "2.4.2", @@ -12430,6 +12446,7 @@ "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -12486,6 +12503,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, "funding": [ { "type": "github", @@ -12532,6 +12550,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, "engines": { "node": ">=6" } @@ -12555,6 +12574,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { "restore-cursor": "^3.1.0" }, @@ -12578,6 +12598,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, "dependencies": { "string-width": "^4.2.0" }, @@ -12592,6 +12613,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -12693,7 +12715,8 @@ "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -12724,6 +12747,7 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, "engines": { "node": ">=4.0.0" } @@ -12884,7 +12908,8 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true }, "node_modules/cosmiconfig": { "version": "7.1.0", @@ -13069,6 +13094,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -13362,6 +13388,7 @@ "version": "13.6.2", "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.2.tgz", "integrity": "sha512-TW3bGdPU4BrfvMQYv1z3oMqj71YI4AlgJgnrycicmPZAXtvywVFZW9DAToshO65D97rCWfG/kqMFsYB6Kp91gQ==", + "dev": true, "hasInstallScript": true, "dependencies": { "@cypress/request": "^3.0.0", @@ -13431,6 +13458,7 @@ "version": "18.19.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.4.tgz", "integrity": "sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -13439,6 +13467,7 @@ "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" }, @@ -13452,12 +13481,14 @@ "node_modules/cypress/node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "node_modules/cypress/node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -13481,6 +13512,7 @@ "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" @@ -13496,6 +13528,7 @@ "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" }, @@ -13507,6 +13540,7 @@ "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" }, @@ -13517,12 +13551,14 @@ "node_modules/cypress/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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/cypress/node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, "engines": { "node": ">= 6" } @@ -13531,6 +13567,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -13545,6 +13582,7 @@ "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" } @@ -13553,6 +13591,7 @@ "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" }, @@ -13564,6 +13603,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -13578,6 +13618,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -13591,7 +13632,8 @@ "node_modules/cypress/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/d3-array": { "version": "3.2.4", @@ -13717,6 +13759,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -13741,7 +13784,8 @@ "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "dev": true }, "node_modules/debounce": { "version": "1.2.1", @@ -13758,6 +13802,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -14542,6 +14587,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -14607,6 +14653,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "dependencies": { "once": "^1.4.0" } @@ -14628,6 +14675,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -14843,6 +14891,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -15303,7 +15352,8 @@ "node_modules/eventemitter2": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==" + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true }, "node_modules/eventemitter3": { "version": "4.0.7", @@ -15323,6 +15373,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -15345,6 +15396,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, "dependencies": { "pify": "^2.2.0" }, @@ -15356,6 +15408,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -15478,12 +15531,14 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -15503,6 +15558,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, "engines": [ "node >=0.6.0" ] @@ -15603,6 +15659,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, "dependencies": { "pend": "~1.2.0" } @@ -15611,6 +15668,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -15917,6 +15975,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, "engines": { "node": "*" } @@ -16254,6 +16313,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -16284,6 +16344,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, "dependencies": { "async": "^3.2.0" } @@ -16292,6 +16353,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -16349,6 +16411,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, "dependencies": { "ini": "2.0.0" }, @@ -16921,6 +16984,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^2.0.2", @@ -16947,6 +17011,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, "engines": { "node": ">=8.12.0" } @@ -17001,6 +17066,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, "funding": [ { "type": "github", @@ -17148,6 +17214,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, "engines": { "node": ">=8" } @@ -17176,6 +17243,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, "engines": { "node": ">=10" } @@ -17395,6 +17463,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, "dependencies": { "ci-info": "^3.2.0" }, @@ -17466,6 +17535,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -17514,6 +17584,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -17649,6 +17720,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -17734,6 +17806,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { "node": ">=8" }, @@ -17789,12 +17862,14 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, "engines": { "node": ">=10" }, @@ -17891,7 +17966,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isobject": { "version": "3.0.1", @@ -17905,7 +17981,8 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -21099,7 +21176,8 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true }, "node_modules/jsdom": { "version": "21.1.2", @@ -21179,7 +21257,8 @@ "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -21256,6 +21335,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, "engines": [ "node >=0.6.0" ], @@ -21506,6 +21586,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, "engines": { "node": "> 0.8" } @@ -21550,6 +21631,7 @@ "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -21576,6 +21658,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -21716,12 +21799,14 @@ "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -21737,6 +21822,7 @@ "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" }, @@ -21751,6 +21837,7 @@ "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" @@ -21766,6 +21853,7 @@ "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" }, @@ -21776,12 +21864,14 @@ "node_modules/log-symbols/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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/log-symbols/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" } @@ -21790,6 +21880,7 @@ "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" }, @@ -21801,6 +21892,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -21818,6 +21910,7 @@ "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" }, @@ -21832,6 +21925,7 @@ "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" }, @@ -21842,12 +21936,14 @@ "node_modules/log-update/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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -21864,6 +21960,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -22167,7 +22264,8 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", @@ -22233,6 +22331,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "engines": { "node": ">=6" } @@ -22446,7 +22545,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -22783,6 +22883,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "dependencies": { "path-key": "^3.0.0" }, @@ -23132,6 +23233,7 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -23294,6 +23396,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -23443,7 +23546,33 @@ "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==" + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "node_modules/p-all": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-all/-/p-all-5.0.0.tgz", + "integrity": "sha512-pofqu/1FhCVa+78xNAptCGc9V45exFz2pvBRyIvgXkNM0Rh18Py7j8pQuSjA+zpabI46v9hRjNWmL9EAFcEbpw==", + "dependencies": { + "p-map": "^6.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-all/node_modules/p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/p-finally": { "version": "1.0.0", @@ -23745,6 +23874,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -23806,12 +23936,14 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true }, "node_modules/pf-4-styles": { "name": "@patternfly/patternfly", @@ -24508,6 +24640,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, "engines": { "node": ">=6" }, @@ -24576,6 +24709,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, "engines": { "node": ">= 0.6.0" } @@ -24651,17 +24785,20 @@ "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==" + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -24671,6 +24808,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -24695,6 +24833,7 @@ "version": "6.10.4", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, "dependencies": { "side-channel": "^1.0.4" }, @@ -24708,7 +24847,8 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -25443,6 +25583,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, "dependencies": { "throttleit": "^1.0.0" } @@ -25500,7 +25641,8 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.8", @@ -25614,6 +25756,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -25651,7 +25794,8 @@ "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true }, "node_modules/rgb-hex": { "version": "4.1.0", @@ -25757,6 +25901,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -25783,6 +25928,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -25815,7 +25961,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "node_modules/sanitize-html": { "version": "2.12.1", @@ -26199,6 +26346,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -26210,6 +26358,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -26252,6 +26401,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -26299,6 +26449,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -26312,6 +26463,7 @@ "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" }, @@ -26326,6 +26478,7 @@ "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" }, @@ -26336,7 +26489,8 @@ "node_modules/slice-ansi/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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/snake-case": { "version": "2.1.0", @@ -26538,6 +26692,7 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -26657,6 +26812,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -26766,6 +26922,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -26786,6 +26943,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, "engines": { "node": ">=6" } @@ -27091,6 +27249,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -27139,6 +27298,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, "dependencies": { "rimraf": "^3.0.0" }, @@ -27150,6 +27310,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -27213,6 +27374,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -27227,6 +27389,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, "engines": { "node": ">= 4.0.0" } @@ -27331,6 +27494,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -27341,7 +27505,8 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true }, "node_modules/type-check": { "version": "0.4.0", @@ -27368,6 +27533,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, "engines": { "node": ">=10" }, @@ -27493,7 +27659,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unfetch": { "version": "4.2.0", @@ -27603,6 +27770,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, "engines": { "node": ">=8" } @@ -27680,6 +27848,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -27802,6 +27971,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, "engines": [ "node >=0.6.0" ], @@ -27845,69 +28015,64 @@ } }, "node_modules/victory-area": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-area/-/victory-area-36.7.0.tgz", - "integrity": "sha512-mRPO/Dmx1DEBvAaFBUZRaiABKQQlsKney4kL3yUXcWU7yCltAfE7T1mgLLxfRAQoW1kILnC1dt7IZOvANhH6Lw==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-area/-/victory-area-36.9.2.tgz", + "integrity": "sha512-32aharvPf2RgdQB+/u1j3/ajYFNH/7ugLX9ZRpdd65gP6QEbtXL+58gS6CxvFw6gr/y8a0xMlkMKkpDVacXLpw==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0", - "victory-vendor": "^36.7.0" + "victory-core": "^36.9.2", + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-axis": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-axis/-/victory-axis-36.7.0.tgz", - "integrity": "sha512-Q2QbzKQtcpIh7/EYT9u3i3xAKs6mD7FoxgibtpjNIG64C4xkW/6fe2TjqajdGfcmlqaqZohargmCr3UquUelsQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-axis/-/victory-axis-36.9.2.tgz", + "integrity": "sha512-4Odws+IAjprJtBg2b2ZCxEPgrQ6LgIOa22cFkGghzOSfTyNayN4M3AauNB44RZyn2O/hDiM1gdBkEg1g9YDevQ==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-bar": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-bar/-/victory-bar-36.7.0.tgz", - "integrity": "sha512-kg+mk2mq5c71h9L/VucWJ72efyBRlax5pbxPDoqs1WNiTLe5HhXvgTE6JaSqCg9PGoaQriKJ98yNSg+pp0ktVA==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-bar/-/victory-bar-36.9.2.tgz", + "integrity": "sha512-R3LFoR91FzwWcnyGK2P8DHNVv9gsaWhl5pSr2KdeNtvLbZVEIvUkTeVN9RMBMzterSFPw0mbWhS1Asb3sV6PPw==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0", - "victory-vendor": "^36.7.0" + "victory-core": "^36.9.2", + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-box-plot": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-box-plot/-/victory-box-plot-36.7.0.tgz", - "integrity": "sha512-P7B1wMPsLI3vByYpaNSUsYPLBg2sf7iTmVXjnGQdJwtaInu0R2QJlJnHKVUHb5Nw9Ew1rYMd/rY2hgAru0c+Ng==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-box-plot/-/victory-box-plot-36.9.2.tgz", + "integrity": "sha512-nUD45V/YHDkAKZyak7YDsz+Vk1F9N0ica3jWQe0AY0JqD9DleHa8RY/olSVws26kLyEj1I+fQqva6GodcLaIqQ==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0", - "victory-vendor": "^36.7.0" + "victory-core": "^36.9.2", + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-brush-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-brush-container/-/victory-brush-container-36.7.0.tgz", - "integrity": "sha512-qUQYrSqI7xedly2BskmQMRhg02UhYlBn9GlCruYHY+og2xF1CWNT8KBBVXuN1BO6Y+3H3ypi5NY/Ray/RR+ZDg==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-brush-container/-/victory-brush-container-36.9.2.tgz", + "integrity": "sha512-KcQjzFeo40tn52cJf1A02l5MqeR9GKkk3loDqM3T2hfi1PCyUrZXEUjGN5HNlLizDRvtcemaAHNAWlb70HbG/g==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" @@ -28121,61 +28286,58 @@ } }, "node_modules/victory-chart": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-chart/-/victory-chart-36.7.0.tgz", - "integrity": "sha512-5Q4hB4kROkQhD8GbzLQMnLeAhx9NvzttLz4wEDyzG5/fl/frN/dl41mjsjk3Uj2ARQjhG0gYqMuYRlO1J13QJw==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-chart/-/victory-chart-36.9.2.tgz", + "integrity": "sha512-dMNcS0BpqL3YiGvI4BSEmPR76FCksCgf3K4CSZ7C/MGyrElqB6wWwzk7afnlB1Qr71YIHXDmdwsPNAl/iEwTtA==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-axis": "^36.7.0", - "victory-core": "^36.7.0", - "victory-polar-axis": "^36.7.0", - "victory-shared-events": "^36.7.0" + "victory-axis": "^36.9.2", + "victory-core": "^36.9.2", + "victory-polar-axis": "^36.9.2", + "victory-shared-events": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-core": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-core/-/victory-core-36.7.0.tgz", - "integrity": "sha512-5dSYy0m4t78qmOX1ouDEmK6KOJ5tsB1ILDAZLqzXxvH0PzLp961UaVacij8Qb6pJja8TtJ6w4J1Em1ethc4aGQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-core/-/victory-core-36.9.2.tgz", + "integrity": "sha512-AzmMy+9MYMaaRmmZZovc/Po9urHne3R3oX7bbXeQdVuK/uMBrlPiv11gVJnuEH2SXLVyep43jlKgaBp8ef9stQ==", "dependencies": { "lodash": "^4.17.21", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-vendor": "^36.7.0" + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-create-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-create-container/-/victory-create-container-36.7.0.tgz", - "integrity": "sha512-mz9vYjMJ3u7YrUEOXspztIRRfZll8krXsUgmwPou09y86NN/lVGj0gQ3uttnHpAIGGsel3Kj3LqFbjdcxK1AHQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-create-container/-/victory-create-container-36.9.2.tgz", + "integrity": "sha512-uA0dh1R0YDzuXyE/7StZvq4qshet+WYceY7R1UR5mR/F9079xy+iQsa2Ca4h97/GtVZoLO6r1eKLWBt9TN+U7A==", "dependencies": { "lodash": "^4.17.19", - "victory-brush-container": "^36.7.0", - "victory-core": "^36.7.0", - "victory-cursor-container": "^36.7.0", - "victory-selection-container": "^36.7.0", - "victory-voronoi-container": "^36.7.0", - "victory-zoom-container": "^36.7.0" + "victory-brush-container": "^36.9.2", + "victory-core": "^36.9.2", + "victory-cursor-container": "^36.9.2", + "victory-selection-container": "^36.9.2", + "victory-voronoi-container": "^36.9.2", + "victory-zoom-container": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-cursor-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-cursor-container/-/victory-cursor-container-36.7.0.tgz", - "integrity": "sha512-I2oWTfm/HQD+YzjvCWV5j0FPxODRhvqMYsJvwdRCR7LiPT1lOR+Ygp+jQ9GxJQFkBaGxxZgC3bSxXt/9iO4gWQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-cursor-container/-/victory-cursor-container-36.9.2.tgz", + "integrity": "sha512-jidab4j3MaciF3fGX70jTj4H9rrLcY8o2LUrhJ67ZLvEFGGmnPtph+p8Fe97Umrag7E/DszjNxQZolpwlgUh3g==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" @@ -28285,15 +28447,14 @@ } }, "node_modules/victory-group": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-group/-/victory-group-36.7.0.tgz", - "integrity": "sha512-9kb9GTzZ4BBOzWfelBL/iSNu/cIZjJd2TlDW47D0Mtn98TKltQNnywnIUu8+jfOW1ZZUclIQo99Dj74Gnwf9xg==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-group/-/victory-group-36.9.2.tgz", + "integrity": "sha512-wBmpsjBTKva8mxHvHNY3b8RE58KtnpLLItEyyAHaYkmExwt3Uj8Cld3sF3vmeuijn2iR64NPKeMbgMbfZJzycw==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-core": "^36.7.0", - "victory-shared-events": "^36.7.0" + "victory-core": "^36.9.2", + "victory-shared-events": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" @@ -28431,132 +28592,123 @@ } }, "node_modules/victory-legend": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-legend/-/victory-legend-36.7.0.tgz", - "integrity": "sha512-3FHdBCo0Mc6+wWHmYCGunlo9tdCfdlsX0kwYBwi76JVZmo/b9GTKIKP8uluerk/8O2e9uZUrmF/CC1bgOGAklw==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-legend/-/victory-legend-36.9.2.tgz", + "integrity": "sha512-cucFJpv6fty+yXp5pElQFQnHBk1TqA4guGUMI+XF/wLlnuM4bhdAtASobRIIBkz0mHGBaCAAV4PzL9azPU/9dg==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-line": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-line/-/victory-line-36.7.0.tgz", - "integrity": "sha512-kRObLRN5ArfkyVKd8Hi3bidyOg0bjI7nP85akIeKAZSUAxDwZ45ZOJUpcIVQRWHb9/4il50heOc7YKrh0JgAbg==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-line/-/victory-line-36.9.2.tgz", + "integrity": "sha512-kmYFZUo0o2xC8cXRsmt/oUBRQSZJVT2IJnAkboUepypoj09e6CY5tRH4TSdfEDGkBk23xQkn7d4IFgl4kAGnSA==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0", - "victory-vendor": "^36.7.0" + "victory-core": "^36.9.2", + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-pie": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-pie/-/victory-pie-36.7.0.tgz", - "integrity": "sha512-orMVXiceRFd1Y+i4RwSXXETpuMnId2n12l+cuW/fPXWJMRcLuCqHH9PFDB0L3jl8rJCLYwwjisEo6ncwn47q0w==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-pie/-/victory-pie-36.9.2.tgz", + "integrity": "sha512-i3zWezvy5wQEkhXKt4rS9ILGH7Vr9Q5eF9fKO4GMwDPBdYOTE3Dh2tVaSrfDC8g9zFIc0DKzOtVoJRTb+0AkPg==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0", - "victory-vendor": "^36.7.0" + "victory-core": "^36.9.2", + "victory-vendor": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-polar-axis": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-polar-axis/-/victory-polar-axis-36.7.0.tgz", - "integrity": "sha512-DgQn6s42W9ewGqezkYZwoKkM0bMoSVCz9NArcQUSA1R5uIbTXodsOjguP+SwGAZzqhWPP9lc41yQ/WrsXjrTSA==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-polar-axis/-/victory-polar-axis-36.9.2.tgz", + "integrity": "sha512-HBR90FF4M56yf/atXjSmy3DMps1vSAaLXmdVXLM/A5g+0pUS7HO719r5x6dsR3I6Rm+8x6Kk8xJs0qgpnGQIEw==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-scatter": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-scatter/-/victory-scatter-36.7.0.tgz", - "integrity": "sha512-HeEiygvY2g1XG/+Z8FnGiOriYx2jGkE1KW2SyG/qAW93ROou1vdDGLQq7Db3z+I0FA3DBOLqYbPWWvzBQZwxbQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-scatter/-/victory-scatter-36.9.2.tgz", + "integrity": "sha512-hK9AtbJQfaW05i8BH7Lf1HK7vWMAfQofj23039HEQJqTKbCL77YT+Q0LhZw1a1BRCpC/5aSg9EuqblhfIYw2wg==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-selection-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-selection-container/-/victory-selection-container-36.7.0.tgz", - "integrity": "sha512-/9NEULiyLykFl+9+a8Kq2hvwEWgWV1e2aDIPoeEboU6C4B2AC2yU7Z4sw8Ovtaus6IIvzstYFq2nY4fJ4fxOpg==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-selection-container/-/victory-selection-container-36.9.2.tgz", + "integrity": "sha512-chboroEwqqVlMB60kveXM2WznJ33ZM00PWkFVCoJDzHHlYs7TCADxzhqet2S67SbZGSyvSprY2YztSxX8kZ+XQ==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-shared-events": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-shared-events/-/victory-shared-events-36.7.0.tgz", - "integrity": "sha512-q8RwkpNcoQcl6MmufPV+WI/7UbhmYBwl9Be0ne4bM0exU3sEftZERg1ql5iPmt/NRPLURSTY2SFfJVNfRIumnQ==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-shared-events/-/victory-shared-events-36.9.2.tgz", + "integrity": "sha512-W/atiw3Or6MnpBuhluFv6007YrixIRh5NtiRvtFLGxNuQJLYjaSh6koRAih5xJer5Pj7YUx0tL9x67jTRcJ6Dg==", "dependencies": { "json-stringify-safe": "^5.0.1", "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-stack": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-stack/-/victory-stack-36.7.0.tgz", - "integrity": "sha512-+H7yPqDztLlqJmOufKeIhgnPopleCz6IiDPqPExSuMFbgxswua1dS6uFYO9XIlMuodWhwu2TovtL/j1PZoRaxg==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-stack/-/victory-stack-36.9.2.tgz", + "integrity": "sha512-imR6FniVlDFlBa/B3Est8kTryNhWj2ZNpivmVOebVDxkKcVlLaDg3LotCUOI7NzOhBQaro0UzeE9KmZV93JcYA==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-core": "^36.7.0", - "victory-shared-events": "^36.7.0" + "victory-core": "^36.9.2", + "victory-shared-events": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-tooltip": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-tooltip/-/victory-tooltip-36.7.0.tgz", - "integrity": "sha512-l6OlY4qvIWF8IXRsOiPEgvhGMJUOVm+alCBVgUKoR/fTaNSTPJto1Aldaj6hhxUAldA22AftHvSdz0HgQAJmGw==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-tooltip/-/victory-tooltip-36.9.2.tgz", + "integrity": "sha512-76seo4TWD1WfZHJQH87IP3tlawv38DuwrUxpnTn8+uW6/CUex82poQiVevYdmJzhataS9jjyCWv3w7pOmLBCLg==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" } }, "node_modules/victory-vendor": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.7.0.tgz", - "integrity": "sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", @@ -28586,16 +28738,15 @@ } }, "node_modules/victory-voronoi-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-voronoi-container/-/victory-voronoi-container-36.7.0.tgz", - "integrity": "sha512-qRa88Luz08ao/M8J6eVX7PN1JQxVkgjn3fXw+VMpvnUA4Jv51FISBrlSVNi+aP1L4ulsKadj0QO3HChzFIKl4Q==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-voronoi-container/-/victory-voronoi-container-36.9.2.tgz", + "integrity": "sha512-NIVYqck9N4OQnEz9mgQ4wILsci3OBWWK7RLuITGHyoD7Ne/+WH1i0Pv2y9eIx+f55rc928FUTugPPhkHvXyH3A==", "dependencies": { "delaunay-find": "0.0.6", "lodash": "^4.17.19", - "prop-types": "^15.8.1", "react-fast-compare": "^3.2.0", - "victory-core": "^36.7.0", - "victory-tooltip": "^36.7.0" + "victory-core": "^36.9.2", + "victory-tooltip": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" @@ -28695,13 +28846,12 @@ } }, "node_modules/victory-zoom-container": { - "version": "36.7.0", - "resolved": "https://registry.npmjs.org/victory-zoom-container/-/victory-zoom-container-36.7.0.tgz", - "integrity": "sha512-scVeW1BMmdEpzpFT7EiG+qc7JBQ0kPg/Uy97lQc3elyubn8G/nQ+S9o5YlpHyvwCUQKWOn4hgttgE0d//zflDw==", + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-zoom-container/-/victory-zoom-container-36.9.2.tgz", + "integrity": "sha512-pXa2Ji6EX/pIarKT6Hcmmu2n7IG/x8Vs0D2eACQ/nbpvZa+DXWIxCRW4hcg2Va35fmXcDIEpGaX3/soXzZ+pbw==", "dependencies": { "lodash": "^4.17.19", - "prop-types": "^15.8.1", - "victory-core": "^36.7.0" + "victory-core": "^36.9.2" }, "peerDependencies": { "react": ">=16.6.0" @@ -29616,6 +29766,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -29718,6 +29869,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -29734,6 +29886,7 @@ "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" }, @@ -29748,6 +29901,7 @@ "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" }, @@ -29758,7 +29912,8 @@ "node_modules/wrap-ansi/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==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/wrappy": { "version": "1.0.2", @@ -29869,6 +30024,7 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index 7cc23f176..5eb3755bb 100644 --- a/package.json +++ b/package.json @@ -132,12 +132,12 @@ "@data-driven-forms/react-form-renderer": "^3.22.1", "@formatjs/cli": "4.8.4", "@openshift/dynamic-plugin-sdk": "^5.0.1", - "@patternfly/patternfly": "^5.2.1", - "@patternfly/quickstarts": "5.2.0-prerelease.3", - "@patternfly/react-charts": "^7.1.2", - "@patternfly/react-core": "^5.2.1", - "@patternfly/react-icons": "^5.2.1", - "@patternfly/react-tokens": "^5.2.1", + "@patternfly/patternfly": "^5.3.0", + "@patternfly/quickstarts": "^5.3.0", + "@patternfly/react-charts": "^7.3.0", + "@patternfly/react-core": "^5.3.0", + "@patternfly/react-icons": "^5.3.0", + "@patternfly/react-tokens": "^5.3.0", "@redhat-cloud-services/frontend-components": "^4.2.2", "@redhat-cloud-services/chrome": "^1.0.9", "@redhat-cloud-services/entitlements-client": "1.2.0", diff --git a/src/components/GlobalFilter/tagsApi.ts b/src/components/GlobalFilter/tagsApi.ts index ab1cc6ab2..6d9cd6497 100644 --- a/src/components/GlobalFilter/tagsApi.ts +++ b/src/components/GlobalFilter/tagsApi.ts @@ -7,7 +7,7 @@ import { HostsApi, SystemProfileApi, TagsApi } from '@redhat-cloud-services/host import { FlagTagsFilter } from '../../@types/types'; import { TagRegisteredWith } from '../../redux/store'; -export const tags = new TagsApi(undefined, INVENTORY_API_BASE, instance); +export const tags = new TagsApi(undefined, INVENTORY_API_BASE, instance as any); export const sap = new SystemProfileApi(undefined, INVENTORY_API_BASE, instance as any); export const system = new HostsApi(undefined, INVENTORY_API_BASE, instance as any); From 48cefe514ae4a21e3347ad8cf9ffa0fdf02836bc Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Tue, 23 Apr 2024 09:38:46 +0200 Subject: [PATCH 29/46] Ensure Chrome PF ids are unique. --- src/bootstrap.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap.tsx b/src/bootstrap.tsx index fdcfca9f2..85fe5ab00 100644 --- a/src/bootstrap.tsx +++ b/src/bootstrap.tsx @@ -13,11 +13,15 @@ import OIDCProvider from './auth/OIDCConnector/OIDCProvider'; import messages from './locales/data.json'; import ErrorBoundary from './components/ErrorComponents/ErrorBoundary'; import chromeStore from './state/chromeStore'; +import { GenerateId } from '@patternfly/react-core/dist/dynamic/helpers/GenerateId/GenerateId'; const isITLessEnv = ITLess(); const language: keyof typeof messages = 'en'; const AuthProvider = OIDCProvider; +GenerateId.defaultProps.prefix = 'hc-console-'; +GenerateId.defaultProps.isRandom = true; + const useInitializeAnalytics = () => { useEffect(() => { // setup trust arc From 05aacc99c6f0352c5443cfa45d54b1b745d84aae Mon Sep 17 00:00:00 2001 From: Filip Hlavac <50696716+fhlavac@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:19:15 +0200 Subject: [PATCH 30/46] Add OUIA to all services page and dropdown items (#2822) * Add OUIA IDs to all services page items * Add OUIA IDs to all services dropdown items * Add conditional chaining to titleToId helper fn --- .../AllServices/AllServicesGroup.tsx | 10 +- .../AllServices/AllServicesLink.tsx | 13 +- .../AllServices/AllServicesSection.tsx | 8 +- .../AllServicesGallery.tsx | 5 +- .../AllServicesGalleryLink.tsx | 11 +- .../AllServicesGallerySection.tsx | 7 +- src/components/ChromeLink/ChromeLink.tsx | 143 +++++++++--------- .../ChromeNavExpandable.test.js.snap | 2 + .../__snapshots__/ChromeNavGroup.test.js.snap | 1 + .../__snapshots__/ChromeNavItem.test.js.snap | 3 + .../ChromeNavItemFactory.test.js.snap | 2 + src/utils/common.ts | 3 + 12 files changed, 122 insertions(+), 86 deletions(-) diff --git a/src/components/AllServices/AllServicesGroup.tsx b/src/components/AllServices/AllServicesGroup.tsx index e12b28450..8d2e267e3 100644 --- a/src/components/AllServices/AllServicesGroup.tsx +++ b/src/components/AllServices/AllServicesGroup.tsx @@ -1,12 +1,14 @@ import { Text, TextVariants } from '@patternfly/react-core/dist/dynamic/components/Text'; import React, { Fragment } from 'react'; -import { ITLess } from '../../utils/common'; +import { ITLess, titleToId } from '../../utils/common'; import AllServicesLink from './AllServicesLink'; import { AllServicesGroup, isAllServicesLink } from './allServicesLinks'; -export type AllServicesGroupProps = AllServicesGroup; -const AllServicesGroup = ({ title, links }: AllServicesGroupProps) => { +export type AllServicesGroupProps = AllServicesGroup & { + category: string; +}; +const AllServicesGroup = ({ title, links, category }: AllServicesGroupProps) => { const filteredLinks = ITLess() ? links.filter((link) => isAllServicesLink(link) && link.ITLess) : links; if (filteredLinks.length === 0) { return null; @@ -17,7 +19,7 @@ const AllServicesGroup = ({ title, links }: AllServicesGroupProps) => { {title} {filteredLinks.map((link, index) => ( - + ))} ); diff --git a/src/components/AllServices/AllServicesLink.tsx b/src/components/AllServices/AllServicesLink.tsx index 7e01f6d45..2a89b2d15 100644 --- a/src/components/AllServices/AllServicesLink.tsx +++ b/src/components/AllServices/AllServicesLink.tsx @@ -13,10 +13,11 @@ import type { AllServicesLink as AllServicesLinkType } from './allServicesLinks' import useFavoritePagesWrapper from '../../hooks/useFavoritePagesWrapper'; import { useAtomValue } from 'jotai'; import { moduleRoutesAtom } from '../../state/atoms/chromeModuleAtom'; +import { titleToId } from '../../utils/common'; -export type AllServicesLinkProps = AllServicesLinkType; +export type AllServicesLinkProps = AllServicesLinkType & { category: string; group?: string }; -const AllServicesLink = ({ href, title, isExternal }: AllServicesLinkProps) => { +const AllServicesLink = ({ href, title, isExternal, category, group }: AllServicesLinkProps) => { const moduleRoutes = useAtomValue(moduleRoutesAtom); // Find service appId const appId = useMemo(() => { @@ -40,7 +41,12 @@ const AllServicesLink = ({ href, title, isExternal }: AllServicesLinkProps) => { 'chr-c-icon-favorited': isFavorite, })} > - + {title} {isExternal && ( @@ -50,6 +56,7 @@ const AllServicesLink = ({ href, title, isExternal }: AllServicesLinkProps) => { {!isExternal && ( handleFavouriteToggle(href, isFavorite)} aria-label={`${isFavorite ? 'Unfavorite' : 'Favorite'} ${title}`} className="pf-v5-u-ml-sm chr-c-icon-star" diff --git a/src/components/AllServices/AllServicesSection.tsx b/src/components/AllServices/AllServicesSection.tsx index e667bd067..57388c59e 100644 --- a/src/components/AllServices/AllServicesSection.tsx +++ b/src/components/AllServices/AllServicesSection.tsx @@ -2,7 +2,7 @@ import { Card, CardBody, CardTitle } from '@patternfly/react-core/dist/dynamic/c import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon'; import { Text, TextContent, TextVariants } from '@patternfly/react-core/dist/dynamic/components/Text'; import React from 'react'; -import { ITLess } from '../../utils/common'; +import { ITLess, titleToId } from '../../utils/common'; import AllServicesGroup from './AllServicesGroup'; import AllServicesLink from './AllServicesLink'; import { AllServicesSection, isAllServicesGroup } from './allServicesLinks'; @@ -27,7 +27,11 @@ const AllServicesSection = ({ icon, title, description, links }: AllServicesSect {description || null} {filteredLinks.map((link, index) => - isAllServicesGroup(link) ? : + isAllServicesGroup(link) ? ( + + ) : ( + + ) )} diff --git a/src/components/AllServicesDropdown/AllServicesGallery.tsx b/src/components/AllServicesDropdown/AllServicesGallery.tsx index 89be2ff8a..293a6ca2e 100644 --- a/src/components/AllServicesDropdown/AllServicesGallery.tsx +++ b/src/components/AllServicesDropdown/AllServicesGallery.tsx @@ -3,6 +3,7 @@ import { Gallery } from '@patternfly/react-core/dist/dynamic/layouts/Gallery'; import { AllServicesGroup, AllServicesLink, AllServicesSection, isAllServicesGroup } from '../AllServices/allServicesLinks'; import AllServicesGalleryLink from './AllServicesGalleryLink'; import AllServicesGallerySection from './AllServicesGallerySection'; +import { titleToId } from '../../utils/common'; export type AllServicesGalleryProps = { selectedService: AllServicesSection; @@ -22,11 +23,11 @@ const AllServicesGallery = ({ selectedService }: AllServicesGalleryProps) => { {links.map((link, index) => ( - + ))} {sections.map((section, index) => ( - + ))} ); diff --git a/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx b/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx index b9c44089c..b32f99364 100644 --- a/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx +++ b/src/components/AllServicesDropdown/AllServicesGalleryLink.tsx @@ -14,10 +14,11 @@ import classNames from 'classnames'; import useFavoritePagesWrapper from '../../hooks/useFavoritePagesWrapper'; import { AllServicesDropdownContext } from './common'; import ServiceIcon from '../FavoriteServices/ServiceIcon'; +import { titleToId } from '../../utils/common'; export type AllServicesGalleryLinkProps = AllServicesLinkProps; -const AllServicesGalleryLink = ({ href, title, icon, description, isExternal }: AllServicesGalleryLinkProps) => { +const AllServicesGalleryLink = ({ href, title, icon, description, isExternal, category, group }: AllServicesGalleryLinkProps) => { const { favoritePage, unfavoritePage, favoritePages } = useFavoritePagesWrapper(); const { onLinkClick } = useContext(AllServicesDropdownContext); const TitleIcon = icon ? : null; @@ -32,7 +33,12 @@ const AllServicesGalleryLink = ({ href, title, icon, description, isExternal }: const isFavorite = !!favoritePages.find(({ pathname, favorite }) => pathname === href && favorite); return ( - + { e.stopPropagation(); e.preventDefault(); diff --git a/src/components/AllServicesDropdown/AllServicesGallerySection.tsx b/src/components/AllServicesDropdown/AllServicesGallerySection.tsx index 6656114b1..af644d2f6 100644 --- a/src/components/AllServicesDropdown/AllServicesGallerySection.tsx +++ b/src/components/AllServicesDropdown/AllServicesGallerySection.tsx @@ -4,10 +4,11 @@ import { Label } from '@patternfly/react-core/dist/dynamic/components/Label'; import React from 'react'; import { AllServicesGroup } from '../AllServices/allServicesLinks'; import AllServicesGalleryLink from './AllServicesGalleryLink'; +import { titleToId } from '../../utils/common'; -export type AllServicesGallerySectionProps = AllServicesGroup; +export type AllServicesGallerySectionProps = AllServicesGroup & { category: string }; -const AllServicesGallerySection = ({ title, links }: AllServicesGallerySectionProps) => { +const AllServicesGallerySection = ({ title, links, category }: AllServicesGallerySectionProps) => { if (links.length === 0) { return null; } @@ -17,7 +18,7 @@ const AllServicesGallerySection = ({ title, links }: AllServicesGallerySectionPr
{links.map((link, index) => ( - + ))}
diff --git a/src/components/ChromeLink/ChromeLink.tsx b/src/components/ChromeLink/ChromeLink.tsx index 2aeb0cc70..1ef4845b5 100644 --- a/src/components/ChromeLink/ChromeLink.tsx +++ b/src/components/ChromeLink/ChromeLink.tsx @@ -28,83 +28,86 @@ export interface LinkWrapperProps extends RefreshLinkProps { tabIndex?: number; } -const LinkWrapper: React.FC = memo(({ href = '', isBeta, onLinkClick, className, currAppId, appId, children, tabIndex }) => { - const linkRef = useRef(null); - const moduleRoutes = useAtomValue(moduleRoutesAtom); - const moduleEntry = useMemo(() => moduleRoutes?.find((route) => href?.includes(route.path)), [href, appId]); - const preloadTimeout = useRef(); - let actionId = href.split('/').slice(2).join('/'); - if (actionId.includes('/')) { - actionId = actionId.split('/').pop() as string; - } - if (currAppId !== appId && href.split('/').length === 3) { - actionId = '/'; - } +const LinkWrapper: React.FC = memo( + ({ href = '', isBeta, onLinkClick, className, currAppId, appId, children, tabIndex, ...props }) => { + const linkRef = useRef(null); + const moduleRoutes = useAtomValue(moduleRoutesAtom); + const moduleEntry = useMemo(() => moduleRoutes?.find((route) => href?.includes(route.path)), [href, appId]); + const preloadTimeout = useRef(); + let actionId = href.split('/').slice(2).join('/'); + if (actionId.includes('/')) { + actionId = actionId.split('/').pop() as string; + } + if (currAppId !== appId && href.split('/').length === 3) { + actionId = '/'; + } - /** - * If the sub nav item points to application root - * eg. /openshift/cost-management we don't want to send "/cost-management" but "/" - * We are not in app sub route but in app root - */ - const domEvent: NavDOMEvent = { - href, - id: actionId, - navId: actionId, /** - * @deprecated - * Remove once nav overhaul is in all environments + * If the sub nav item points to application root + * eg. /openshift/cost-management we don't want to send "/cost-management" but "/" + * We are not in app sub route but in app root */ - type: 'click', - }; - const dispatch = useDispatch(); - const onClick = (event: React.MouseEvent) => { - if (event.ctrlKey || event.shiftKey) { - return false; - } - if (onLinkClick && isBeta) { - if (!onLinkClick(event, href)) { + const domEvent: NavDOMEvent = { + href, + id: actionId, + navId: actionId, + /** + * @deprecated + * Remove once nav overhaul is in all environments + */ + type: 'click', + }; + const dispatch = useDispatch(); + const onClick = (event: React.MouseEvent) => { + if (event.ctrlKey || event.shiftKey) { return false; } - } + if (onLinkClick && isBeta) { + if (!onLinkClick(event, href)) { + return false; + } + } - /** - * Add reference to the DOM link element - */ - domEvent.target = linkRef.current; - dispatch(appNavClick({ id: actionId }, domEvent)); - }; + /** + * Add reference to the DOM link element + */ + domEvent.target = linkRef.current; + dispatch(appNavClick({ id: actionId }, domEvent)); + }; - // turns /settings/rbac/roles -> settings_rbac_roles - const quickStartHighlightId = href - .split('/') - .slice(href.startsWith('/') ? 1 : 0) - .join('_'); - return ( - { - if (moduleEntry) { - preloadTimeout.current = setTimeout(() => { - preloadModule(moduleEntry?.scope, moduleEntry?.module); - }, 250); - } - }} - onMouseLeave={() => { - if (preloadTimeout.current) { - clearTimeout(preloadTimeout.current); - } - }} - tabIndex={tabIndex} - ref={linkRef} - data-testid="router-link" - onClick={onClick} - to={href} - className={className} - data-quickstart-id={quickStartHighlightId} - > - {children} - - ); -}); + // turns /settings/rbac/roles -> settings_rbac_roles + const quickStartHighlightId = href + .split('/') + .slice(href.startsWith('/') ? 1 : 0) + .join('_'); + return ( + { + if (moduleEntry) { + preloadTimeout.current = setTimeout(() => { + preloadModule(moduleEntry?.scope, moduleEntry?.module); + }, 250); + } + }} + onMouseLeave={() => { + if (preloadTimeout.current) { + clearTimeout(preloadTimeout.current); + } + }} + tabIndex={tabIndex} + ref={linkRef} + data-testid="router-link" + onClick={onClick} + to={href} + className={className} + data-quickstart-id={quickStartHighlightId} + > + {children} + + ); + } +); LinkWrapper.displayName = 'MemoizedLinkWrapper'; diff --git a/src/components/Navigation/__snapshots__/ChromeNavExpandable.test.js.snap b/src/components/Navigation/__snapshots__/ChromeNavExpandable.test.js.snap index 265ecdaa8..7e58ab302 100644 --- a/src/components/Navigation/__snapshots__/ChromeNavExpandable.test.js.snap +++ b/src/components/Navigation/__snapshots__/ChromeNavExpandable.test.js.snap @@ -59,6 +59,7 @@ exports[`ChromeNavExpandable should render nav item expandable 1`] = ` data-quickstart-id="foo_bar" data-testid="router-link" href="/foo/bar" + itemid="/foo/bar" > Title @@ -127,6 +128,7 @@ exports[`ChromeNavExpandable should render nav item expandable with items 1`] = data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Sub Item diff --git a/src/components/Navigation/__snapshots__/ChromeNavGroup.test.js.snap b/src/components/Navigation/__snapshots__/ChromeNavGroup.test.js.snap index cf59b6ede..ba853eafd 100644 --- a/src/components/Navigation/__snapshots__/ChromeNavGroup.test.js.snap +++ b/src/components/Navigation/__snapshots__/ChromeNavGroup.test.js.snap @@ -110,6 +110,7 @@ exports[`ChromeNavGroup should render nav item group with items 1`] = ` data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Sub Item diff --git a/src/components/Navigation/__snapshots__/ChromeNavItem.test.js.snap b/src/components/Navigation/__snapshots__/ChromeNavItem.test.js.snap index 66ef01f91..8b38c5df9 100644 --- a/src/components/Navigation/__snapshots__/ChromeNavItem.test.js.snap +++ b/src/components/Navigation/__snapshots__/ChromeNavItem.test.js.snap @@ -15,6 +15,7 @@ exports[`ChromeNavItem should render nav item 1`] = ` data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Foo @@ -36,6 +37,7 @@ exports[`ChromeNavItem should render nav item with a node title 1`] = ` data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Foo diff --git a/src/components/Navigation/__snapshots__/ChromeNavItemFactory.test.js.snap b/src/components/Navigation/__snapshots__/ChromeNavItemFactory.test.js.snap index 47839b491..18a3403a9 100644 --- a/src/components/Navigation/__snapshots__/ChromeNavItemFactory.test.js.snap +++ b/src/components/Navigation/__snapshots__/ChromeNavItemFactory.test.js.snap @@ -57,6 +57,7 @@ exports[`ChromeNavItemFactory should render chrome expandable nav item 1`] = ` data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Foo @@ -110,6 +111,7 @@ exports[`ChromeNavItemFactory should render chrome nav item 1`] = ` data-quickstart-id="foo" data-testid="router-link" href="/foo" + itemid="/foo" > Foo diff --git a/src/utils/common.ts b/src/utils/common.ts index 9a8bfdb9c..b75195c24 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -458,3 +458,6 @@ export function findNavLeafPath( return { activeItem: leaf, navItems: leafPath }; } + +// converts text to an identifier in title case +export const titleToId = (title: string) => title?.replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase()).replace(/\s+/g, ''); From 38bb1f8c092e071708b1b7f54bdc725e232e4d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Maro=C5=A1i?= Date: Wed, 24 Apr 2024 12:33:40 +0200 Subject: [PATCH 31/46] Enable VA in insights bundle. (#2823) --- src/components/Routes/VirtualAssistant.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Routes/VirtualAssistant.tsx b/src/components/Routes/VirtualAssistant.tsx index 285b9eaa5..ca2d14d70 100644 --- a/src/components/Routes/VirtualAssistant.tsx +++ b/src/components/Routes/VirtualAssistant.tsx @@ -4,7 +4,7 @@ import { ScalprumComponent } from '@scalprum/react-core'; import './virtual-assistant.scss'; -const viableRoutes = ['/', '/settings/*', '/subscriptions/overview/*', '/subscriptions/inventory/*', '/subscriptions/usage/*']; +const viableRoutes = ['/', '/insights/*', '/settings/*', '/subscriptions/overview/*', '/subscriptions/inventory/*', '/subscriptions/usage/*']; const VirtualAssistant = () => { return ( From 7a69b4997ffcc4db94b9689c426ffa2e135e9375 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 25 Apr 2024 09:37:21 +0200 Subject: [PATCH 32/46] Hide global filter when disabled. --- src/components/GlobalFilter/GlobalFilter.tsx | 16 ++-- .../GlobalFilter/GlobalFilterMenu.tsx | 4 +- src/components/RootApp/ScalprumRoot.test.js | 73 +++++++++++++++++-- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/components/GlobalFilter/GlobalFilter.tsx b/src/components/GlobalFilter/GlobalFilter.tsx index 41e92154d..7e26ffcd4 100644 --- a/src/components/GlobalFilter/GlobalFilter.tsx +++ b/src/components/GlobalFilter/GlobalFilter.tsx @@ -66,9 +66,6 @@ const GlobalFilter = ({ hasAccess }: { hasAccess: boolean }) => { }), shallowEqual ); - const globalFilterHidden = useSelector(({ globalFilter: { globalFilterHidden } }: ReduxState) => globalFilterHidden); - const activeModule = useAtomValue(activeModuleAtom); - const isDisabled = globalFilterHidden || !activeModule; const { filter, chips, selectedTags, setValue, filterTagsBy } = ( useTagsFilter as unknown as ( @@ -110,16 +107,15 @@ const GlobalFilter = ({ hasAccess }: { hasAccess: boolean }) => { }, []); useEffect(() => { - if (hasAccess && !isDisabled) { + if (hasAccess) { loadTags(selectedTags, filterTagsBy); selectTags(selectedTags); } - }, [selectedTags, filterTagsBy, hasAccess, isDisabled]); + }, [selectedTags, filterTagsBy, hasAccess]); return ( key === 'Workloads'), ...chips.filter(({ key }) => key !== 'Workloads')]} setValue={setValue} @@ -141,10 +137,16 @@ const GlobalFilterWrapper = () => { // FIXME: Clean up the global filter display flag const isLanding = pathname === '/'; const isAllowed = isGlobalFilterAllowed(); + const globalFilterHidden = useSelector(({ globalFilter: { globalFilterHidden } }: ReduxState) => globalFilterHidden); + const activeModule = useAtomValue(activeModuleAtom); + const isDisabled = globalFilterHidden || !activeModule; const isGlobalFilterEnabled = useMemo(() => { + if (isDisabled) { + return false; + } const globalFilterAllowed = isAllowed || globalFilterRemoved; return !isLanding && (globalFilterAllowed || Boolean(localStorage.getItem('chrome:experimental:global-filter'))); - }, [isLanding, isAllowed]); + }, [isLanding, isAllowed, isDisabled]); useEffect(() => { let mounted = true; diff --git a/src/components/GlobalFilter/GlobalFilterMenu.tsx b/src/components/GlobalFilter/GlobalFilterMenu.tsx index d43132f14..60e3bae7e 100644 --- a/src/components/GlobalFilter/GlobalFilterMenu.tsx +++ b/src/components/GlobalFilter/GlobalFilterMenu.tsx @@ -56,7 +56,7 @@ export type SelectedTags = { export type GlobalFilterDropdownProps = { allowed: boolean; - isDisabled: boolean; + isDisabled?: boolean; filter: { filterBy?: string | number; onFilter?: (value: string) => void; @@ -74,7 +74,7 @@ export type GlobalFilterDropdownProps = { export const GlobalFilterDropdown: React.FunctionComponent = ({ allowed, - isDisabled, + isDisabled = false, filter, chips, setValue, diff --git a/src/components/RootApp/ScalprumRoot.test.js b/src/components/RootApp/ScalprumRoot.test.js index 8f65705f0..19f68e48f 100644 --- a/src/components/RootApp/ScalprumRoot.test.js +++ b/src/components/RootApp/ScalprumRoot.test.js @@ -4,6 +4,7 @@ import ScalprumRoot from './ScalprumRoot'; import { act, render, waitFor } from '@testing-library/react'; import configureStore from 'redux-mock-store'; import { Provider } from 'react-redux'; +import { Provider as JotaiProvider } from 'jotai'; jest.mock('../../utils/common', () => { const utils = jest.requireActual('../../utils/common'); @@ -47,6 +48,19 @@ window.ResizeObserver = import * as routerDom from 'react-router-dom'; import { initializeVisibilityFunctions } from '../../utils/VisibilitySingleton'; import ChromeAuthContext from '../../auth/ChromeAuthContext'; +import { useHydrateAtoms } from 'jotai/utils'; +import { activeModuleAtom } from '../../state/atoms/activeModuleAtom'; + +const HydrateAtoms = ({ initialValues, children }) => { + useHydrateAtoms(initialValues); + return children; +}; + +const JotaiTestProvider = ({ initialValues, children }) => ( + + {children} + +); describe('ScalprumRoot', () => { let initialState; @@ -220,17 +234,62 @@ describe('ScalprumRoot', () => { }); const { container } = render( - - - - - - - + + + + + + + + + ); await waitFor(() => expect(container.querySelector('#global-filter')).toBeTruthy()); useLocationSpy.mockRestore(); fetchSpy.mockRestore(); }); + + it('should not render GlobalFilter', async () => { + const fetchSpy = jest.spyOn(window, 'fetch').mockImplementationOnce(() => Promise.resolve({ ok: true, json: () => ({}) })); + const useLocationSpy = jest.spyOn(routerDom, 'useLocation'); + useLocationSpy.mockReturnValue({ pathname: '/insights', search: undefined, hash: undefined }); + Object.defineProperty(window, 'location', { + value: { + pathname: '/insights', + href: '/insights', + host: 'foo.bar.baz', + }, + }); + Object.defineProperty(window, 'insights', { + value: { + chrome: { + getEnvironment: () => '', + }, + }, + }); + const store = mockStore({ + ...initialState, + chrome: { + ...initialState.chrome, + activeLocation: 'insights', + }, + }); + + const { container } = render( + + + + + + + + + + ); + await waitFor(() => expect(container.querySelector('#global-filter')).toBeFalsy()); + + useLocationSpy.mockRestore(); + fetchSpy.mockRestore(); + }); }); From 64ccf6a190136949911757171d4f2062d02c5235 Mon Sep 17 00:00:00 2001 From: Muslimjon Date: Mon, 29 Apr 2024 19:59:14 +0200 Subject: [PATCH 33/46] update insights bundle title suffix to RHEL --- src/hooks/useBundle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useBundle.ts b/src/hooks/useBundle.ts index 26110c3a7..8005aff5a 100644 --- a/src/hooks/useBundle.ts +++ b/src/hooks/useBundle.ts @@ -19,7 +19,7 @@ export const bundleMapping: { 'application-services': 'Application and Data Services', openshift: 'OpenShift', ansible: 'Ansible Automation Platform', - insights: 'Red Hat Insights', + insights: 'RHEL', edge: 'Edge management', settings: 'Settings', landing: 'Home', From abcd25e5c3d6f363859e3e19424cf13935c458a8 Mon Sep 17 00:00:00 2001 From: alex <86322239+aferd@users.noreply.github.com> Date: Mon, 6 May 2024 02:43:49 -0400 Subject: [PATCH 34/46] RHCLOUD-32399 update link (#2829) * update link * remove console log * remove a tag --- .../FavoriteServices/DashboardFavorites.tsx | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/components/FavoriteServices/DashboardFavorites.tsx b/src/components/FavoriteServices/DashboardFavorites.tsx index 68f2534ac..3321a9117 100644 --- a/src/components/FavoriteServices/DashboardFavorites.tsx +++ b/src/components/FavoriteServices/DashboardFavorites.tsx @@ -14,7 +14,6 @@ import './DashboardFavorites.scss'; const DashboardFavorites = () => { const favoritedServices = useFavoritedServices(); - const getBundle = (href: string) => bundleMapping[href.split('/')[1]]; return ( @@ -26,21 +25,19 @@ const DashboardFavorites = () => { {favoritedServices.map((favorite, index) => ( - - - - - - - - - {favorite.name} - - {getBundle(favorite.pathname)} - - - - + + + + + + + + {favorite.name} + + {getBundle(favorite.pathname)} + + + ))} From 2ac36c14e11b711a78c004ee285673a9b3a68a9a Mon Sep 17 00:00:00 2001 From: ewinchel Date: Wed, 8 May 2024 10:48:47 -0400 Subject: [PATCH 35/46] Move 'favorite services' widget styling back to chrome --- src/components/FavoriteServices/DashboardFavorites.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/FavoriteServices/DashboardFavorites.scss b/src/components/FavoriteServices/DashboardFavorites.scss index f9a2f6866..43f1b9de8 100644 --- a/src/components/FavoriteServices/DashboardFavorites.scss +++ b/src/components/FavoriteServices/DashboardFavorites.scss @@ -1,3 +1,7 @@ +.chrome-favoriteServices { + overflow-y: auto; +} + .widget-favorites { column-width: 300px; } From e9d7f81d80fdca8021b0f36e79a02494c2a83bff Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 9 May 2024 09:36:38 +0200 Subject: [PATCH 36/46] Add LocalStorage flag to force new preview feaures. --- src/utils/debugFunctions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/debugFunctions.ts b/src/utils/debugFunctions.ts index cd9b8c890..f09a451bb 100644 --- a/src/utils/debugFunctions.ts +++ b/src/utils/debugFunctions.ts @@ -23,6 +23,7 @@ const debugFunctions = { segmentDev: () => functionBuilder('chrome:analytics:dev', true), intlDebug: () => functionBuilder('chrome:intl:debug', true), sentryDebug: () => functionBuilder('chrome:sentry:debug', true), + forceLocalPreview: () => functionBuilder('chrome:local-preview', true), }; export default debugFunctions; From 8e25d2eacd429be3089fa26448c680d5e94cd8df Mon Sep 17 00:00:00 2001 From: Bryan Florkiewicz Date: Fri, 10 May 2024 00:52:18 -0400 Subject: [PATCH 37/46] RHCLOUD-32008: create internal jotai state for preview Adds an internal state variable via jotai to track if preview is enabled or disabled. Tested locally by adding a sub in the store with a console log (see screenshots). The state is correctly toggled with the preview toggle and initialized when chrome loads. --- src/components/Header/Tools.tsx | 3 +++ src/state/atoms/releaseAtom.ts | 5 +++++ src/state/atoms/utils.ts | 11 +++++++++++ src/state/chromeStore.ts | 3 +++ 4 files changed, 22 insertions(+) create mode 100644 src/state/atoms/releaseAtom.ts create mode 100644 src/state/atoms/utils.ts diff --git a/src/components/Header/Tools.tsx b/src/components/Header/Tools.tsx index 8f391cb4b..fd0e52ff1 100644 --- a/src/components/Header/Tools.tsx +++ b/src/components/Header/Tools.tsx @@ -28,12 +28,15 @@ import BellIcon from '@patternfly/react-icons/dist/dynamic/icons/bell-icon'; import { toggleNotificationsDrawer } from '../../redux/actions'; import useWindowWidth from '../../hooks/useWindowWidth'; import ChromeAuthContext from '../../auth/ChromeAuthContext'; +import { isPreviewAtom } from '../../state/atoms/releaseAtom'; +import chromeStore from '../../state/chromeStore'; const isITLessEnv = ITLess(); export const switchRelease = (isBeta: boolean, pathname: string, previewEnabled: boolean) => { cookie.set('cs_toggledRelease', 'true'); const previewFragment = getRouterBasename(pathname); + chromeStore.set(isPreviewAtom, !isBeta); if (isBeta) { return pathname.replace(previewFragment.includes('beta') ? /\/beta/ : /\/preview/, ''); diff --git a/src/state/atoms/releaseAtom.ts b/src/state/atoms/releaseAtom.ts new file mode 100644 index 000000000..f54332027 --- /dev/null +++ b/src/state/atoms/releaseAtom.ts @@ -0,0 +1,5 @@ +import { atomWithToggle } from './utils'; + +import { isBeta } from '../../utils/common'; + +export const isPreviewAtom = atomWithToggle(isBeta()); diff --git a/src/state/atoms/utils.ts b/src/state/atoms/utils.ts new file mode 100644 index 000000000..0bbb74aba --- /dev/null +++ b/src/state/atoms/utils.ts @@ -0,0 +1,11 @@ +import { WritableAtom, atom } from 'jotai'; + +// recipe from https://jotai.org/docs/recipes/atom-with-toggle +export function atomWithToggle(initialValue?: boolean): WritableAtom { + const anAtom = atom(initialValue, (get, set, nextValue?: boolean) => { + const update = nextValue ?? !get(anAtom); + set(anAtom, update); + }); + + return anAtom as WritableAtom; +} diff --git a/src/state/chromeStore.ts b/src/state/chromeStore.ts index 73453161b..ddce3b852 100644 --- a/src/state/chromeStore.ts +++ b/src/state/chromeStore.ts @@ -1,12 +1,15 @@ import { createStore } from 'jotai'; import { activeModuleAtom } from './atoms/activeModuleAtom'; import { contextSwitcherOpenAtom } from './atoms/contextSwitcher'; +import { isPreviewAtom } from './atoms/releaseAtom'; +import { isBeta } from '../utils/common'; const chromeStore = createStore(); // setup initial chrome store state chromeStore.set(contextSwitcherOpenAtom, false); chromeStore.set(activeModuleAtom, undefined); +chromeStore.set(isPreviewAtom, isBeta()); // globally handle subscription to activeModuleAtom chromeStore.sub(activeModuleAtom, () => { From b829a38a2e667f4aafca4818c5980b59638ad605 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Mon, 13 May 2024 12:30:47 +0200 Subject: [PATCH 38/46] Send cookie to PDF generator. --- src/auth/setCookie.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/auth/setCookie.ts b/src/auth/setCookie.ts index 739fd269a..886b803f1 100644 --- a/src/auth/setCookie.ts +++ b/src/auth/setCookie.ts @@ -27,6 +27,9 @@ export async function setCookie(token: string, expiresAt: number) { setCookieWrapper(`${cookieName}=${token};` + `path=/api/automation-hub;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}`); setCookieWrapper(`${cookieName}=${token};` + `path=/api/remediations/v1;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}`); setCookieWrapper(`${cookieName}=${token};` + `path=/api/edge/v1;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}`); + setCookieWrapper( + `${cookieName}=${token};` + `path=/api/crc-pdf-generator/v2/download;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}` + ); } } } From d915320c9bdc9f5114de6f75129281359961de02 Mon Sep 17 00:00:00 2001 From: Radek Kaluzik Date: Tue, 14 May 2024 13:58:28 +0200 Subject: [PATCH 39/46] Changed URL for User Preferences in UserToggle --- .../Header/HeaderTests/__snapshots__/UserToggle.test.js.snap | 4 ++-- src/components/Header/UserToggle.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Header/HeaderTests/__snapshots__/UserToggle.test.js.snap b/src/components/Header/HeaderTests/__snapshots__/UserToggle.test.js.snap index e8bf2380a..bc676af67 100644 --- a/src/components/Header/HeaderTests/__snapshots__/UserToggle.test.js.snap +++ b/src/components/Header/HeaderTests/__snapshots__/UserToggle.test.js.snap @@ -245,9 +245,9 @@ exports[`UserToggle should render correctly with isSmall false 1`] = ` > User Preferences diff --git a/src/components/Header/UserToggle.tsx b/src/components/Header/UserToggle.tsx index cfd5c2e84..0ad7dc1e8 100644 --- a/src/components/Header/UserToggle.tsx +++ b/src/components/Header/UserToggle.tsx @@ -108,7 +108,7 @@ const DropdownItems = ({ ( - + {intl.formatMessage(messages.userPreferences)} )} From 499d521bc3ccae93791846f9c006b5f47ed52a83 Mon Sep 17 00:00:00 2001 From: Adonis Puente Date: Wed, 15 May 2024 11:20:06 -0400 Subject: [PATCH 40/46] Replace sentry var to check for app names --- src/utils/sentry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/sentry.ts b/src/utils/sentry.ts index d4d00b56d..c12b8fb36 100644 --- a/src/utils/sentry.ts +++ b/src/utils/sentry.ts @@ -42,7 +42,7 @@ function initSentry() { const appDetails = getAppDetails(); let API_KEY; - switch (appDetails.app.group) { + switch (appDetails.app.name) { case 'advisor': API_KEY = 'https://f8eb44de949e487e853185c09340f3cf@o490301.ingest.us.sentry.io/4505397435367424'; break; From 0ce19ead767de24ada733ff7be9362cf54c6e252 Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Fri, 17 May 2024 10:54:39 +0200 Subject: [PATCH 41/46] Update PDF generator cookie path. --- src/auth/setCookie.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/setCookie.ts b/src/auth/setCookie.ts index 886b803f1..e08c6ffc7 100644 --- a/src/auth/setCookie.ts +++ b/src/auth/setCookie.ts @@ -28,7 +28,7 @@ export async function setCookie(token: string, expiresAt: number) { setCookieWrapper(`${cookieName}=${token};` + `path=/api/remediations/v1;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}`); setCookieWrapper(`${cookieName}=${token};` + `path=/api/edge/v1;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}`); setCookieWrapper( - `${cookieName}=${token};` + `path=/api/crc-pdf-generator/v2/download;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}` + `${cookieName}=${token};` + `path=/api/crc-pdf-generator/v2/create;` + `secure=true;` + `expires=${getCookieExpires(expiresAt)}` ); } } From ffee5336dc22ead55b318b5025d8ee662babdde5 Mon Sep 17 00:00:00 2001 From: Karel Hala Date: Fri, 17 May 2024 11:39:31 +0200 Subject: [PATCH 42/46] PAss available bundles via chrome API --- package-lock.json | 8 ++++---- package.json | 2 +- src/chrome/create-chrome.ts | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0811f16eb..650dff169 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.3.0", "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4", - "@redhat-cloud-services/types": "^1.0.7", + "@redhat-cloud-services/types": "^1.0.9", "@simonsmith/cypress-image-snapshot": "^8.1.2", "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29", @@ -5220,9 +5220,9 @@ } }, "node_modules/@redhat-cloud-services/types": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.7.tgz", - "integrity": "sha512-+10LrAlXuzn8VaS+CuzLjU04Pd0GrrqrOxEWzjapdXKLbjBKBorzIEX8CJmuDXPkHJd9zyJ92+1/4dX8lswuZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/types/-/types-1.0.9.tgz", + "integrity": "sha512-dKYYSLU0cwNkOSq5kSvdKWzgwFGBk45uwAwoHGi44PMQdWkuz+tXhYLrKKAXoSXVahR6VFjBDONlaxok8Lzkcw==", "dev": true }, "node_modules/@remix-run/router": { diff --git a/package.json b/package.json index 7cc23f176..1359af920 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@redhat-cloud-services/eslint-config-redhat-cloud-services": "^1.3.0", "@redhat-cloud-services/frontend-components-config-utilities": "^3.0.4", - "@redhat-cloud-services/types": "^1.0.7", + "@redhat-cloud-services/types": "^1.0.9", "@simonsmith/cypress-image-snapshot": "^8.1.2", "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29", diff --git a/src/chrome/create-chrome.ts b/src/chrome/create-chrome.ts index a81bf7d28..48c7f1a16 100644 --- a/src/chrome/create-chrome.ts +++ b/src/chrome/create-chrome.ts @@ -29,7 +29,7 @@ import chromeHistory from '../utils/chromeHistory'; import { ReduxState } from '../redux/store'; import { STORE_INITIAL_HASH } from '../redux/action-types'; import { FlagTagsFilter } from '../@types/types'; -import useBundle, { getUrl } from '../hooks/useBundle'; +import useBundle, { bundleMapping, getUrl } from '../hooks/useBundle'; import { warnDuplicatePkg } from './warnDuplicatePackages'; import { getVisibilityFunctions } from '../utils/VisibilitySingleton'; import { ChromeAuthContextValue } from '../auth/ChromeAuthContext'; @@ -132,6 +132,7 @@ export const createChromeContext = ({ } return environment; }, + getAvailableBundles: () => Object.entries(bundleMapping).map(([key, value]) => ({ id: key, title: value })), createCase: (fields?: any) => chromeAuth.getUser().then((user) => createSupportCase(user!.identity, chromeAuth.token, fields)), getUserPermissions: async (app = '', bypassCache?: boolean) => { const token = await chromeAuth.getToken(); @@ -168,9 +169,9 @@ export const createChromeContext = ({ segment: { setPageMetadata, }, - toggleFeedbackModal: (...args) => dispatch(toggleFeedbackModal(...args)), + toggleFeedbackModal: (isOpen: boolean) => dispatch(toggleFeedbackModal(isOpen)), enableDebugging: () => dispatch(toggleDebuggerButton(true)), - toggleDebuggerModal: (...args) => dispatch(toggleDebuggerModal(...args)), + toggleDebuggerModal: (isOpen: boolean) => dispatch(toggleDebuggerModal(isOpen)), // FIXME: Update types once merged quickStarts: quickstartsAPI as unknown as ChromeAPI['quickStarts'], helpTopics, From fa4e37e790bb5ff2894ed03a2faf3e2d0b6c5335 Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Mon, 20 May 2024 14:57:14 -0500 Subject: [PATCH 43/46] add brain icon for AI/ML allservices section --- src/components/AllServicesDropdown/icon-brain.tsx | 10 ++++++++++ src/components/FavoriteServices/ServiceIcon.tsx | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 src/components/AllServicesDropdown/icon-brain.tsx diff --git a/src/components/AllServicesDropdown/icon-brain.tsx b/src/components/AllServicesDropdown/icon-brain.tsx new file mode 100644 index 000000000..452bc6a4b --- /dev/null +++ b/src/components/AllServicesDropdown/icon-brain.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +const BrainIcon = () => { + return ( + + + + ); +}; +export default BrainIcon; diff --git a/src/components/FavoriteServices/ServiceIcon.tsx b/src/components/FavoriteServices/ServiceIcon.tsx index 536c2fc1c..1708114de 100644 --- a/src/components/FavoriteServices/ServiceIcon.tsx +++ b/src/components/FavoriteServices/ServiceIcon.tsx @@ -4,6 +4,7 @@ import AITechnologyIcon from '../AllServicesDropdown/icon-ai-technology'; import ACSIcon from '../AllServicesDropdown/icon-acs'; import AnsibleIcon from '../AllServicesDropdown/icon-ansible'; import AppServicesIcon from '../AllServicesDropdown/icon-app-services'; +import BrainIcon from '../AllServicesDropdown/icon-brain'; import DataScienceIcon from '../AllServicesDropdown/icon-data-science'; import EdgeIcon from '../AllServicesDropdown/icon-edge'; import InsightsIcon from '../AllServicesDropdown/icon-insights'; @@ -34,6 +35,7 @@ export enum FavorableIcons { ACSIcon = 'ACSIcon', AnsibleIcon = 'AnsibleIcon', AppServicesIcon = 'AppServicesIcon', + BrainIcon = 'BrainIcon', DataScienceIcon = 'DataScienceIcon', EdgeIcon = 'EdgeIcon', InsightsIcon = 'InsightsIcon', @@ -66,6 +68,7 @@ const iconEnum: { [key in FavorableIcons]: React.ComponentType } = { ACSIcon, AnsibleIcon, AppServicesIcon, + BrainIcon, DataScienceIcon, EdgeIcon, InsightsIcon, From 1f7cded0409cdd69da364b996af4319456c8a5c3 Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Mon, 20 May 2024 15:27:16 -0500 Subject: [PATCH 44/46] use brain icon from patternfly --- src/components/AllServicesDropdown/icon-brain.tsx | 10 ---------- src/components/FavoriteServices/ServiceIcon.tsx | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 src/components/AllServicesDropdown/icon-brain.tsx diff --git a/src/components/AllServicesDropdown/icon-brain.tsx b/src/components/AllServicesDropdown/icon-brain.tsx deleted file mode 100644 index 452bc6a4b..000000000 --- a/src/components/AllServicesDropdown/icon-brain.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; - -const BrainIcon = () => { - return ( - - - - ); -}; -export default BrainIcon; diff --git a/src/components/FavoriteServices/ServiceIcon.tsx b/src/components/FavoriteServices/ServiceIcon.tsx index 1708114de..f2bb2f9e5 100644 --- a/src/components/FavoriteServices/ServiceIcon.tsx +++ b/src/components/FavoriteServices/ServiceIcon.tsx @@ -4,7 +4,6 @@ import AITechnologyIcon from '../AllServicesDropdown/icon-ai-technology'; import ACSIcon from '../AllServicesDropdown/icon-acs'; import AnsibleIcon from '../AllServicesDropdown/icon-ansible'; import AppServicesIcon from '../AllServicesDropdown/icon-app-services'; -import BrainIcon from '../AllServicesDropdown/icon-brain'; import DataScienceIcon from '../AllServicesDropdown/icon-data-science'; import EdgeIcon from '../AllServicesDropdown/icon-edge'; import InsightsIcon from '../AllServicesDropdown/icon-insights'; @@ -29,6 +28,7 @@ import UsersIcon from '@patternfly/react-icons/dist/dynamic/icons/users-icon'; import MonitoringIcon from '@patternfly/react-icons/dist/dynamic/icons/monitoring-icon'; import AutomationIcon from '@patternfly/react-icons/dist/dynamic/icons/automation-icon'; import BellIcon from '@patternfly/react-icons/dist/dynamic/icons/bell-icon'; +import BrainIcon from '@patternfly/react-icons/dist/dynamic/icons/brain-icon'; export enum FavorableIcons { AITechnologyIcon = 'AITechnologyIcon', @@ -68,7 +68,6 @@ const iconEnum: { [key in FavorableIcons]: React.ComponentType } = { ACSIcon, AnsibleIcon, AppServicesIcon, - BrainIcon, DataScienceIcon, EdgeIcon, InsightsIcon, @@ -93,6 +92,7 @@ const iconEnum: { [key in FavorableIcons]: React.ComponentType } = { ShoppingCartIcon, CubeIcon, BoxesIcon, + BrainIcon, MonitoringIcon, }; From fe512ff135353f79def769f65a10d1938a0a6f2c Mon Sep 17 00:00:00 2001 From: Martin Marosi Date: Thu, 23 May 2024 09:15:16 +0200 Subject: [PATCH 45/46] Remove business-services bundle references. --- src/components/AppFilter/useAppFilter.test.js | 2 +- src/components/AppFilter/useAppFilter.ts | 1 - src/components/Routes/Routes.tsx | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/AppFilter/useAppFilter.test.js b/src/components/AppFilter/useAppFilter.test.js index 9e7f2017d..a3ff799b8 100644 --- a/src/components/AppFilter/useAppFilter.test.js +++ b/src/components/AppFilter/useAppFilter.test.js @@ -91,7 +91,7 @@ describe('useAppFilter', () => { await act(async () => { result.current.setIsOpen(true); }); - expect(axiosGetSpy).toHaveBeenCalledTimes(10); + expect(axiosGetSpy).toHaveBeenCalledTimes(9); for (let index = 0; index < 8; index++) { expect(axiosGetSpy.mock.calls[index]).toEqual([ `/api/chrome-service/v1/static/stable/stage/navigation/${requiredBundles[index]}-navigation.json?ts=666`, diff --git a/src/components/AppFilter/useAppFilter.ts b/src/components/AppFilter/useAppFilter.ts index 56e79d90c..bc0c8144a 100644 --- a/src/components/AppFilter/useAppFilter.ts +++ b/src/components/AppFilter/useAppFilter.ts @@ -25,7 +25,6 @@ export const requiredBundles = [ 'settings', 'iam', 'quay', - 'business-services', 'subscriptions', ...(!isProd() ? previewBundles : isBeta() ? previewBundles : []), ].filter(Boolean); diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index 6f8046460..dd30eb4b7 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -52,10 +52,6 @@ const redirects = [ path: '/subscriptions', to: '/subscriptions/overview', }, - { - path: '/business-services', - to: '/business-services/hybrid-committed-spend', - }, { path: '/docs', to: '/docs/api', From 76ccaa5118c8ae0e9683dcba191b38be950148d1 Mon Sep 17 00:00:00 2001 From: Dan Labrecque Date: Thu, 23 May 2024 10:19:45 -0400 Subject: [PATCH 46/46] Remove old business-services filter --- src/components/AppFilter/useAppFilter.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/components/AppFilter/useAppFilter.ts b/src/components/AppFilter/useAppFilter.ts index bc0c8144a..75defc33e 100644 --- a/src/components/AppFilter/useAppFilter.ts +++ b/src/components/AppFilter/useAppFilter.ts @@ -31,19 +31,7 @@ export const requiredBundles = [ export const itLessBundles = ['openshift', 'insights', 'settings', 'iam']; -const bundlesOrder = [ - 'application-services', - 'openshift', - 'rhel', - 'edge', - 'ansible', - 'settings', - 'cost-management', - 'subscriptions', - 'iam', - 'quay', - 'business-services', -]; +const bundlesOrder = ['application-services', 'openshift', 'rhel', 'edge', 'ansible', 'settings', 'cost-management', 'subscriptions', 'iam', 'quay']; function findModuleByLink(href: string, { modules }: Pick = { modules: [] }) { const routes = (modules || [])