diff --git a/cypress.config.ts b/cypress.config.ts index c112d4c4c..f4f28ab5c 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -31,7 +31,7 @@ export default defineConfig({ }, }, e2e: { - blockHosts: ['static.redhat.com', 'consent.trustarc.com', 'www.redhat.com/en/cms/ajax/site-switcher'], + blockHosts: ['consent.trustarc.com'], baseUrl: 'https://stage.foo.redhat.com:1337/beta', env: { E2E_USER: process.env.E2E_USER, diff --git a/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx b/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx index 6203698bf..760e1dea6 100644 --- a/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx +++ b/cypress/component/AllServicesDropdown/AllServicesDropdown.cy.tsx @@ -23,11 +23,11 @@ describe('', () => { it('should close all services dropdown in link matches current pathname', () => { function checkMenuClosed() { cy.get('.pf-v5-c-menu-toggle__text').click(); - cy.contains('Browse all services').should('exist'); + cy.contains('All services').should('exist'); cy.contains('Favorites').click(); cy.contains('Test section').click(); cy.contains('Test link').click(); - cy.contains('Browse all services').should('not.exist'); + cy.contains('All services').should('not.exist'); } cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/services/services.json', [ { diff --git a/cypress/component/AllServicesPage/AllServicesPage.cy.tsx b/cypress/component/AllServicesPage/AllServicesPage.cy.tsx new file mode 100644 index 000000000..03a55d685 --- /dev/null +++ b/cypress/component/AllServicesPage/AllServicesPage.cy.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import AllServices from '../../../src/layouts/AllServices'; +import { BrowserRouter } from 'react-router-dom'; +import { IntlProvider } from 'react-intl'; +import { Provider } from 'react-redux'; +import { createStore } from 'redux'; +import { ScalprumProvider } from '@scalprum/react-core'; +import { getVisibilityFunctions, initializeVisibilityFunctions } from '../../../src/utils/VisibilitySingleton'; +import userFixture from '../../fixtures/testUser.json'; +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', { + status: 200, + fixture: 'services.json', + }); + cy.intercept('http://localhost:8080/entry?cacheBuster=*', ''); + cy.intercept('http://localhost:8080/foo/bar.json', { + foo: { + entry: ['/entry'], + }, + }); + cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/navigation/settings-navigation.json?ts=*', { + status: 200, + fixture: 'settings-navigation.json', + }); + // cy.intercept('http://localhost:8080/api/chrome-service/v1/static/stable/stage/navigation/*-navigation.json?ts=*', { + // data: [], + // }); + }); + + it('should filter by service category title', () => { + initializeVisibilityFunctions({ + getToken: () => Promise.resolve(''), + getUser: () => Promise.resolve(userFixture as unknown as ChromeUser), + getUserPermissions: () => Promise.resolve([]), + }); + const visibilityFunctions = getVisibilityFunctions(); + const store = createStore(() => ({ + chrome: { + moduleRoutes: [ + { + path: '/test/link', + scope: 'foo', + module: 'bar', + }, + ], + }, + })); + cy.mount( + + + + + + + + + + ); + + cy.get('.pf-v5-c-text-input-group__text-input').type('consoleset'); + cy.contains('Console Settings').should('exist'); + }); +}); diff --git a/cypress/e2e/release-gate/navigation.cy.ts b/cypress/e2e/release-gate/navigation.cy.ts index 7b74e120d..7abcabbd1 100644 --- a/cypress/e2e/release-gate/navigation.cy.ts +++ b/cypress/e2e/release-gate/navigation.cy.ts @@ -14,10 +14,10 @@ describe('Navigation', () => { cy.get('.chr-c-link-service-toggle').click(); // check if favorite services links exist - cy.contains('.pf-v5-c-tabs__link', 'My favorite services'); + cy.contains('.pf-v5-c-tabs__link', 'Favorites'); // click on all services - cy.get('.chr-l-flex__item-browse-all-services a').click(); + cy.get('.chr-l-stack__item-browse-all-services a').click(); // get users link cy.get('p:contains("Users")').click(); diff --git a/cypress/e2e/release-gate/search.cy.tsx b/cypress/e2e/release-gate/search.cy.tsx deleted file mode 100644 index b88347640..000000000 --- a/cypress/e2e/release-gate/search.cy.tsx +++ /dev/null @@ -1,69 +0,0 @@ -const searchResponse = { - response: { - numFound: 2, - start: 0, - maxScore: 10.0, - docs: [ - { - id: 'hcc-module-/openshift/create-OPENSHIFT.cluster.create.azure', - view_uri: 'https://console.redhat.com/openshift/create', - documentKind: 'ModuleDefinition', - allTitle: 'Azure Red Hat OpenShift', - bundle: ['openshift'], - bundle_title: ['OpenShift'], - relative_uri: '/openshift/create', - alt_titles: ['ARO', 'Azure', 'OpenShift on Azure'], - abstract: 'https://console.redhat.com/openshift/create', - timestamp: '2023-08-22T17:01:31.717Z', - _version_: 1774949404248113152, - }, - { - id: 'hcc-module-/openshift/releases-openshift.releases', - view_uri: 'https://console.redhat.com/openshift/releases', - documentKind: 'ModuleDefinition', - allTitle: 'Releases', - bundle: ['openshift'], - bundle_title: ['OpenShift'], - relative_uri: '/openshift/releases', - icons: 'InfrastructureIcon', - abstract: 'View general information on the most recent OpenShift Container Platform release versions that you can install.', - timestamp: '2023-08-15T10:55:46.769Z', - _version_: 1774949404248113152, - }, - ], - }, - highlighting: { - 'hcc-module-/openshift/create-OPENSHIFT.cluster.create.azure': { - abstract: ['https://console.redhat.com/openshift/create'], - allTitle: ['Azure Red Hat OpenShift'], - bundle: ['openshift'], - }, - 'hcc-module-/openshift/releases-openshift.releases': { - abstract: ['View general information on the most recent OpenShift Container Platform release versions that you can install.'], - allTitle: ['Releases'], - bundle: ['openshift'], - }, - }, -}; - -describe('Search', () => { - it('search for openshift services', () => { - cy.login(); - cy.visit('/'); - cy.intercept( - { - method: 'GET', - url: '**/hydra/rest/search/**', - }, - searchResponse - ).as('search'); - cy.get('.chr-c-search__input').click().type('openshift'); - cy.wait('@search').its('response.statusCode').should('equal', 200); - cy.get('@search.all').should('have.length', 1); - cy.screenshot(); - cy.get('.chr-c-search__input').should('contain', 'Top 2 results'); - cy.get('.chr-c-search__input li').first().should('contain', 'Azure'); - cy.get('.chr-c-search__input li').last().should('contain', 'Releases').click(); - cy.url().should('contain', '/openshift/releases'); - }); -}); diff --git a/cypress/fixtures/services.json b/cypress/fixtures/services.json new file mode 100644 index 000000000..8087e49c4 --- /dev/null +++ b/cypress/fixtures/services.json @@ -0,0 +1,508 @@ +[ + { + "id": "dataset", + "icon": "LightBulbIcon", + "title": "AI/ML", + "description": "Create, manage, and migrate relational and non-relational databases.", + "links": [ + { + "isGroup": true, + "title": "Application and Data Services", + "links": [ + "application-services.dataScience" + ] + } + ] + }, + { + "id": "automation", + "title": "Automation", + "icon": "AutomationIcon", + "description": "Solve problems once, in one place, and scale up.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + "rhel.remediations", + "rhel.tasks" + ] + }, + { + "isGroup": true, + "title": "Ansible", + "links": [ + { + "title": "Ansible Hub", + "href": "/ansible/automation-hub/", + "icon": "AnsibleIcon" + }, + { + "title": "Automation Analytics", + "href": "/ansible/automation-analytics/reports", + "icon": "AnsibleIcon", + "description": "Plan, measure, and scale your automation using actionable data." + }, + "ansible.inventory", + { + "title": "Register Systems", + "filterable": false, + "href": "/ansible/registration", + "icon": "AnsibleIcon" + }, + "ansible.tasks" + ] + } + ] + }, + { + "id": "containers", + "title": "Containers", + "icon": "CubeIcon", + "description": "Run your applications in a consistent and isolated environment.", + "links": [ + { + "isGroup": true, + "title": "OpenShift", + "links": [ + { + "title": "Clusters", + "href": "/openshift", + "icon": "OpenShiftIcon", + "description": "View, Register, or Create an OpenShift Cluster." + } + ] + }, + { + "isGroup": true, + "title": "Quay.io", + "links": [ + "quay.quayOrganizations" + ] + }, + { + "isGroup": true, + "title": "Application and Data Services", + "links": [ + "application-services.trustedContentOverview", + "application-services.apiManagement" + ] + } + ] + }, + { + "id": "deploy", + "icon": "RocketIcon", + "title": "Deploy", + "description": "Create RHEL images, systems at the Edge, and OpenShift clusters.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + "rhel.imageBuilder" + ] + }, + { + "isGroup": true, + "title": "Quay.io", + "links": [ + "quay.quayRepositories" + ] + }, + { + "isGroup": true, + "title": "Edge", + "links": [ + { + "title": "Images", + "href": "/edge/manage-images", + "icon": "EdgeIcon", + "description": "Manage the lifecycle and enhance security of your RHEL systems at the edge." + } + ] + } + ] + }, + { + "id": "iam", + "icon": "UsersIcon", + "title": "Identity and Access Management", + "description": "Ensure that the right users have the appropriate access to technology resources.", + "links": [ + { + "isGroup": true, + "title": "IAM", + "links": [ + "iam.users", + "iam.groups", + "iam.authFactors" + ] + }, + { + "isGroup": true, + "title": "Application and Data Services", + "links": [ + { + "title": "Service Accounts", + "href": "/application-services/service-accounts", + "icon": "ServicesIcon", + "description": "Authenticate and connect securely to APIs from multiple services." + } + ] + } + ] + }, + { + "id": "integrations-notifications", + "icon": "BellIcon", + "title": "Integrations and Notifications", + "description": "Alerts users to events, using email and integrations such as webhooks.", + "links": [ + { + "isGroup": true, + "title": "Console Settings", + "links": [ + "settings.integrations", + "settings.notifications" + ] + } + ] + }, + { + "id": "inventories", + "icon": "BoxesIcon", + "title": "Inventories", + "description": "View OpenShift clusters, Edge systems, RHEL hosts, and your organization's subscriptions.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + "rhel.imageBuilder", + "rhel.subscriptionsInventory", + "rhel.inventory", + { + "title": "Inventory Groups", + "href": "/insights/inventory/groups", + "icon": "InsightsIcon" + } + ] + }, + { + "isGroup": true, + "title": "OpenShift", + "links": [ + "openshift.clusters" + ] + }, + { + "isGroup": true, + "title": "Ansible", + "links": [ + "ansible.inventory" + ] + }, + { + "isGroup": true, + "title": "Subscription Services", + "links": [ + "subscriptions.subscriptionsInventory" + ] + } + ] + }, + { + "id": "observe", + "icon": "ChartLineIcon", + "title": "Observability and Monitoring", + "description": "Monitor, troubleshoot, and improve application performance.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + "rhel.advisories", + "rhel.repositories", + { + "href": "/insights/patch/systems", + "title": "Patch", + "icon": "InsightsIcon" + }, + { + "href": "/insights/advisor/recommendations", + "title": "Advisor", + "icon": "InsightsIcon", + "subtitle": "Red Hat Insights for RHEL", + "description": "View details about your Red Hat Enterprise Linux systems." + }, + { + "href": "/insights/drift", + "title": "Drift", + "icon": "InsightsIcon", + "subtitle": "Red Hat Insights for RHEL", + "description": "Compare systems in your Red Hat Enterprise Linux inventory to one another or against a set baseline." + }, + "rhel.policies" + ] + }, + { + "isGroup": true, + "title": "OpenShift", + "links": [ + { + "href": "/openshift/insights/advisor/recommendations", + "icon": "OpenShiftIcon", + "title": "Advisor", + "subtitle": "Red Hat Insights for OpenShift", + "description": "See targeted recommendations to optimize your OpenShift clusters’ availability, performance, and security." + }, + { + "href": "/openshift/insights/vulnerability/cves", + "icon": "OpenShiftIcon", + "title": "Vulnerability", + "subtitle": "Red Hat Insights for OpenShift", + "description": "Identify and prioritize security vulnerabilities within your OpenShift clusters based on severity and frequency." + } + ] + }, + { + "isGroup": true, + "title": "Ansible", + "links": [ + { + "href": "/ansible/advisor/recommendations", + "title": "Advisor", + "subtitle": "Red Hat Insights for Ansible", + "icon": "AnsibleIcon", + "description": "See targeted recommendations to optimize your Ansible hosts’ availability, performance, and security." + }, + { + "title": "Drift", + "href": "/ansible/drift", + "icon": "AnsibleIcon", + "subtitle": "Red Hat Insights for Ansible", + "description": "Compare systems in your Ansible inventory to one another or against a set baseline." + }, + "ansible.policies" + ] + }, + { + "isGroup": true, + "title": "Subscription Services", + "links": [ + { + "id": "openshift", + "title": "Subscriptions Usage", + "icon": "OpenShiftIcon", + "href": "/subscriptions/usage/openshift" + } + ] + } + ] + }, + { + "id": "security", + "icon": "CloudSecurityIcon", + "title": "Security", + "description": "Meet your policy and compliance objectives.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + "rhel.advisories", + { + "href": "/insights/advisor/recommendations", + "title": "Advisor", + "icon": "InsightsIcon", + "subtitle": "Red Hat Insights for RHEL", + "description": "View details about your Red Hat Enterprise Linux systems." + }, + { + "href": "/insights/vulnerability/cves", + "icon": "InsightsIcon", + "title": "Vulnerability", + "subtitle": "Red Hat Insights for RHEL", + "description": "Identify and prioritize security vulnerabilities within your Red Hat Enterprise Linux systems based on severity and frequency." + }, + { + "href": "/insights/compliance/reports", + "icon": "InsightsIcon", + "title": "Compliance", + "subtitle":"Red Hat Insights for RHEL", + "description": "Evaluate your Red Hat Enterprise systems’ compliance with security or regulatory standards." + }, + { + "href": "/insights/malware/signatures", + "title": "Malware", + "icon": "InsightsIcon", + "subtitle": "Red Hat Insights for RHEL", + "description": "Identify potential malware on your Red Hat Enterprise Linux systems." + }, + "rhel.remediations" + ] + }, + { + "isGroup": true, + "title": "OpenShift", + "links": [ + { + "href": "/openshift/insights/vulnerability/cves", + "icon": "OpenShiftIcon", + "title": "Vulnerability", + "subtitle": "Red Hat Insights for OpenShift" + } + ] + }, + { + "isGroup": true, + "title": "Ansible", + "links": [ + "ansible.remediations" + ] + }, + { + "isGroup": true, + "title": "Quay.io", + "links": [ + "quay.quayOrganizations" + ] + }, + { + "isGroup": true, + "title": "Application and Data Services", + "links": [ + "application-services.trustedContentOverview", + { + "title": "Advanced Cluster Security", + "href": "/application-services/acs/overview", + "icon": "ACSIcon", + "description": "Securely build, deploy, and run your cloud applications using Kubernetes-native architecture." + } + ] + } + ] + }, + { + "id": "subscriptions", + "icon": "CreditCardIcon", + "title": "Subscriptions and Spend", + "description": "Subscription Services empower buying decisions. SaMS provides software usage reporting that is designed to make your subscription choices data-driven.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + { + "title": "Subscriptions", + "href": "/insights/subscriptions/rhel", + "icon": "OpenShiftIcon" + }, + { + "title": "Resource Optimization", + "filterable": false, + "href": "/insights/ros", + "icon": "OpenShiftIcon" + } + ] + }, + { + "isGroup": true, + "title": "OpenShift", + "links": [ + { + "title": "Subscriptions", + "href": "/openshift/subscriptions/openshift", + "icon": "OpenShiftIcon" + }, + { + "title": "Cost Management", + "filterable": false, + "href": "/openshift/cost-management", + "icon": "OpenShiftIcon" + } + ] + }, + { + "isGroup": true, + "title": "Subscription Services", + "links": [ + "subscriptions.subscriptionsInventory", + "subscriptions.subscriptionsUsage", + "hybridCommittedSpend.hybridCommittedSpend" + ] + } + ] + }, + { + "id": "systemConfiguration", + "icon": "CogIcon", + "title": "System Configuration", + "description": "Connect your RHEL systems to Hybrid Cloud Console services.", + "links": [ + { + "isGroup": true, + "title": "Red Hat Enterprise Linux", + "links": [ + { + "href": "/insights/connector", + "title": "Remote Host Configuration (RHC)", + "icon": "InsightsIcon", + "subtitle": "Red Hat Insights for RHEL", + "description": "Configure your systems to execute Ansible Playbooks." + }, + "settings.manageConfiguration", + "rhel.activationKeys", + "rhel.manifests", + "rhel.registerSystems", + "rhel.stalenessAndDeletion" + ] + }, + { + "isGroup": true, + "title": "Ansible", + "links": [ + { + "title": "Register Systems", + "filterable": false, + "href": "/ansible/registration", + "icon": "AnsibleIcon" + } + ] + }, + { + "isGroup": true, + "title": "Console Settings", + "links": [ + "settings.integrations", + "settings.notifications" + ] + } + ] + }, + { + "id": "tryBuy", + "icon": "ShoppingCartIcon", + "title": "Try and Buy", + "description": "Our no-cost trials help you gain hands-on experience, prepare for a certification, or assess if a product is right for your organization.", + "links": [ + "openshift.developerSandbox", + { + "isExternal": true, + "href": "https://marketplace.redhat.com/en-us", + "title": "Red Hat Marketplace", + "icon": "RHIcon", + "description": "Find, try, purchase, and deploy your software across clouds." + }, + { + "isExternal": true, + "href": "https://www.redhat.com/en/products/trials", + "title": "Red Hat Product Trials", + "icon": "RHIcon", + "description": "Gain hands-on experience and assess if a product is right for you in a no-cost trial." + } + ] + } + ] + \ No newline at end of file diff --git a/cypress/fixtures/settings-navigation.json b/cypress/fixtures/settings-navigation.json new file mode 100644 index 000000000..30ceaab4f --- /dev/null +++ b/cypress/fixtures/settings-navigation.json @@ -0,0 +1,107 @@ +{ + "id": "settings", + "title": "Settings", + "navItems": [ + { + "id": "sources", + "appId": "sources", + "title": "Integrations", + "description": "Integrations provide a way for applications to collect data outside of the Red Hat Hybrid Cloud Console through either a direct connection to the source or indirectly.", + "href": "/settings/integrations", + "icon": "PlaceholderIcon", + "alt_title": [ + "providers", + "cloud providers", + "cloud sources", + "Red Hat sources", + "integrations", + "cloud integrations", + "cloud connection", + "aws", + "Amazon", + "Google", + "cloud", + "IBM", + "Microsoft", + "secrets", + "Azure", + "Oracle", + "Infrastructure", + "prediction", + "cost", + "subscriptions", + "account", + "credentials" + ] + }, + { + "id": "learningResources", + "appId": "learningResources", + "title": "Learning Resources", + "href": "/settings/learning-resources" + }, + { + "id": "idmsvc", + "appId": "idmsvc", + "title": "Directory & Domain Services", + "description": "Directory and Domain Services for console.redhat.com", + "href": "/settings/idmsvc", + "icon": "PlaceholderIcon" + }, + { + "title": "Notifications", + "id": "notifications", + "description": "A standardized way of notifying users of events for supported services on the Hybrid Cloud Console.", + "expandable": true, + "routes": [ + { + "id": "notificationOverview", + "appId": "notifications", + "icon": "PlaceholderIcon", + "title": "Overview", + "href": "/settings/notifications" + }, + { + "id": "configureEvents", + "appId": "notifications", + "title": "Configure Events", + "href": "/settings/notifications/configure-events", + "permissions": [ + { + "method": "isOrgAdmin" + } + ] + }, + { + "id": "eventLog", + "appId": "notifications", + "title": "Event Log", + "href": "/settings/notifications/eventlog", + "permissions": [ + { + "method": "isOrgAdmin" + } + ] + }, + { + "id": "notificationsLog", + "appId": "notifications", + "title": "Notifications Log", + "href": "/settings/notifications/notificationslog", + "permissions": [ + { + "method": "featureFlag", + "args": ["platform.chrome.notifications-drawer", true] + } + ] + }, + { + "id": "myUserPreferences", + "appId": "notifications", + "title": "My User Preferences", + "href": "/settings/notifications/user-preferences" + } + ] + } + ] +} diff --git a/package-lock.json b/package-lock.json index e45a73400..b215000db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@patternfly/react-core": "^5.0.1", "@patternfly/react-icons": "^5.0.1", "@patternfly/react-tokens": "^5.0.1", - "@redhat-cloud-services/chrome": "^1.0.2", + "@redhat-cloud-services/chrome": "^1.0.4", "@redhat-cloud-services/entitlements-client": "1.2.0", "@redhat-cloud-services/frontend-components": "^4.0.10", "@redhat-cloud-services/frontend-components-notifications": "^4.0.2", @@ -150,9 +150,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.0.tgz", - "integrity": "sha512-+RNNcQvw2V1bmnBTPAtOLfW/9mhH2vC67+rUSi5T8EtEWt6lEnGNY2GuhZ1/YwbgikT1TkhvidCDmN5Q5YCo/w==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", + "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -219,12 +219,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" }, "engines": { @@ -289,12 +289,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -320,22 +320,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -427,9 +427,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -459,12 +459,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -473,9 +473,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -672,33 +672,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -707,13 +707,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2757,20 +2757,19 @@ "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA==" }, "node_modules/@patternfly/quickstarts": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.0.0.tgz", - "integrity": "sha512-G1nb0x+jmO/F2fVv+bymadvjO+RZWwY3foU+1VBqvI28vtr7M6isLj81Cz8cjjT0t0Z2CdMSVVfkwxoKQxMOgA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.1.0.tgz", + "integrity": "sha512-ql5Q8IlW+Yp1Y7rqDqrsoDhYrSv3/HTp+1BYg7n4vyOsTc9QL+PxW4+PI8mLLk/tB6Z93yS7l76b5gaACPgH2g==", "dependencies": { "@patternfly/react-catalog-view-extension": "^5.0.0", "dompurify": "^2.2.6", - "history": "^5.0.0", - "showdown": "1.8.6" + "history": "^5.0.0" }, "peerDependencies": { - "@patternfly/react-core": ">=4.115.2", + "@patternfly/react-core": ">=5.0.0", "react": ">=16.8.0", "react-dom": ">=16.8.0", - "showdown": ">=1.8.6" + "showdown": ">=2.1.0" } }, "node_modules/@patternfly/react-catalog-view-extension": { @@ -3017,9 +3016,12 @@ } }, "node_modules/@redhat-cloud-services/chrome": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/chrome/-/chrome-1.0.2.tgz", - "integrity": "sha512-NDmtDcrRspMuuPlgEFMgYokj3B3w1xkUdeAlatSzF5Y2eNl3DMJpE3/DMNL+gFDq7U7S/7pu/EODGym7yz07Pg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/chrome/-/chrome-1.0.4.tgz", + "integrity": "sha512-lERy/qYzZM5Lpj6m+uE4Sh5KNQzfK6s6B35eiLt6eZ64Q3VPtgTe3louQtiBo2AoxJvnvl0LBE9HNv2wujrIyg==", + "dependencies": { + "lodash": "^4.17.21" + }, "peerDependencies": { "@scalprum/react-core": "^0.5.1", "react": "^18.2.0", @@ -10439,14 +10441,6 @@ "node": ">= 0.12.0" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -11398,14 +11392,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -14735,14 +14721,6 @@ "tslib": "^2.4.0" } }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", @@ -18966,17 +18944,6 @@ "node": "> 0.8" } }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -19591,25 +19558,6 @@ "node": ">= 0.6" } }, - "node_modules/mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ==", - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "engines": { - "node": ">=4" - } - }, "node_modules/memfs": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", @@ -20309,14 +20257,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nwsapi": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", @@ -20659,125 +20599,6 @@ "node": ">=8" } }, - "node_modules/os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dependencies": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/os-locale/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/os-locale/node_modules/execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "dependencies": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/os-locale/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/os-locale/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-locale/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/os-locale/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/os-locale/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/os-locale/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-locale/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-locale/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/os-locale/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" - }, "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", @@ -21249,9 +21070,9 @@ } }, "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -21860,11 +21681,6 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==" }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -22708,6 +22524,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -22721,11 +22538,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" - }, "node_modules/requirejs": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", @@ -23387,11 +23199,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -23444,224 +23251,28 @@ } }, "node_modules/showdown": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.8.6.tgz", - "integrity": "sha512-cOmS+LUIiyMxFo7OU3cgV+zTv43GItwlTwUPrpUd5dqdlZh8CJMVb8KxAMhr42J6exQwKTCHMxUiG74vamV1kA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "peer": true, "dependencies": { - "yargs": "^10.0.3" + "commander": "^9.0.0" }, "bin": { "showdown": "bin/showdown.js" - } - }, - "node_modules/showdown/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dependencies": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/showdown/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dependencies": { - "locate-path": "^2.0.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "node_modules/showdown/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/showdown/node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/showdown/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/showdown/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/showdown/node_modules/wrap-ansi/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "individual", + "url": "https://www.paypal.me/tiviesantos" } }, - "node_modules/showdown/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dependencies": { - "ansi-regex": "^2.0.0" - }, + "node_modules/showdown/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "peer": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/showdown/node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - }, - "node_modules/showdown/node_modules/yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", - "dependencies": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" - } - }, - "node_modules/showdown/node_modules/yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", - "dependencies": { - "camelcase": "^4.1.0" + "node": "^12.20.0 || >=14" } }, "node_modules/side-channel": { @@ -24160,14 +23771,6 @@ "node": ">=8" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -26995,11 +26598,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, "node_modules/which-typed-array": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", @@ -27223,9 +26821,9 @@ "dev": true }, "@adobe/css-tools": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.0.tgz", - "integrity": "sha512-+RNNcQvw2V1bmnBTPAtOLfW/9mhH2vC67+rUSi5T8EtEWt6lEnGNY2GuhZ1/YwbgikT1TkhvidCDmN5Q5YCo/w==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", + "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", "dev": true }, "@ampproject/remapping": { @@ -27290,12 +26888,12 @@ } }, "@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" } }, @@ -27340,12 +26938,12 @@ } }, "@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -27365,19 +26963,19 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { @@ -27442,9 +27040,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -27465,20 +27063,20 @@ } }, "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==" + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -27615,42 +27213,42 @@ } }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -29260,14 +28858,13 @@ "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA==" }, "@patternfly/quickstarts": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.0.0.tgz", - "integrity": "sha512-G1nb0x+jmO/F2fVv+bymadvjO+RZWwY3foU+1VBqvI28vtr7M6isLj81Cz8cjjT0t0Z2CdMSVVfkwxoKQxMOgA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@patternfly/quickstarts/-/quickstarts-5.1.0.tgz", + "integrity": "sha512-ql5Q8IlW+Yp1Y7rqDqrsoDhYrSv3/HTp+1BYg7n4vyOsTc9QL+PxW4+PI8mLLk/tB6Z93yS7l76b5gaACPgH2g==", "requires": { "@patternfly/react-catalog-view-extension": "^5.0.0", "dompurify": "^2.2.6", - "history": "^5.0.0", - "showdown": "1.8.6" + "history": "^5.0.0" } }, "@patternfly/react-catalog-view-extension": { @@ -29457,10 +29054,12 @@ } }, "@redhat-cloud-services/chrome": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@redhat-cloud-services/chrome/-/chrome-1.0.2.tgz", - "integrity": "sha512-NDmtDcrRspMuuPlgEFMgYokj3B3w1xkUdeAlatSzF5Y2eNl3DMJpE3/DMNL+gFDq7U7S/7pu/EODGym7yz07Pg==", - "requires": {} + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@redhat-cloud-services/chrome/-/chrome-1.0.4.tgz", + "integrity": "sha512-lERy/qYzZM5Lpj6m+uE4Sh5KNQzfK6s6B35eiLt6eZ64Q3VPtgTe3louQtiBo2AoxJvnvl0LBE9HNv2wujrIyg==", + "requires": { + "lodash": "^4.17.21" + } }, "@redhat-cloud-services/entitlements-client": { "version": "1.2.0", @@ -34045,11 +33644,6 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" - }, "collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -34786,11 +34380,6 @@ "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" - }, "decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -37304,11 +36893,6 @@ } } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==" - }, "ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", @@ -40514,14 +40098,6 @@ "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==" }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "requires": { - "invert-kv": "^1.0.0" - } - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -40978,21 +40554,6 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha512-nOBDrc/wgpkd3X/JOhMqYR+/eLqlfLP4oQfoBA6QExIxEl+GU01oyEkwWyueyO8110pUKijtiHGhEmYoOn88oQ==", - "requires": { - "mimic-fn": "^1.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - } - } - }, "memfs": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", @@ -41520,11 +41081,6 @@ "boolbase": "^1.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" - }, "nwsapi": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", @@ -41773,100 +41329,6 @@ } } }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" - } - } - }, "ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", @@ -42231,9 +41693,9 @@ "dev": true }, "postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -42664,11 +42126,6 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==" }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" - }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -43298,7 +42755,8 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true }, "require-from-string": { "version": "2.0.2", @@ -43306,11 +42764,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==" - }, "requirejs": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", @@ -43794,11 +43247,6 @@ "send": "0.18.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -43839,176 +43287,19 @@ "dev": true }, "showdown": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.8.6.tgz", - "integrity": "sha512-cOmS+LUIiyMxFo7OU3cgV+zTv43GItwlTwUPrpUd5dqdlZh8CJMVb8KxAMhr42J6exQwKTCHMxUiG74vamV1kA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "peer": true, "requires": { - "yargs": "^10.0.3" + "commander": "^9.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==" - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" - }, - "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" - } - }, - "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", - "requires": { - "camelcase": "^4.1.0" - } + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "peer": true } } }, @@ -44412,11 +43703,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==" - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -46770,11 +46056,6 @@ "is-weakset": "^2.0.1" } }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, "which-typed-array": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", diff --git a/package.json b/package.json index 94e294116..e46b3b887 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "build:beta": "BETA=true npm run build", "build:dev": "NODE_ENV=development webpack --config config/webpack.config.js --mode=development", "build:res": "NODE_ENV=restricted webpack --config config/webpack.config.js --mode=production", + "build:res:beta": "BETA=true npm run build:res", "cypress": "cypress", "cypress:run": "cypress run --browser electron", "dev": "DEV_SERVER=true webpack serve --config config/webpack.config.js --mode=development", @@ -135,7 +136,7 @@ "@patternfly/react-core": "^5.0.1", "@patternfly/react-icons": "^5.0.1", "@patternfly/react-tokens": "^5.0.1", - "@redhat-cloud-services/chrome": "^1.0.2", + "@redhat-cloud-services/chrome": "^1.0.4", "@redhat-cloud-services/entitlements-client": "1.2.0", "@redhat-cloud-services/frontend-components": "^4.0.10", "@redhat-cloud-services/frontend-components-notifications": "^4.0.2", diff --git a/src/components/AllServices/AllServicesIcons.ts b/src/components/AllServices/AllServicesIcons.ts index a3fbb9407..1f1237120 100644 --- a/src/components/AllServices/AllServicesIcons.ts +++ b/src/components/AllServices/AllServicesIcons.ts @@ -7,7 +7,7 @@ import CloudUploadAltIcon from '@patternfly/react-icons/dist/dynamic/icons/cloud import CogIcon from '@patternfly/react-icons/dist/dynamic/icons/cog-icon'; import CreditCardIcon from '@patternfly/react-icons/dist/dynamic/icons/credit-card-icon'; import CubeIcon from '@patternfly/react-icons/dist/dynamic/icons/cube-icon'; -import DatabaseIcon from '@patternfly/react-icons/dist/dynamic/icons/database-icon'; +import LightBulbIcon from '@patternfly/react-icons/dist/dynamic/icons/lightbulb-icon'; import InfrastructureIcon from '@patternfly/react-icons/dist/dynamic/icons/infrastructure-icon'; import RocketIcon from '@patternfly/react-icons/dist/dynamic/icons/rocket-icon'; import ShoppingCartIcon from '@patternfly/react-icons/dist/dynamic/icons/shopping-cart-icon'; @@ -17,7 +17,7 @@ import MonitoringIcon from '@patternfly/react-icons/dist/dynamic/icons/monitorin const AllServicesIcons = { CloudUploadAltIcon, AutomationIcon, - DatabaseIcon, + LightBulbIcon, RocketIcon, UsersIcon, InfrastructureIcon, diff --git a/src/components/AllServicesDropdown/AllServicesDropdown.scss b/src/components/AllServicesDropdown/AllServicesDropdown.scss index 4bf344a14..3c1ee7fa2 100644 --- a/src/components/AllServicesDropdown/AllServicesDropdown.scss +++ b/src/components/AllServicesDropdown/AllServicesDropdown.scss @@ -13,11 +13,11 @@ .chr-c-page__services-nav-dropdown-menu { @media screen and (min-width: $pf-v5-global--breakpoint--2xl) { top: 70px; - height: calc(100vh - 70px); + height: 100vh; } @media screen and (max-width: $pf-v5-global--breakpoint--2xl) { top: 118px; - height: calc(100vh - 118px); + height: 100vh; } // pos has to be important to override PF styles that get lazy loaded! @@ -39,23 +39,14 @@ @media (max-width: $pf-v5-global--breakpoint--md) { .chr-c-panel-services-nav { - .chr-l-flex__item-browse-all-services { + .chr-l-stack__item-browse-all-services { background: var(--pf-v5-global--BackgroundColor--200); border-bottom: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--dark-100); } .pf-v5-c-tabs { background: var(--pf-v5-global--BackgroundColor--200); border-bottom: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--dark-100); - height: calc(100% - 80px); - } - .pf-v5-c-tabs__toggle-button { - width: 100%; - } - .pf-v5-c-tabs__toggle-button .pf-v5-c-button { - flex-direction: row-reverse; - justify-content: space-between; - padding: var(--pf-v5-global--spacer--sm); - width: 100%; + height: 100%; } .pf-v5-c-sidebar__panel { --pf-v5-l-flex--RowGap: 0; @@ -65,30 +56,22 @@ @media (min-width: $pf-v5-global--breakpoint--md) { .chr-c-panel-services-nav { - .chr-l-flex__item-browse-all-services { - border-top: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--dark-100); - bottom: 0; - position: absolute; + .chr-l-stack__item-browse-all-services { + border-bottom: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--dark-100); } - .pf-v5-c-sidebar { --pf-v5-c-sidebar__panel--md--FlexBasis: 20rem; --pf-v5-c-sidebar__panel--BackgroundColor: var(--pf-v5-global--BackgroundColor--200); &__main { - height: 80vh; + height: 630px; } &__content { - height: 80vh; + height: 630px; overflow: auto; } &__panel { - height: 80vh; - position: relative; + height: 630px; box-shadow: inset -4px 0 4px -4px rgba(0, 0, 0, 0.16); - .chr-l-flex__item-tabs { - overflow: auto; - padding-bottom: var(--pf-v5-global--spacer--2xl); - } .pf-v5-c-tabs { --pf-v5-c-tabs__item--m-current__link--after--BorderColor: transparent; --pf-v5-c-tabs--m-vertical__link--PaddingTop: var(--pf-v5-global--spacer--sm); diff --git a/src/components/AllServicesDropdown/AllServicesMenu.tsx b/src/components/AllServicesDropdown/AllServicesMenu.tsx index 913a5771e..11363cce9 100644 --- a/src/components/AllServicesDropdown/AllServicesMenu.tsx +++ b/src/components/AllServicesDropdown/AllServicesMenu.tsx @@ -2,8 +2,7 @@ import React, { Fragment } from 'react'; import { Backdrop } from '@patternfly/react-core/dist/dynamic/components/Backdrop'; import { Button } from '@patternfly/react-core/dist/dynamic/components/Button'; import { Card, CardBody, CardHeader } from '@patternfly/react-core/dist/dynamic/components/Card'; -import { FlexItem } from '@patternfly/react-core/dist/dynamic/layouts/Flex'; -import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon'; +import { Stack, StackItem } from '@patternfly/react-core/dist/dynamic/layouts/Stack'; import { Panel, PanelMain } from '@patternfly/react-core/dist/dynamic/components/Panel'; import { Sidebar, SidebarContent, SidebarPanel } from '@patternfly/react-core/dist/dynamic/components/Sidebar'; import { TabContent } from '@patternfly/react-core/dist/dynamic/components/Tabs'; @@ -11,7 +10,6 @@ import { Text, TextContent, TextVariants } from '@patternfly/react-core/dist/dyn import { Title } from '@patternfly/react-core/dist/dynamic/components/Title'; import ChromeLink from '../ChromeLink'; -import BookOpenIcon from '@patternfly/react-icons/dist/dynamic/icons/book-open-icon'; import TimesIcon from '@patternfly/react-icons/dist/dynamic/icons/times-icon'; import type { AllServicesSection } from '../AllServices/allServicesLinks'; import FavoriteServicesGallery from '../FavoriteServices/ServicesGallery'; @@ -67,34 +65,30 @@ const AllServicesMenu = ({ setIsOpen, isOpen, menuRef, linkSections, favoritedSe - - - - - - - - - Browse all services - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/components/AllServicesDropdown/AllServicesTabs.tsx b/src/components/AllServicesDropdown/AllServicesTabs.tsx index 1e036e236..21ba0a948 100644 --- a/src/components/AllServicesDropdown/AllServicesTabs.tsx +++ b/src/components/AllServicesDropdown/AllServicesTabs.tsx @@ -83,8 +83,8 @@ const AllServicesTabs = ({ eventKey={FAVORITE_TAB_ID} title={ - My favorite services - + Favorites + diff --git a/src/components/AppFilter/useAppFilter.ts b/src/components/AppFilter/useAppFilter.ts index 476bf3cdd..987b21802 100644 --- a/src/components/AppFilter/useAppFilter.ts +++ b/src/components/AppFilter/useAppFilter.ts @@ -12,7 +12,7 @@ export type AppFilterBucket = { links: NavItem[]; }; -const previewBundles = ['subscriptions']; +const previewBundles = ['']; export const requiredBundles = [ 'application-services', @@ -24,8 +24,9 @@ export const requiredBundles = [ 'iam', 'quay', 'business-services', + 'subscriptions', ...(!isProd() ? previewBundles : isBeta() ? previewBundles : []), -]; +].filter(Boolean); export const itLessBundles = ['openshift', 'insights', 'settings', 'iam']; diff --git a/src/components/ContextSwitcher/ContextSwitcher.scss b/src/components/ContextSwitcher/ContextSwitcher.scss index 5f849f63d..78e6bee8c 100644 --- a/src/components/ContextSwitcher/ContextSwitcher.scss +++ b/src/components/ContextSwitcher/ContextSwitcher.scss @@ -1,7 +1,8 @@ @import '~@patternfly/patternfly/sass-utilities/_all'; .chr-c-context-selector { --pf-v5-c-masthead--c-context-selector--Width: 224px; - .chr-c-content-personal-account { + .chr-c-content-account { + width: 100%; .account-label { display: flex; flex-direction: row; @@ -9,8 +10,14 @@ } } .pf-v5-c-context-selector__menu-list-item { + width: calc(224px - 16px); svg { font-size: 9px; } + small.account-name { + text-overflow: ellipsis; + overflow: hidden; + text-align: initial; + } } } diff --git a/src/components/ContextSwitcher/index.tsx b/src/components/ContextSwitcher/index.tsx index b92022798..8a747f7a3 100644 --- a/src/components/ContextSwitcher/index.tsx +++ b/src/components/ContextSwitcher/index.tsx @@ -35,11 +35,19 @@ export type ContextSwitcherProps = { className?: string; }; +// These attributes are present in the response based on the open API spec. +// TODO: Migrate to the new RBAC JS client when it is ready. +type CrossAccountRequestInternal = CrossAccountRequest & { + first_name?: string | null; + last_name?: string | null; + email: string; +}; + const ContextSwitcher = ({ user, className }: ContextSwitcherProps) => { const dispatch = useDispatch(); const intl = useIntl(); const isOpen = useSelector(({ chrome }: ReduxState) => chrome?.contextSwitcherOpen); - const [data, setData] = useState([]); + const [data, setData] = useState([]); const [searchValue, setSearchValue] = useState(''); const [selectedAccountNumber, setSelectedAccountNumber] = useState(user.identity.account_number); const onSelect = () => { @@ -98,7 +106,7 @@ const ContextSwitcher = ({ user, className }: ContextSwitcherProps) => { } } axios - .get<{ data: CrossAccountRequest[] }>('/api/rbac/v1/cross-account-requests/', { + .get<{ data: CrossAccountRequestInternal[] }>('/api/rbac/v1/cross-account-requests/', { params: { status: 'approved', order_by: '-created', @@ -109,7 +117,7 @@ const ContextSwitcher = ({ user, className }: ContextSwitcherProps) => { if (mounted) { setData( data - .reduce((acc, curr) => { + .reduce((acc, curr) => { const request = acc.find(({ target_account }) => target_account === curr.target_account); if (request) { return acc; @@ -148,16 +156,18 @@ const ContextSwitcher = ({ user, className }: ContextSwitcherProps) => { > {user && user?.identity?.account_number?.includes(searchValue) ? ( - + {user?.identity?.account_number} {user?.identity?.account_number === `${selectedAccountNumber}` && ( - - + + )} - {intl.formatMessage(messages.personalAccount)} + + {intl.formatMessage(messages.personalAccount)} + ) : ( @@ -165,14 +175,21 @@ const ContextSwitcher = ({ user, className }: ContextSwitcherProps) => { )} {filteredData?.length === 0 ? {intl.formatMessage(messages.noResults)} : } {filteredData ? ( - filteredData.map(({ target_account, request_id, end_date, target_org }) => ( + filteredData.map(({ target_account, request_id, end_date, target_org, email, first_name, last_name }) => ( handleItemClick(target_account, request_id, end_date, target_org)} key={request_id}> - {target_account} - {target_account === selectedAccountNumber && ( - - - - )} + + + {target_account} + {target_account === selectedAccountNumber && ( + + + + )} + + + {first_name && last_name ? `${first_name} ${last_name}` : email} + + )) ) : ( diff --git a/src/components/Feedback/FeedbackError.tsx b/src/components/Feedback/FeedbackError.tsx index 53fbc5d1f..489de0060 100644 --- a/src/components/Feedback/FeedbackError.tsx +++ b/src/components/Feedback/FeedbackError.tsx @@ -24,7 +24,7 @@ const FeedbackError = ({ onCloseModal }: FeedbackErrorProps) => { {intl.formatMessage(messages.somethingWentWrong)} {intl.formatMessage(messages.problemProcessingRequest)}{' '} - + {intl.formatMessage(messages.redHatSupport)} diff --git a/src/components/Feedback/FeedbackModal.tsx b/src/components/Feedback/FeedbackModal.tsx index 82b142c96..30c21706d 100644 --- a/src/components/Feedback/FeedbackModal.tsx +++ b/src/components/Feedback/FeedbackModal.tsx @@ -124,7 +124,11 @@ const FeedbackModal = memo(({ user }: FeedbackModalProps) => { modalDescription={ {intl.formatMessage(messages.describeReportBug)}{' '} - + {intl.formatMessage(messages.openSupportCase)} diff --git a/src/components/Header/Tools.tsx b/src/components/Header/Tools.tsx index bf6b8685d..308d901ef 100644 --- a/src/components/Header/Tools.tsx +++ b/src/components/Header/Tools.tsx @@ -27,7 +27,6 @@ import { ReduxState } from '../../redux/store'; import BellIcon from '@patternfly/react-icons/dist/dynamic/icons/bell-icon'; import { toggleNotificationsDrawer } from '../../redux/actions'; import useWindowWidth from '../../hooks/useWindowWidth'; -import { usePreviewFlag } from '../../utils/usePreviewFlag'; const isITLessEnv = ITLess(); @@ -81,7 +80,7 @@ const Tools = () => { isRhosakEntitled: false, isDemoAcc: false, }); - const enableIntegrations = usePreviewFlag('platform.sources.integrations'); + const enableIntegrations = useFlag('platform.sources.integrations'); const { xs } = useWindowWidth(); const user = useSelector(({ chrome: { user } }: ReduxState) => user!); const unreadNotifications = useSelector(({ chrome: { notifications } }: ReduxState) => notifications.data.some((item) => !item.read)); @@ -130,6 +129,10 @@ const Tools = () => { } }, [user]); + const supportOptionsUrl = () => { + return isITLessEnv ? 'https://redhatgov.servicenowservices.com/css' : 'https://access.redhat.com/support'; + }; + /* list out the items for the about menu */ const aboutMenuDropdownItems = [ { @@ -150,7 +153,7 @@ const Tools = () => { }, { title: intl.formatMessage(messages.supportOptions), - url: isITLessEnv ? 'https://redhatgov.servicenowservices.com/css' : 'https://access.redhat.com/support', + onClick: () => (window.location.href = supportOptionsUrl()), }, { title: intl.formatMessage(messages.insightsRhelDocumentation), @@ -261,7 +264,7 @@ const Tools = () => { )} - {isInternal && ( + {isInternal && !ITLess() && ( diff --git a/src/components/Header/UserToggle.tsx b/src/components/Header/UserToggle.tsx index b04a655c0..6848b60a0 100644 --- a/src/components/Header/UserToggle.tsx +++ b/src/components/Header/UserToggle.tsx @@ -1,22 +1,23 @@ +import './UserToggle.scss'; + +import { Dropdown, DropdownItem, DropdownList } from '@patternfly/react-core/dist/dynamic/components/Dropdown'; +import { ITLess, ITLessCognito, getEnv, isProd as isProdEnv } from '../../utils/common'; import React, { useRef, useState } from 'react'; + +import ChromeLink from '../ChromeLink/ChromeLink'; import { Divider } from '@patternfly/react-core/dist/dynamic/components/Divider'; -import { Dropdown, DropdownItem, DropdownList } from '@patternfly/react-core/dist/dynamic/components/Dropdown'; +import { EllipsisVIcon } from '@patternfly/react-icons/dist/dynamic/icons/ellipsis-v-icon'; import { MenuToggle } from '@patternfly/react-core/dist/dynamic/components/MenuToggle'; -import { Tooltip } from '@patternfly/react-core/dist/dynamic/components/Tooltip'; import QuestionCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/question-circle-icon'; -import UserIcon from './UserIcon'; -import { useSelector } from 'react-redux'; -import { ITLess, ITLessCognito, getEnv, isProd as isProdEnv } from '../../utils/common'; -import ChromeLink from '../ChromeLink/ChromeLink'; -import { useIntl } from 'react-intl'; -import messages from '../../locales/Messages'; import { ReduxState } from '../../redux/store'; -import { logout } from '../../jwt/jwt'; -import { cogLogout } from '../../cognito/auth'; -import { EllipsisVIcon } from '@patternfly/react-icons/dist/dynamic/icons/ellipsis-v-icon'; +import { Tooltip } from '@patternfly/react-core/dist/dynamic/components/Tooltip'; +import UserIcon from './UserIcon'; import classNames from 'classnames'; - -import './UserToggle.scss'; +import { cogLogout } from '../../cognito/auth'; +import { logout } from '../../jwt/jwt'; +import messages from '../../locales/Messages'; +import { useIntl } from 'react-intl'; +import { useSelector } from 'react-redux'; const buildItems = (username = '', isOrgAdmin?: boolean, accountNumber?: string, isInternal?: boolean, extraItems: React.ReactNode[] = []) => { const env = getEnv(); @@ -92,9 +93,14 @@ const buildItems = (username = '', isOrgAdmin?: boolean, accountNumber?: string, , {isInternal && isProd && ( - - {intl.formatMessage(messages.internal)} - + ( + + {intl.formatMessage(messages.internal)} + + )} + /> )} , (ITLessCognito() ? cogLogout() : logout(true))}> diff --git a/src/components/RootApp/ScalprumRoot.tsx b/src/components/RootApp/ScalprumRoot.tsx index f5fb7aa80..931ba5789 100644 --- a/src/components/RootApp/ScalprumRoot.tsx +++ b/src/components/RootApp/ScalprumRoot.tsx @@ -32,6 +32,8 @@ import { ITLess, isBeta } from '../../utils/common'; import InternalChromeContext from '../../utils/internalChromeContext'; import useChromeServiceEvents from '../../hooks/useChromeServiceEvents'; import { populateNotifications } from '../../redux/actions'; +import useTrackPendoUsage from '../../hooks/useTrackPendoUsage'; +import useDisablePendoOnLanding from '../../hooks/useDisablePendoOnLanding'; const ProductSelection = lazy(() => import('../Stratosphere/ProductSelection')); @@ -59,6 +61,10 @@ const ScalprumRoot = memo( // initialize WS event handling useChromeServiceEvents(); + // track pendo usage + useTrackPendoUsage(); + // disable guides on landing page + useDisablePendoOnLanding(); async function getNotifications() { try { diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx index b547decd9..d8649b3ad 100644 --- a/src/components/Routes/Routes.tsx +++ b/src/components/Routes/Routes.tsx @@ -5,7 +5,7 @@ import ChromeRoute from '../ChromeRoute'; import NotFoundRoute from '../NotFoundRoute'; import LoadingFallback from '../../utils/loading-fallback'; import { ReduxState } from '../../redux/store'; -import { usePreviewFlag } from '../../utils/usePreviewFlag'; +import { useFlag } from '@unleash/proxy-client-react'; const INTEGRATION_SOURCES = 'platform.sources.integrations'; @@ -23,7 +23,7 @@ const redirects = [ { path: '/settings', to: '/settings/integrations', - previewFlag: { + featureFlag: { value: true, name: INTEGRATION_SOURCES, }, @@ -31,7 +31,7 @@ const redirects = [ { path: '/settings', to: '/settings/sources', - previewFlag: { + featureFlag: { value: false, name: INTEGRATION_SOURCES, }, @@ -67,8 +67,8 @@ export type RoutesProps = { }; const ChromeRoutes = ({ routesProps }: RoutesProps) => { - const enableIntegrations = usePreviewFlag(INTEGRATION_SOURCES); - const previewFlags = useMemo>(() => ({ INTEGRATION_SOURCES: enableIntegrations }), [enableIntegrations]); + const enableIntegrations = useFlag(INTEGRATION_SOURCES); + const featureFlags = useMemo>(() => ({ INTEGRATION_SOURCES: enableIntegrations }), [enableIntegrations]); const moduleRoutes = useSelector(({ chrome: { moduleRoutes } }: ReduxState) => moduleRoutes); const showBundleCatalog = localStorage.getItem('chrome:experimental:quickstarts') === 'true'; @@ -84,10 +84,10 @@ const ChromeRoutes = ({ routesProps }: RoutesProps) => { } /> )} - {redirects.map(({ path, to, previewFlag }) => { - if (previewFlag) { - const found = Object.keys(previewFlags).find((item) => item === previewFlag.name); - if (previewFlags[found as string] !== previewFlag.value) { + {redirects.map(({ path, to, featureFlag }) => { + if (featureFlag) { + const found = Object.keys(featureFlags).find((item) => item === featureFlag.name); + if (featureFlags[found as string] !== featureFlag.value) { return null; } } diff --git a/src/components/Search/SearchDescription.tsx b/src/components/Search/SearchDescription.tsx index d6d5a6e63..a530e30eb 100644 --- a/src/components/Search/SearchDescription.tsx +++ b/src/components/Search/SearchDescription.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Text, TextContent } from '@patternfly/react-core/dist/dynamic/components/Text'; -import parseHighlights from './parseHighlight'; import './SearchDescription.scss'; +import parseHighlights from './parseHighlight'; const SearchDescription = ({ description, highlight = [] }: { highlight?: string[]; description: string }) => { const parsedDescription = parseHighlights(description, highlight); diff --git a/src/components/Search/SearchGroup.tsx b/src/components/Search/SearchGroup.tsx deleted file mode 100644 index d6f646bc4..000000000 --- a/src/components/Search/SearchGroup.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { MenuGroup, MenuItem } from '@patternfly/react-core/dist/dynamic/components/Menu'; -import React from 'react'; -import ChromeLink from '../ChromeLink'; -import SearchDescription from './SearchDescription'; -import SearchTitle from './SearchTitle'; -import { HighlightingResponseType, SearchResultItem } from './SearchTypes'; - -const SearchGroup = ({ items, highlighting }: { items: SearchResultItem[]; highlighting: HighlightingResponseType }) => { - return items.length > 0 ? ( - - {items.map(({ id, allTitle, bundle_title, abstract, relative_uri }) => ( - } - description={} - key={id} - > - - - ))} - - ) : null; -}; - -export default SearchGroup; diff --git a/src/components/Search/SearchInput.scss b/src/components/Search/SearchInput.scss index 077ec00fe..c57481b62 100644 --- a/src/components/Search/SearchInput.scss +++ b/src/components/Search/SearchInput.scss @@ -37,6 +37,9 @@ display: none; } } + small { + display: inline-block; + } } &__empty-state { .pf-v5-c-empty-state__icon { diff --git a/src/components/Search/SearchInput.tsx b/src/components/Search/SearchInput.tsx index 7c0d3d982..9a826ba8e 100644 --- a/src/components/Search/SearchInput.tsx +++ b/src/components/Search/SearchInput.tsx @@ -1,19 +1,23 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Bullseye } from '@patternfly/react-core/dist/dynamic/layouts/Bullseye'; -import { Menu, MenuContent, MenuGroup, MenuList } from '@patternfly/react-core/dist/dynamic/components/Menu'; +import { Menu, MenuContent, MenuGroup, MenuItem, MenuList } from '@patternfly/react-core/dist/dynamic/components/Menu'; import { SearchInput as PFSearchInput, SearchInputProps } from '@patternfly/react-core/dist/dynamic/components/SearchInput'; import { Spinner } from '@patternfly/react-core/dist/dynamic/components/Spinner'; import { Popper } from '@patternfly/react-core/dist/dynamic/helpers/Popper/Popper'; import debounce from 'lodash/debounce'; +import uniq from 'lodash/uniq'; +import uniqWith from 'lodash/uniqWith'; import './SearchInput.scss'; -import SearchGroup from './SearchGroup'; -import { HighlightingResponseType, SearchResponseType, SearchResultItem } from './SearchTypes'; +import { AUTOSUGGEST_TERM_DELIMITER, SearchAutoSuggestionResponseType, SearchAutoSuggestionResultItem, SearchResponseType } from './SearchTypes'; import EmptySearchState from './EmptySearchState'; import { isProd } from '../../utils/common'; import { useSegment } from '../../analytics/useSegment'; import useWindowWidth from '../../hooks/useWindowWidth'; +import ChromeLink from '../ChromeLink'; +import SearchTitle from './SearchTitle'; +import SearchDescription from './SearchDescription'; export type SearchInputprops = { isExpanded?: boolean; @@ -21,7 +25,7 @@ export type SearchInputprops = { const IS_PROD = isProd(); const REPLACE_TAG = 'REPLACE_TAG'; -const FUZZY_RANGE_TAG = 'FUZZY_RANGE_TAG'; +const REPLACE_COUNT_TAG = 'REPLACE_COUNT_TAG'; /** * The ?q is the search term. * ------ @@ -36,25 +40,25 @@ const FUZZY_RANGE_TAG = 'FUZZY_RANGE_TAG'; */ const BASE_SEARCH = new URLSearchParams(); -BASE_SEARCH.append( - 'q', - `${REPLACE_TAG} OR *${REPLACE_TAG}~${FUZZY_RANGE_TAG} OR ${REPLACE_TAG}*~${FUZZY_RANGE_TAG} OR ${REPLACE_TAG}~${FUZZY_RANGE_TAG}` -); // add query replacement tag and enable fuzzy search with ~ and wildcards +BASE_SEARCH.append('q', `alt_titles:${REPLACE_TAG}`); // add query replacement tag and enable fuzzy search with ~ and wildcards BASE_SEARCH.append('fq', 'documentKind:ModuleDefinition'); // search for ModuleDefinition documents -BASE_SEARCH.append('rows', '10'); // request 10 results -BASE_SEARCH.append('hl', 'true'); // enable highlight -BASE_SEARCH.append('hl.method', 'original'); // choose highlight method -BASE_SEARCH.append('hl.fl', 'abstract'); // highlight description -BASE_SEARCH.append('hl.fl', 'allTitle'); // highlight title -BASE_SEARCH.append('hl.fl', 'bundle_title'); // highlight bundle title -BASE_SEARCH.append('hl.fl', 'bundle'); // highlight bundle id -BASE_SEARCH.append('hl.snippets', '3'); // enable up to 3 highlights in a single string -BASE_SEARCH.append('hl.mergeContiguous', 'true'); // Use only one highlight attribute to simply tag replacement. +BASE_SEARCH.append('rows', `${REPLACE_COUNT_TAG}`); // request 10 results const BASE_URL = new URL(`https://access.${IS_PROD ? '' : 'stage.'}redhat.com/hydra/rest/search/platform/console/`); // search API stopped receiving encoded search string BASE_URL.search = decodeURIComponent(BASE_SEARCH.toString()); -const SEARCH_QUERY = BASE_URL.toString(); + +const SUGGEST_SEARCH = new URLSearchParams(); +SUGGEST_SEARCH.append('redhat_client', 'console'); // required client id +SUGGEST_SEARCH.append('q', REPLACE_TAG); // add query replacement tag and enable fuzzy search with ~ and wildcards +SUGGEST_SEARCH.append('suggest.count', '10'); // request 10 results +SUGGEST_SEARCH.append('suggest.dictionary', 'improvedInfixSuggester'); // console new suggest dictionary +SUGGEST_SEARCH.append('suggest.dictionary', 'default'); + +const SUGGEST_URL = new URL(`https://access.${IS_PROD ? '' : 'stage.'}redhat.com/hydra/proxy/gss-diag/rs/search/autosuggest`); +// search API stopped receiving encoded search string +SUGGEST_URL.search = decodeURIComponent(SUGGEST_SEARCH.toString()); +const SUGGEST_SEARCH_QUERY = SUGGEST_URL.toString(); const getMaxMenuHeight = (menuElement?: HTMLDivElement | null) => { if (!menuElement) { @@ -67,29 +71,38 @@ const getMaxMenuHeight = (menuElement?: HTMLDivElement | null) => { return bodyHeight - menuTopOffset - 4; }; -type SearchCategories = { - highLevel: SearchResultItem[]; - midLevel: SearchResultItem[]; - lowLevel: SearchResultItem[]; -}; - -const initialSearchState: SearchResponseType = { - docs: [], - maxScore: 0, - numFound: 0, - start: 0, +type SearchItem = { + title: string; + bundleTitle: string; + description: string; + pathname: string; }; type SearchInputListener = { onStateChange: (isOpen: boolean) => void; }; +function parseSuggestions(suggestions: SearchAutoSuggestionResultItem[] = []) { + return suggestions.map((suggestion) => { + const [allTitle, bundleTitle, abstract] = suggestion.term.split(AUTOSUGGEST_TERM_DELIMITER); + const url = new URL(suggestion.payload); + return { + item: { + title: allTitle, + bundleTitle, + description: abstract, + pathname: url.pathname, + }, + allTitle, + }; + }); +} + const SearchInput = ({ onStateChange }: SearchInputListener) => { const [isOpen, setIsOpen] = useState(false); const [searchValue, setSearchValue] = useState(''); const [isFetching, setIsFetching] = useState(false); - const [searchResults, setSearchResults] = useState(initialSearchState); - const [highlighting, setHighlighting] = useState({}); + const [searchItems, setSearchItems] = useState([]); const { ready, analytics } = useSegment(); const blockCloseEvent = useRef(false); @@ -99,38 +112,7 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { const containerRef = useRef(null); const { md } = useWindowWidth(); - // sort result items based on matched field and its priority - const resultCategories = useMemo( - () => - searchResults.docs.reduce( - (acc, curr) => { - if (highlighting[curr.id]?.allTitle) { - return { - ...acc, - highLevel: [...acc.highLevel, curr], - }; - } - - if (highlighting[curr.id]?.abstract) { - return { - ...acc, - midLevel: [...acc.midLevel, curr], - }; - } - - return { - ...acc, - lowLevel: [...acc.lowLevel, curr], - }; - }, - { - highLevel: [], - midLevel: [], - lowLevel: [], - } - ), - [searchResults.docs, highlighting] - ); + const resultCount = searchItems.length; const handleMenuKeys = (event: KeyboardEvent) => { if (!isOpen) { @@ -155,7 +137,7 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { }; const onInputClick: SearchInputProps['onClick'] = () => { - if (!isOpen && searchResults.numFound > 0) { + if (!isOpen && resultCount > 0) { if (!md && isExpanded && searchValue !== '') { setIsOpen(true); onStateChange(true); @@ -213,28 +195,46 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { }; }, [isOpen, menuRef]); - const handleFetch = (value = '') => { - return fetch(SEARCH_QUERY.replaceAll(REPLACE_TAG, value).replaceAll(FUZZY_RANGE_TAG, value.length > 3 ? '2' : '1')) - .then((r) => r.json()) - .then(({ response, highlighting }: { highlighting: HighlightingResponseType; response: SearchResponseType }) => { - if (isMounted.current) { - setSearchResults(response); - setHighlighting(highlighting); - // make sure to calculate resize when switching from loading to sucess state - handleWindowResize(); - } - if (ready && analytics) { - analytics.track('chrome.search-query', { query: value }); - } - }) - .finally(() => { - isMounted.current && setIsFetching(false); - }); + const handleFetch = async (value = '') => { + const response = (await fetch(SUGGEST_SEARCH_QUERY.replaceAll(REPLACE_TAG, value)).then((r) => r.json())) as SearchAutoSuggestionResponseType; + + // parse default suggester + // parse improved suggester + let items: { item: SearchItem; allTitle: string }[] = []; + items = items + .concat( + parseSuggestions(response?.suggest?.default[value]?.suggestions), + parseSuggestions(response?.suggest?.improvedInfixSuggester[value]?.suggestions) + ) + .slice(0, 10); + const suggests = uniq(items.map(({ allTitle }) => allTitle.replace(/(|<\/b>)/gm, '').trim())); + let searchItems = items.map(({ item }) => item); + if (items.length < 10) { + const altTitleResults = (await fetch( + BASE_URL.toString() + .replaceAll(REPLACE_TAG, `(${suggests.length > 0 ? suggests.join(' OR ') + ' OR ' : ''}${value})`) + .replaceAll(REPLACE_COUNT_TAG, '10') + ).then((r) => r.json())) as { response: SearchResponseType }; + searchItems = searchItems.concat( + altTitleResults.response.docs.map((doc) => ({ + pathname: doc.relative_uri, + bundleTitle: doc.bundle_title[0], + title: doc.allTitle, + description: doc.abstract, + })) + ); + } + searchItems = uniqWith(searchItems, (a, b) => a.title.replace(/(|<\/b>)/gm, '').trim() === b.title.replace(/(|<\/b>)/gm, '').trim()); + setSearchItems(searchItems.slice(0, 10)); + isMounted.current && setIsFetching(false); + if (ready && analytics) { + analytics.track('chrome.search-query', { query: value }); + } }; const debouncedFetch = useCallback(debounce(handleFetch, 500), []); - const handleChange = (_e: any, value: string) => { + const handleChange: SearchInputProps['onChange'] = (_e, value) => { setSearchValue(value); setIsFetching(true); debouncedFetch(value); @@ -262,7 +262,7 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { onChange={handleChange} onClear={(ev) => { setSearchValue(''); - setSearchResults(initialSearchState); + setSearchItems([]); ev.stopPropagation(); setIsOpen(false); onStateChange(false); @@ -280,7 +280,6 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { className={isExpanded ? 'pf-u-flex-grow-1' : 'chr-c-search__collapsed'} /> ); - const menu = ( @@ -291,14 +290,17 @@ const SearchInput = ({ onStateChange }: SearchInputListener) => { ) : ( <> - 0 ? `Top ${searchResults.docs.length} results` : undefined}> - - - + 0 ? `Top ${searchItems.length} results` : undefined}> + {searchItems.map((item, index) => ( + }> + + + + ))} )} - {searchResults.numFound === 0 && !isFetching && } + {searchItems.length === 0 && !isFetching && } diff --git a/src/components/Search/SearchTitle.tsx b/src/components/Search/SearchTitle.tsx index 729ea9684..445e42f81 100644 --- a/src/components/Search/SearchTitle.tsx +++ b/src/components/Search/SearchTitle.tsx @@ -2,13 +2,16 @@ import React from 'react'; import { Text, TextContent } from '@patternfly/react-core/dist/dynamic/components/Text'; const SearchTitle = ({ title, bundleTitle }: { title: string; bundleTitle: string }) => { + const showBundleTitle = bundleTitle.replace(/\s/g, '').length > 0; return ( - - {title} - | - {bundleTitle} - + + {showBundleTitle && ( + + | + + )} + {showBundleTitle && } ); }; diff --git a/src/components/Search/SearchTypes.ts b/src/components/Search/SearchTypes.ts index 82f7738db..7b44d7b20 100644 --- a/src/components/Search/SearchTypes.ts +++ b/src/components/Search/SearchTypes.ts @@ -9,6 +9,12 @@ export type SearchResultItem = { view_uri: string; }; +export type SearchAutoSuggestionResultItem = { + term: string; + weight: string; + payload: string; +}; + export type SearchResponseType = { docs: SearchResultItem[]; start: number; @@ -16,8 +22,21 @@ export type SearchResponseType = { maxScore: number; }; -export type SearchHighlight = { allTitle?: string[]; abstract?: string[]; bundle_title?: string[]; bundle?: string[] }; - -export type HighlightingResponseType = { - [recordId: string]: SearchHighlight; +export type SearchAutoSuggestionResponseType = { + suggest: { + improvedInfixSuggester: { + [recordId: string]: { + numFound: number; + suggestions: SearchAutoSuggestionResultItem[]; + }; + }; + default: { + [recordId: string]: { + numFound: number; + suggestions: SearchAutoSuggestionResultItem[]; + }; + }; + }; }; + +export const AUTOSUGGEST_TERM_DELIMITER = '|'; diff --git a/src/hooks/useAllServices.ts b/src/hooks/useAllServices.ts index f8266df6c..f75f82841 100644 --- a/src/hooks/useAllServices.ts +++ b/src/hooks/useAllServices.ts @@ -107,6 +107,9 @@ const filterAllServicesLinks = (links: (AllServicesLink | AllServicesGroup)[], f return links.reduce<(AllServicesLink | AllServicesGroup)[]>((acc, link) => { // groups have links nested, we have to filter them as well if (isAllServicesGroup(link)) { + if (matchStrings(link.title, filterValue)) { + return [...acc, link]; + } const groupLinks = filterAllServicesLinks(link.links, filterValue); // replace group links with filtered results const newGroup: AllServicesGroup = { diff --git a/src/hooks/useBreadcrumbsLinks.ts b/src/hooks/useBreadcrumbsLinks.ts index f75eb6437..4150f3b7b 100644 --- a/src/hooks/useBreadcrumbsLinks.ts +++ b/src/hooks/useBreadcrumbsLinks.ts @@ -24,7 +24,7 @@ const useBreadcrumbsLinks = () => { href: `/${bundleId}`, }, ]; - const activeNavSegment = navigation[bundleId]; + const activeNavSegment = navigation?.[bundleId]; if (activeNavSegment && isNavItems(activeNavSegment)) { const activeNavigation = extractNavItemGroups(activeNavSegment); const { activeItem, navItems } = findNavLeafPath(activeNavigation); diff --git a/src/hooks/useChromeServiceEvents.ts b/src/hooks/useChromeServiceEvents.ts index 41709b6f8..2833acaaf 100644 --- a/src/hooks/useChromeServiceEvents.ts +++ b/src/hooks/useChromeServiceEvents.ts @@ -6,7 +6,7 @@ import { UPDATE_NOTIFICATIONS } from '../redux/action-types'; import { getEncodedToken, setCookie } from '../jwt/jwt'; import { NotificationsPayload } from '../redux/store'; -const NOTIFICATION_DRAWER = 'notifications.drawer'; +const NOTIFICATION_DRAWER = 'com.redhat.console.notifications.drawer'; const SAMPLE_EVENT = 'sample.type'; const ALL_TYPES = [NOTIFICATION_DRAWER, SAMPLE_EVENT] as const; diff --git a/src/hooks/useDisablePendoOnLanding.ts b/src/hooks/useDisablePendoOnLanding.ts new file mode 100644 index 000000000..d47a00e7b --- /dev/null +++ b/src/hooks/useDisablePendoOnLanding.ts @@ -0,0 +1,74 @@ +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { ReduxState } from '../redux/store'; +import { isProd } from '../utils/common'; +import { isITLessEnv } from '../utils/consts'; + +// interval timing is short because we want to catch the bubble before ASAP so it does not cover the VA button +const RETRY_ATTEMPS = 500; +const RETRY_INTERVAL = 50; + +function retry(fn: () => void, retriesLeft = 10, interval = 100) { + try { + return fn(); + } catch (error) { + const newRetry = retriesLeft - 1; + if (newRetry > 0) { + setTimeout(() => { + retry(fn, newRetry, interval); + }, interval); + } else { + console.error('Pendo retries exhausted: ', error); + } + } +} + +const useDisablePendoOnLanding = () => { + const activeModule = useSelector((state: ReduxState) => state.chrome.activeModule); + + const toggleGuides = () => { + // push the call to the end of the event loop to make sure the pendo script is loaded and initialized + setTimeout(() => { + if (window.pendo && activeModule === 'landing') { + // pendo functions might not be ready for what ever reason, we will have to retry a few times to give it a shot + retry(() => { + window.pendo?.setGuidesDisabled(true); + window.pendo?.stopGuides(); + }); + } else if (window.pendo) { + retry(() => { + window.pendo?.setGuidesDisabled(false); + window.pendo?.startGuides(); + }); + } + }); + }; + + useEffect(() => { + let attempt = 0; + let interval: NodeJS.Timeout | undefined = undefined; + if (window.pendo) { + toggleGuides(); + } else { + interval = setInterval(() => { + if (attempt < RETRY_ATTEMPS) { + attempt += 1; + if (window.pendo) { + clearInterval(interval); + toggleGuides(); + } + } else { + clearInterval(interval); + } + }, RETRY_INTERVAL); + } + + return () => { + if (interval && !isProd() && !isITLessEnv) { + clearInterval(interval); + } + }; + }, [activeModule]); +}; + +export default useDisablePendoOnLanding; diff --git a/src/hooks/useTrackPendoUsage.ts b/src/hooks/useTrackPendoUsage.ts new file mode 100644 index 000000000..1c0c2bea2 --- /dev/null +++ b/src/hooks/useTrackPendoUsage.ts @@ -0,0 +1,62 @@ +import { useSelector } from 'react-redux'; +import { ReduxState } from '../redux/store'; +import { useCallback, useEffect, useRef } from 'react'; +import { useSegment } from '../analytics/useSegment'; + +const badgeQuery = 'div[id^="_pendo-badge_"]'; +const RETRY_ATTEMPS = 10; +const RETRY_INTERVAL = 2000; +const SEGMENT_EVENT_NAME = 'pendo-badge-clicked'; + +const useTrackPendoUsage = () => { + const activeModule = useSelector((state) => state.chrome.activeModule); + const mutableData = useRef({ activeModule }); + const { analytics } = useSegment(); + const setupEventTracking = useCallback(() => { + analytics?.track(SEGMENT_EVENT_NAME, { + application: mutableData.current.activeModule, + }); + }, []); + + useEffect(() => { + let interval: NodeJS.Timeout | undefined = undefined; + let pendoBadgeElement: HTMLDivElement | null = document.querySelector(badgeQuery); + try { + // this feature is not critical, if any of the following fails, we just ignore it + mutableData.current.activeModule = activeModule; + let attempt = 0; + if (!pendoBadgeElement) { + // pendo badge was not loaded yet + // try a few times to find it, then give up + interval = setInterval(() => { + if (attempt < RETRY_ATTEMPS) { + attempt += 1; + pendoBadgeElement = document.querySelector(badgeQuery); + if (pendoBadgeElement) { + clearInterval(interval); + pendoBadgeElement.addEventListener('click', setupEventTracking); + } + } else { + clearInterval(interval); + } + }, RETRY_INTERVAL); + } else { + pendoBadgeElement.addEventListener('click', setupEventTracking); + } + } catch (error) { + console.error('Failed to setup pendo badge event tracking', error); + } + return () => { + if (interval) { + clearInterval(interval); + } + + if (pendoBadgeElement) { + pendoBadgeElement.removeEventListener('click', setupEventTracking); + pendoBadgeElement = null; + } + }; + }, [activeModule]); +}; + +export default useTrackPendoUsage; diff --git a/src/jwt/jwt.ts b/src/jwt/jwt.ts index 2501a2b43..4417b660f 100644 --- a/src/jwt/jwt.ts +++ b/src/jwt/jwt.ts @@ -193,6 +193,7 @@ export const init = (options: JWTInitOptions, configSsoUrl?: string) => { } return getTokenWithAuthorizationCode().then((res) => { priv.setToken(res); + initSuccess(); token = res; return token; }); diff --git a/src/layouts/SatelliteToken.tsx b/src/layouts/SatelliteToken.tsx index 1f50c20fc..b7e770abe 100644 --- a/src/layouts/SatelliteToken.tsx +++ b/src/layouts/SatelliteToken.tsx @@ -8,6 +8,7 @@ import { List, ListComponent, ListItem, OrderType } from '@patternfly/react-core import { Masthead } from '@patternfly/react-core/dist/dynamic/components/Masthead'; import { Page, PageSection } from '@patternfly/react-core/dist/dynamic/components/Page'; import SatelliteTable from '../components/Satellite/SatelliteTable'; +import { getEnv } from '../utils/common'; const SatelliteToken: React.FC = () => { const [token, setToken] = useState(''); @@ -24,6 +25,8 @@ const SatelliteToken: React.FC = () => { setError(err); }); }; + const itlessProd = getEnv() === 'frh'; + const satelliteUrl = itlessProd ? 'https://mtls.console.openshiftusgov.com' : 'https://mtls.console.stage.openshiftusgov.com'; useEffect(() => { if (token.length < 1 && error === null) { generateToken(); @@ -70,7 +73,7 @@ const SatelliteToken: React.FC = () => { Step 2. You will prompted to enter the token from Step 1.`} - {`SATELLITE_RH_CLOUD_URL=https://mtls.console.stage.openshiftusgov.com org_id= foreman-rake rh_cloud:hybridcloud_register`} + {`SATELLITE_RH_CLOUD_URL=${satelliteUrl} org_id= foreman-rake rh_cloud:hybridcloud_register`} diff --git a/src/utils/common.ts b/src/utils/common.ts index 690667db2..8334a0d1b 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -34,12 +34,12 @@ export const DEFAULT_SSO_ROUTES = { }, frhStage: { url: ['console.stage.openshiftusgov.com'], - sso: 'https://ocm-ra-stage-domain.auth-fips.us-gov-west-1.amazoncognito.com/login', + sso: 'https://sso.stage.openshiftusgov.com', portal: 'https://console.stage.openshiftusgov.com', }, frh: { url: ['console.openshiftusgov.com'], - sso: 'https://ocm-ra-stage-domain.auth-fips.us-gov-west-1.amazoncognito.com/login', + sso: 'https://ocm-ra-prod-domain.auth-fips.us-gov-west-1.amazoncognito.com/login', portal: 'https://console.openshiftusgov.com', }, ephem: { @@ -215,11 +215,11 @@ export function ITLess() { } export function ITLessCognito() { - return getEnv() === 'frhStage' || getEnv() === 'frh'; + return getEnv() === 'frh'; } export function ITLessKeycloak() { - return getEnv() === 'ephem' || getEnv() === 'int' || getEnv() === 'scr'; + return getEnv() === 'ephem' || getEnv() === 'int' || getEnv() === 'scr' || getEnv() === 'frhStage'; } export function updateDocumentTitle(title?: string, noSuffix = false) {