From ab89c3aebcc6b20ba2e50439f265dbd72a791c0b Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Thu, 12 Feb 2026 02:41:53 -0500 Subject: [PATCH 1/2] Graphical View of Applications (#8342, 8349) Signed-off-by: Keith Chong --- locales/en/plugin__gitops-plugin.json | 22 +- locales/ja/plugin__gitops-plugin.json | 22 +- locales/ko/plugin__gitops-plugin.json | 22 +- locales/zh/plugin__gitops-plugin.json | 22 +- package.json | 30 +- .../application/ApplicationDetailsTab.tsx | 53 +- .../application/ApplicationResourcesTab.tsx | 78 +- .../graph/ApplicationGraphView.scss | 29 + .../graph/ApplicationGraphView.tsx | 479 ++++++ .../application/graph/graph-utils.tsx | 507 ++++++ .../graph/hooks/GraphResourceMenuItems.tsx | 61 + .../graph/icons/resource-colours.tsx | 72 + .../graph/icons/resource-icons.tsx | 191 +++ .../graph/nodes/ApplicationNode.tsx | 197 +++ .../graph/nodes/ResourceGroupNode.tsx | 209 +++ .../application/graph/nodes/ResourceNode.tsx | 73 + .../components/graph/SvgTextWithOverflow.tsx | 36 + .../hooks/useApplicationActionsProvider.tsx | 23 +- .../hooks/useResourceActionsProvider.tsx | 4 +- src/gitops/models/ApplicationModel.ts | 158 +- src/gitops/utils/components/Icons/Icons.tsx | 12 +- .../utils/hooks/useGitOpsTranslation.ts | 3 +- src/images/README.md | 9 + src/images/resources/c-role-1.svg | 1 + src/images/resources/c-role.svg | 1 + src/images/resources/cm.svg | 1 + src/images/resources/crb.svg | 1 + src/images/resources/crd.svg | 1 + src/images/resources/cronjob.svg | 1 + src/images/resources/deploy.svg | 1 + src/images/resources/ds.svg | 1 + src/images/resources/ep.svg | 1 + src/images/resources/git.svg | 10 + src/images/resources/group.svg | 1 + src/images/resources/helm.svg | 4 + src/images/resources/hpa.svg | 1 + src/images/resources/ing.svg | 1 + src/images/resources/job.svg | 1 + src/images/resources/limits.svg | 1 + src/images/resources/netpol.svg | 1 + src/images/resources/ns.svg | 1 + src/images/resources/oci.svg | 22 + src/images/resources/pod.svg | 1 + src/images/resources/psp.svg | 1 + src/images/resources/pv.svg | 1 + src/images/resources/pvc.svg | 1 + src/images/resources/quota.svg | 1 + src/images/resources/rb.svg | 1 + src/images/resources/role.svg | 1 + src/images/resources/rs.svg | 1 + src/images/resources/sa.svg | 1 + src/images/resources/sc.svg | 1 + src/images/resources/secret.svg | 1 + src/images/resources/sts.svg | 1 + src/images/resources/svc.svg | 1 + src/images/resources/user.svg | 1 + src/images/resources/vol.svg | 1 + src/index.d.ts | 5 +- webpack.config.ts | 15 +- yarn.lock | 1476 ++++++++++++++++- 60 files changed, 3683 insertions(+), 192 deletions(-) create mode 100644 src/gitops/components/application/graph/ApplicationGraphView.scss create mode 100644 src/gitops/components/application/graph/ApplicationGraphView.tsx create mode 100644 src/gitops/components/application/graph/graph-utils.tsx create mode 100644 src/gitops/components/application/graph/hooks/GraphResourceMenuItems.tsx create mode 100644 src/gitops/components/application/graph/icons/resource-colours.tsx create mode 100644 src/gitops/components/application/graph/icons/resource-icons.tsx create mode 100644 src/gitops/components/application/graph/nodes/ApplicationNode.tsx create mode 100644 src/gitops/components/application/graph/nodes/ResourceGroupNode.tsx create mode 100644 src/gitops/components/application/graph/nodes/ResourceNode.tsx create mode 100644 src/gitops/components/graph/SvgTextWithOverflow.tsx create mode 100644 src/images/README.md create mode 100644 src/images/resources/c-role-1.svg create mode 100644 src/images/resources/c-role.svg create mode 100644 src/images/resources/cm.svg create mode 100644 src/images/resources/crb.svg create mode 100644 src/images/resources/crd.svg create mode 100644 src/images/resources/cronjob.svg create mode 100644 src/images/resources/deploy.svg create mode 100644 src/images/resources/ds.svg create mode 100644 src/images/resources/ep.svg create mode 100644 src/images/resources/git.svg create mode 100644 src/images/resources/group.svg create mode 100644 src/images/resources/helm.svg create mode 100644 src/images/resources/hpa.svg create mode 100644 src/images/resources/ing.svg create mode 100644 src/images/resources/job.svg create mode 100644 src/images/resources/limits.svg create mode 100644 src/images/resources/netpol.svg create mode 100644 src/images/resources/ns.svg create mode 100644 src/images/resources/oci.svg create mode 100644 src/images/resources/pod.svg create mode 100644 src/images/resources/psp.svg create mode 100644 src/images/resources/pv.svg create mode 100644 src/images/resources/pvc.svg create mode 100644 src/images/resources/quota.svg create mode 100644 src/images/resources/rb.svg create mode 100644 src/images/resources/role.svg create mode 100644 src/images/resources/rs.svg create mode 100644 src/images/resources/sa.svg create mode 100644 src/images/resources/sc.svg create mode 100644 src/images/resources/secret.svg create mode 100644 src/images/resources/sts.svg create mode 100644 src/images/resources/svc.svg create mode 100644 src/images/resources/user.svg create mode 100644 src/images/resources/vol.svg diff --git a/locales/en/plugin__gitops-plugin.json b/locales/en/plugin__gitops-plugin.json index bd7834787..97b6b8d61 100644 --- a/locales/en/plugin__gitops-plugin.json +++ b/locales/en/plugin__gitops-plugin.json @@ -80,6 +80,7 @@ "No resources": "No resources", "There are no resources associated with the application.": "There are no resources associated with the application.", "Application resources": "Application resources", + "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.": "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.", "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", @@ -109,6 +110,20 @@ "Resources Last Synced": "Resources Last Synced", "Status": "Status", "Hook": "Hook", + "View in Argo CD": "View in Argo CD", + "Edit labels": "Edit labels", + "Edit annotations": "Edit annotations", + "Edit {{x}}": "Edit {{x}}", + "Delete {{x}}": "Delete {{x}}", + "Edit Application": "Edit Application", + "Delete Application": "Delete Application", + "Show {{x}}": "Show {{x}}", + "Hide {{x}}": "Hide {{x}}", + "Group resources of the same kind into one node": "Group resources of the same kind into one node", + "Group Nodes": "Group Nodes", + "There is no health status for this resource": "There is no health status for this resource", + "Sync Unknown": "Sync Unknown", + "One or more resources are in Progressing state": "One or more resources are in Progressing state", "There is no history associated with the application.": "There is no history associated with the application.", "ID": "ID", "Deploy Started At": "Deploy Started At", @@ -133,8 +148,6 @@ "Allow": "Allow", "No destinations configured": "No destinations configured", "This AppProject does not have any destinations configured.": "This AppProject does not have any destinations configured.", - "Edit labels": "Edit labels", - "Edit annotations": "Edit annotations", "Edit AppProject": "Edit AppProject", "Delete": "Delete", "Allowed Sources": "Allowed Sources", @@ -239,8 +252,8 @@ "There are no pods associated with the rollout.": "There are no pods associated with the rollout.", "Edit Pod": "Edit Pod", "Promote": "Promote", - "Full Promote": "Full Promote", "Abort": "Abort", + "Full Promote": "Full Promote", "Retry": "Retry", "Restart": "Restart", "Edit Rollout": "Edit Rollout", @@ -302,7 +315,6 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ArgoCD ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", - "View in Argo CD": "View in Argo CD", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", @@ -316,8 +328,6 @@ "Stop": "Stop", "Refresh": "Refresh", "Refresh (Hard)": "Refresh (Hard)", - "Edit Application": "Edit Application", - "Delete Application": "Delete Application", "Edit ApplicationSet": "Edit ApplicationSet", "Delete ApplicationSet": "Delete ApplicationSet", "Actions": "Actions", diff --git a/locales/ja/plugin__gitops-plugin.json b/locales/ja/plugin__gitops-plugin.json index 80a7fad24..cf337c2f4 100644 --- a/locales/ja/plugin__gitops-plugin.json +++ b/locales/ja/plugin__gitops-plugin.json @@ -80,6 +80,7 @@ "No resources": "No resources", "There are no resources associated with the application.": "There are no resources associated with the application.", "Application resources": "Application resources", + "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.": "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.", "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", @@ -109,6 +110,20 @@ "Resources Last Synced": "Resources Last Synced", "Status": "Status", "Hook": "Hook", + "View in Argo CD": "View in Argo CD", + "Edit labels": "Edit labels", + "Edit annotations": "Edit annotations", + "Edit {{x}}": "Edit {{x}}", + "Delete {{x}}": "Delete {{x}}", + "Edit Application": "Edit Application", + "Delete Application": "Delete Application", + "Show {{x}}": "Show {{x}}", + "Hide {{x}}": "Hide {{x}}", + "Group resources of the same kind into one node": "Group resources of the same kind into one node", + "Group Nodes": "Group Nodes", + "There is no health status for this resource": "There is no health status for this resource", + "Sync Unknown": "Sync Unknown", + "One or more resources are in Progressing state": "One or more resources are in Progressing state", "There is no history associated with the application.": "There is no history associated with the application.", "ID": "ID", "Deploy Started At": "Deploy Started At", @@ -133,8 +148,6 @@ "Allow": "Allow", "No destinations configured": "No destinations configured", "This AppProject does not have any destinations configured.": "This AppProject does not have any destinations configured.", - "Edit labels": "Edit labels", - "Edit annotations": "Edit annotations", "Edit AppProject": "Edit AppProject", "Delete": "Delete", "Allowed Sources": "Allowed Sources", @@ -239,8 +252,8 @@ "There are no pods associated with the rollout.": "There are no pods associated with the rollout.", "Edit Pod": "Edit Pod", "Promote": "Promote", - "Full Promote": "Full Promote", "Abort": "Abort", + "Full Promote": "Full Promote", "Retry": "Retry", "Restart": "Restart", "Edit Rollout": "Edit Rollout", @@ -302,7 +315,6 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", - "View in Argo CD": "View in Argo CD", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", @@ -316,8 +328,6 @@ "Stop": "Stop", "Refresh": "Refresh", "Refresh (Hard)": "Refresh (Hard)", - "Edit Application": "Edit Application", - "Delete Application": "Delete Application", "Edit ApplicationSet": "Edit ApplicationSet", "Delete ApplicationSet": "Delete ApplicationSet", "Actions": "Actions", diff --git a/locales/ko/plugin__gitops-plugin.json b/locales/ko/plugin__gitops-plugin.json index 7e7e65654..51453e7d0 100644 --- a/locales/ko/plugin__gitops-plugin.json +++ b/locales/ko/plugin__gitops-plugin.json @@ -80,6 +80,7 @@ "No resources": "No resources", "There are no resources associated with the application.": "There are no resources associated with the application.", "Application resources": "Application resources", + "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.": "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.", "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", @@ -109,6 +110,20 @@ "Resources Last Synced": "Resources Last Synced", "Status": "Status", "Hook": "Hook", + "View in Argo CD": "View in Argo CD", + "Edit labels": "Edit labels", + "Edit annotations": "Edit annotations", + "Edit {{x}}": "Edit {{x}}", + "Delete {{x}}": "Delete {{x}}", + "Edit Application": "Edit Application", + "Delete Application": "Delete Application", + "Show {{x}}": "Show {{x}}", + "Hide {{x}}": "Hide {{x}}", + "Group resources of the same kind into one node": "Group resources of the same kind into one node", + "Group Nodes": "Group Nodes", + "There is no health status for this resource": "There is no health status for this resource", + "Sync Unknown": "Sync Unknown", + "One or more resources are in Progressing state": "One or more resources are in Progressing state", "There is no history associated with the application.": "There is no history associated with the application.", "ID": "ID", "Deploy Started At": "Deploy Started At", @@ -133,8 +148,6 @@ "Allow": "Allow", "No destinations configured": "No destinations configured", "This AppProject does not have any destinations configured.": "This AppProject does not have any destinations configured.", - "Edit labels": "Edit labels", - "Edit annotations": "Edit annotations", "Edit AppProject": "Edit AppProject", "Delete": "Delete", "Allowed Sources": "Allowed Sources", @@ -239,8 +252,8 @@ "There are no pods associated with the rollout.": "There are no pods associated with the rollout.", "Edit Pod": "Edit Pod", "Promote": "Promote", - "Full Promote": "Full Promote", "Abort": "Abort", + "Full Promote": "Full Promote", "Retry": "Retry", "Restart": "Restart", "Edit Rollout": "Edit Rollout", @@ -302,7 +315,6 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", - "View in Argo CD": "View in Argo CD", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", @@ -316,8 +328,6 @@ "Stop": "Stop", "Refresh": "Refresh", "Refresh (Hard)": "Refresh (Hard)", - "Edit Application": "Edit Application", - "Delete Application": "Delete Application", "Edit ApplicationSet": "Edit ApplicationSet", "Delete ApplicationSet": "Delete ApplicationSet", "Actions": "Actions", diff --git a/locales/zh/plugin__gitops-plugin.json b/locales/zh/plugin__gitops-plugin.json index 59e8d782e..f9f95fefb 100644 --- a/locales/zh/plugin__gitops-plugin.json +++ b/locales/zh/plugin__gitops-plugin.json @@ -80,6 +80,7 @@ "No resources": "No resources", "There are no resources associated with the application.": "There are no resources associated with the application.", "Application resources": "Application resources", + "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.": "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.", "Name": "Name", "Namespace": "Namespace", "Sync Wave": "Sync Wave", @@ -109,6 +110,20 @@ "Resources Last Synced": "Resources Last Synced", "Status": "Status", "Hook": "Hook", + "View in Argo CD": "View in Argo CD", + "Edit labels": "Edit labels", + "Edit annotations": "Edit annotations", + "Edit {{x}}": "Edit {{x}}", + "Delete {{x}}": "Delete {{x}}", + "Edit Application": "Edit Application", + "Delete Application": "Delete Application", + "Show {{x}}": "Show {{x}}", + "Hide {{x}}": "Hide {{x}}", + "Group resources of the same kind into one node": "Group resources of the same kind into one node", + "Group Nodes": "Group Nodes", + "There is no health status for this resource": "There is no health status for this resource", + "Sync Unknown": "Sync Unknown", + "One or more resources are in Progressing state": "One or more resources are in Progressing state", "There is no history associated with the application.": "There is no history associated with the application.", "ID": "ID", "Deploy Started At": "Deploy Started At", @@ -133,8 +148,6 @@ "Allow": "Allow", "No destinations configured": "No destinations configured", "This AppProject does not have any destinations configured.": "This AppProject does not have any destinations configured.", - "Edit labels": "Edit labels", - "Edit annotations": "Edit annotations", "Edit AppProject": "Edit AppProject", "Delete": "Delete", "Allowed Sources": "Allowed Sources", @@ -239,8 +252,8 @@ "There are no pods associated with the rollout.": "There are no pods associated with the rollout.", "Edit Pod": "Edit Pod", "Promote": "Promote", - "Full Promote": "Full Promote", "Abort": "Abort", + "Full Promote": "Full Promote", "Retry": "Retry", "Restart": "Restart", "Edit Rollout": "Edit Rollout", @@ -302,7 +315,6 @@ "There was an error retrieving applicationsets. Check your connection and reload the page.": "There was an error retrieving applicationsets. Check your connection and reload the page.", "ApplicationSets": "ApplicationSets", "Create ApplicationSet": "Create ApplicationSet", - "View in Argo CD": "View in Argo CD", "Name must be unique within a namespace.": "Name must be unique within a namespace.", "Namespace defines the space within which each name must be unique.": "Namespace defines the space within which each name must be unique.", "Map of string keys and values that can be used to organize and categorize (scope and select) objects.": "Map of string keys and values that can be used to organize and categorize (scope and select) objects.", @@ -316,8 +328,6 @@ "Stop": "Stop", "Refresh": "Refresh", "Refresh (Hard)": "Refresh (Hard)", - "Edit Application": "Edit Application", - "Delete Application": "Delete Application", "Edit ApplicationSet": "Edit ApplicationSet", "Delete ApplicationSet": "Delete ApplicationSet", "Actions": "Actions", diff --git a/package.json b/package.json index d21c4e5a6..6aa7453d3 100644 --- a/package.json +++ b/package.json @@ -16,25 +16,28 @@ "lint": "eslint ./src --fix" }, "devDependencies": { + "@dagrejs/dagre": "^1.1.8", "@openshift-console/dynamic-plugin-sdk": "^4.19.0-prerelease.2", "@openshift-console/dynamic-plugin-sdk-internal": "^4.19.0-prerelease.2", "@openshift-console/dynamic-plugin-sdk-webpack": "^4.19.0-prerelease.2", "@openshift-console/plugin-shared": "^0.0.3", - "@patternfly/quickstarts": "^6.2.0", - "@patternfly/react-charts": "^8.2.0", - "@patternfly/react-core": "^6.2.0", - "@patternfly/react-icons": "^6.2.0", - "@patternfly/react-table": "^6.2.0", - "@patternfly/react-data-view": "^6.2.0", - "@patternfly/react-tokens": "6.2.0", - "@patternfly/react-topology": "^6.2.0", + "@patternfly/quickstarts": "^6.4.0", + "@patternfly/react-charts": "^8.4.0", + "@patternfly/react-core": "^6.4.0", + "@patternfly/react-data-view": "^6.4.0", + "@patternfly/react-icons": "^6.4.0", + "@patternfly/react-table": "^6.4.0", + "@patternfly/react-tokens": "6.4.0", + "@patternfly/react-topology": "^6.4.0", + "@svgr/webpack": "^8.1.0", "@types/classnames": "^2.3.1", + "@types/dagre": "^0.7.53", "@types/git-url-parse": "^9.0.0", "@types/node": "^17.0.21", "@types/react": "17.0.89", "@types/react-redux": "7.1.34", - "@types/webpack-dev-server": "^4.7.2", "@types/semver": "7.7.1", + "@types/webpack-dev-server": "^4.7.2", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", "copy-webpack-plugin": "12.0.2", @@ -51,13 +54,13 @@ "eslint-plugin-react-hooks": "^4.3.0", "eslint-plugin-simple-import-sort": "^7.0.0", "file-loader": "6.2.0", + "http-server": "0.12.x", "i18next": "^19.8.3", "i18next-parser": "^3.3.0", - "lodash-es": "^4.17.21", + "lodash-es": "^4.17.23", + "marked": "15.0.12", "prettier": "^2.6.0", "prop-types": "15.7.x", - "http-server": "0.12.x", - "marked": "15.0.12", "react": "17.0.2", "react-dom": "17.0.2", "react-i18next": "^11.7.3", @@ -79,7 +82,7 @@ "@types/jest": "21.x", "hosted-git-info": "^3.0.8", "jquery": "3.5.1", - "lodash-es": "^4.17.21", + "lodash-es": "^4.17.23", "minimist": "1.2.8", "ua-parser-js": "^0.7.24", "jest": "21.x", @@ -102,6 +105,7 @@ }, "dependencies": { "classnames": "^2.3.2", + "dagre": "^0.8.5", "git-url-parse": "^13.1.0", "react": "17.0.2", "react-helmet": "^6.1.0", diff --git a/src/gitops/components/application/ApplicationDetailsTab.tsx b/src/gitops/components/application/ApplicationDetailsTab.tsx index cbea04bac..b713720a6 100644 --- a/src/gitops/components/application/ApplicationDetailsTab.tsx +++ b/src/gitops/components/application/ApplicationDetailsTab.tsx @@ -14,23 +14,8 @@ import SyncStatus from '@gitops/Statuses/SyncStatus'; import { ArgoServer, getArgoServer, getFriendlyClusterName } from '@gitops/utils/gitops'; import { useGitOpsTranslation } from '@gitops/utils/hooks/useGitOpsTranslation'; import { useObjectModifyPermissions } from '@gitops/utils/utils'; -import { - k8sUpdate, - ResourceLink, - useK8sModel, - useModal, -} from '@openshift-console/dynamic-plugin-sdk'; -import { ModalComponent } from '@openshift-console/dynamic-plugin-sdk/lib/app/modal-support/ModalProvider'; -import { - Button, - Label as PfLabel, - Modal, - ModalBody, - ModalFooter, - ModalHeader, - ToggleGroup, - ToggleGroupItem, -} from '@patternfly/react-core'; +import { k8sUpdate, ResourceLink, useK8sModel } from '@openshift-console/dynamic-plugin-sdk'; +import { Label as PfLabel, ToggleGroup, ToggleGroupItem } from '@patternfly/react-core'; import { DescriptionList, Flex, @@ -62,7 +47,6 @@ const ApplicationDetailsTab: React.FC = ({ obj }) => const [canPatch, canUpdate] = useObjectModifyPermissions(obj, ApplicationModel); const [argoServer, setArgoServer] = React.useState({ host: '', protocol: '' }); - const launchModal = useModal(); React.useEffect(() => { (async () => { getArgoServer(model, obj) @@ -75,37 +59,6 @@ const ApplicationDetailsTab: React.FC = ({ obj }) => })(); }, [model, obj]); - const modalStyle: React.CSSProperties = { - padding: '1rem 1rem', - textAlign: 'left', - zIndex: 9999, - width: '500px', - }; - - const syncErrorModal: ModalComponent = (props) => { - return ( - - - - - Sync policy change failed. Check your application/logs and try again. - - - - - - - ); - }; - const onChangeAutomated = (event: React.MouseEvent | React.KeyboardEvent | MouseEvent) => { const id = event.currentTarget.id; switch (id) { @@ -145,7 +98,7 @@ const ApplicationDetailsTab: React.FC = ({ obj }) => // ignore }) .catch((e) => { - launchModal(syncErrorModal, { errorMessage: e.message }); + console.log('GitOps error updating application:' + e); }); }; diff --git a/src/gitops/components/application/ApplicationResourcesTab.tsx b/src/gitops/components/application/ApplicationResourcesTab.tsx index 189b78a02..ea2528954 100644 --- a/src/gitops/components/application/ApplicationResourcesTab.tsx +++ b/src/gitops/components/application/ApplicationResourcesTab.tsx @@ -21,6 +21,9 @@ import { import { EmptyState, EmptyStateBody, + Flex, + FlexItem, + PageBody, PageSection, PageSectionVariants, Title, @@ -31,8 +34,11 @@ import { CubesIcon } from '@patternfly/react-icons'; import { Tbody, Td, Tr } from '@patternfly/react-table'; import { ArgoServer, getArgoServer } from '../../utils/gitops'; +import ArgoCDLink from '../shared/ArgoCDLink/ArgoCDLink'; import { GitOpsDataViewTable, useGitOpsDataViewSort } from '../shared/DataView'; +import { ApplicationGraphView } from './graph/ApplicationGraphView'; + type ApplicationResourcesTabProps = RouteComponentProps<{ ns: string; name: string; @@ -119,24 +125,64 @@ const ApplicationResourcesTab: React.FC = ({ obj } {t('Application resources')} - {obj.metadata && ( + + + {t( + "The graph and table views show health and sync status for the application's immediate resources only. Click the Argo CD Link to see the complete resource tree. Use the filter to filter resources based on status and kind.", + )} + + + + + + + + <> - - + {obj.metadata && ( + + + + + + + + + + + )} - )} + ); diff --git a/src/gitops/components/application/graph/ApplicationGraphView.scss b/src/gitops/components/application/graph/ApplicationGraphView.scss new file mode 100644 index 000000000..dbdf3ab65 --- /dev/null +++ b/src/gitops/components/application/graph/ApplicationGraphView.scss @@ -0,0 +1,29 @@ +// GraphView Topology Styles +.gitops-topology-view { + height: 100%; + width: 100%; + + // Background grid + .pf-topology-content + { + background-image: radial-gradient( var(--pf-t--global--text--color--regular) 0.5px, transparent 0.5px) !important; + background-size: 24px 24px !important; + } + + // Toolbar - move to the top left corner and override Patternfly's style + // Argo CD toolbar is in the top left corner + .pf-topology-control-bar { + position: absolute; + top: 0; + left: var(--pf-t--global--spacer--lg); + height: 40px !important; + border-radius: 4px; + padding: 8px; + } + + // Not the same as in the Topology view, but seems like a border is better for more visibility, + // especially when in dark mode. Remove this if we want to be consistent with the Topology view. + .pf-topology-control-bar__button.pf-v6-c-button.pf-m-tertiary { + border: 1px solid darkgray; + } +} diff --git a/src/gitops/components/application/graph/ApplicationGraphView.tsx b/src/gitops/components/application/graph/ApplicationGraphView.tsx new file mode 100644 index 000000000..0e19662e8 --- /dev/null +++ b/src/gitops/components/application/graph/ApplicationGraphView.tsx @@ -0,0 +1,479 @@ +import * as React from 'react'; +import { NavigateFunction, useNavigate } from 'react-router-dom-v5-compat'; +import { observer } from 'mobx-react'; + +import { + ApplicationKind, + applicationModelRef, + ApplicationResourceStatus, +} from '@gitops/models/ApplicationModel'; +import { HealthStatus } from '@gitops/utils/constants'; +import { ArgoServer, getArgoServer } from '@gitops/utils/gitops'; +import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; +import { + useAnnotationsModal, + useDeleteModal, + useK8sModels, + useLabelsModal, + useUserSettings, +} from '@openshift-console/dynamic-plugin-sdk'; +import { useK8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/utils/k8s/hooks/useK8sModel'; +import { ObjectGroupIcon } from '@patternfly/react-icons'; +import { + action, + ComponentFactory, + ContextMenuItem, + ContextMenuSeparator, + createTopologyControlButtons, + DagreLayout, + DEFAULT_SPACER_NODE_TYPE, + defaultControlButtonsOptions, + DefaultEdge, + Edge, + EdgeStyle, + EdgeTerminalType, + Graph, + GraphComponent, + GraphElement, + GROUPS_LAYER, + Layer, + Layout, + LayoutFactory, + Model, + ModelKind, + Node as TopologyNode, + SELECTION_EVENT, + SpacerNode, + TaskEdge, + TopologyControlBar, + TopologyView, + Visualization, + VisualizationProvider, + VisualizationSurface, + withContextMenu, + withPanZoom, + withSelection, +} from '@patternfly/react-topology'; + +import { GraphResourceMenuItem } from './hooks/GraphResourceMenuItems'; +import { ApplicationNode } from './nodes/ApplicationNode'; +import { ResourceGroupNode } from './nodes/ResourceGroupNode'; +import { ResourceNode } from './nodes/ResourceNode'; +import { getInitialEdges, getInitialNodes } from './graph-utils'; + +import './ApplicationGraphView.scss'; + +const customLayoutFactory: LayoutFactory = (type: string, graph: Graph): Layout | undefined => { + return new DagreLayout(graph, { + rankdir: 'LR', + ranksep: 1, + nodesep: 0, + edgesep: 0, + ranker: 'network-simplex', + marginx: 50, + marginy: 50, + }); +}; + +const customComponentFactory = + ( + hrefRef: React.MutableRefObject, + application: ApplicationKind, + navigate: NavigateFunction, + launchLabelsModal: () => void, + launchAnnotationsModal: () => void, + launchDeleteModal: () => void, + groupNodeStates: string[], + setGroupNodeStates: React.Dispatch>, + ): ComponentFactory => + (kind: ModelKind, type: string) => { + const createContextMenuItems = ( + graphElement: GraphElement, + resourceKind, + ...labels: string[] + ): React.ReactElement[] => { + return labels.map((label, i) => contextMenuItem(graphElement, label, i)); + }; + const createContextMenuItems2 = ( + graphElement: GraphElement, + labels: string[], + ): React.ReactElement[] => { + return labels.map((label, i) => contextMenuItem2(graphElement, label, i)); + }; + + const contextMenuItem2 = ( + graphElement: GraphElement, + label: string, + i: number, + ): React.ReactElement => { + if (label === '-') { + return ; + } + + if ( + label === 'Edit labels' || + label === 'Edit annotations' || + label === 'Delete ' + graphElement.getData().kind || + label === 'Edit ' + graphElement.getData().kind + ) { + return ; + } + + // For other actions that don't need resource-specific hooks + return ( + { + if (label === t('View in Argo CD')) { + window.open(hrefRef.current, '_blank'); + } + }} + > + {label} + + ); + }; + + const resourceItems = (graphElement: GraphElement) => { + if (graphElement.getData().resourceHealthStatus === HealthStatus.MISSING) { + return createContextMenuItems2(graphElement, [t('View in Argo CD')]); + } + if (graphElement.getData().kind === 'AppProject') { + return createContextMenuItems2(graphElement, [ + t('Edit labels'), + t('Edit annotations'), + t('Edit {{x}}', { + x: graphElement.getData().kind, + }), + '-', + t('View in Argo CD'), + ]); + } else { + return createContextMenuItems2(graphElement, [ + t('Edit labels'), + t('Edit annotations'), + t('Edit {{x}}', { + x: graphElement.getData().kind, + }), + t('Delete {{x}}', { + x: graphElement.getData().kind, + }), + '-', + t('View in Argo CD'), + ]); + } + }; + + const contextMenuItem = ( + graphElement: GraphElement, + label: string, + i: number, + ): React.ReactElement => { + if (label === '-') { + return ; + } + + return ( + // eslint-disable-next-line no-alert + { + if (label === t('View in Argo CD')) { + window.open(hrefRef.current, '_blank'); + } else if (label === t('Edit labels')) { + launchLabelsModal(); + } else if (label === t('Edit annotations')) { + launchAnnotationsModal(); + } else if (label === t('Edit Application')) { + navigate( + `/k8s/ns/${application.metadata.namespace}/${applicationModelRef}/${application.metadata.name}/yaml`, + ); + } else if (label === t('Delete Application')) { + launchDeleteModal(); + } else if ( + label === 'Show ' + graphElement.getData().kindPlural || + label === 'Hide ' + graphElement.getData().kindPlural + ) { + const key = graphElement.getData().kindPlural; + setGroupNodeStates((prev) => { + const isPresent = prev.includes(key); + const newStates = isPresent ? prev.filter((node) => node !== key) : [...prev, key]; + return newStates; + }); + } + }} + > + {label} + + ); + }; + switch (type) { + case 'group': + return TransparentGroup; + case 'data-edge': + return DataEdge; + case 'task-edge': + return TaskEdge; + case 'spacer-node': + return SpacerNode; + case DEFAULT_SPACER_NODE_TYPE: + return SpacerNode; + case 'node-group': + return withContextMenu((graphElement) => { + const resourceGroupExpandState = graphElement.getData().resourceGroupExpandState; + return createContextMenuItems( + graphElement, + kind, + !resourceGroupExpandState + ? t('Show {{x}}', { + x: graphElement.getData().kindPlural, + }) + : t('Hide {{x}}', { + x: graphElement.getData().kindPlural, + }), + ); + })(withSelection()(ResourceGroupNode)); + case 'application-node': { + return withContextMenu((graphElement) => + createContextMenuItems( + graphElement, + t('Edit labels'), + t('Edit annotations'), + t('Edit Application'), + t('Delete Application'), + '-', + t('View in Argo CD'), + ), + )(withSelection()(ApplicationNode)); + } + default: + switch (kind) { + case ModelKind.graph: + return withPanZoom()(GraphComponent); + case ModelKind.node: + return withContextMenu((graphElement) => resourceItems(graphElement))( + withSelection()(ResourceNode), + ); + case ModelKind.edge: + return TaskEdge; + default: + return undefined; + } + } + }; + +const TransparentGroup: React.FC<{ element: TopologyNode }> = observer(({}) => { + return ( + + + + ); +}); + +interface DataEdgeProps { + element: Edge; +} + +const DataEdge: React.FC = ({ element, ...rest }) => ( + +); + +export const ApplicationGraphView: React.FC<{ + application: ApplicationKind; + resources: ApplicationResourceStatus[]; +}> = ({ application, resources }) => { + const [model] = useK8sModel({ group: 'route.openshift.io', version: 'v1', kind: 'Route' }); + const [allK8sModels] = useK8sModels(); + const [groupNodeStates, setGroupNodeStates] = React.useState([]); + // Save the group node setting so it will be used whenever the user re-enters the graph view + const [groupNodeState, setGroupNodeState] = useUserSettings( + 'redhat.gitops.groupNodeState', + false, + false, + ); + const [argoServer, setArgoServer] = React.useState({ host: '', protocol: '' }); + const hrefRef = React.useRef(''); + React.useEffect(() => { + (async () => { + getArgoServer(model, application) + .then((server) => { + setArgoServer(server); + }) + .catch((err) => { + console.error('Graph view error: ' + err); + }); + })(); + }, [model, application]); + const href = argoServer + ? argoServer.protocol + + '://' + + argoServer.host + + '/applications/' + + application?.metadata?.namespace + + '/' + + application?.metadata?.name + : ''; + hrefRef.current = href; + + const [selectedIds, setSelectedIds] = React.useState([]); + const [renderKey, setRenderKey] = React.useState(0); + const launchLabelsModal = useLabelsModal(application); + const launchAnnotationsModal = useAnnotationsModal(application); + const launchDeleteModal = useDeleteModal(application); + const navigate = useNavigate(); + + const controller = React.useMemo(() => { + const newController = new Visualization(); + newController.registerLayoutFactory(customLayoutFactory); + newController.registerComponentFactory( + customComponentFactory( + hrefRef, + application, + navigate, + launchLabelsModal, + launchAnnotationsModal, + launchDeleteModal, + groupNodeStates, + setGroupNodeStates, + ), + ); + newController.addEventListener(SELECTION_EVENT, setSelectedIds); + return newController; + }, []); + + const initialNodes = getInitialNodes( + application, + resources, + allK8sModels, + groupNodeState, + groupNodeStates, + ); + const initialEdges = getInitialEdges(application, initialNodes, groupNodeState); + const nodes = [...initialNodes]; + + // Logic to handle unnecessary re-renders was aided by AI. Examining structural changes to the tree to determine + // when to refresh and layout seems like a good idea, versus, data-only changes, and we just simply want + // to refresh the contents of the nodes. This appears to work better than setting merge to true and false on the controller + // Track the previous node count to detect structural changes + const previousNodeCountRef = React.useRef(0); + const groupNodeRef = React.useRef(groupNodeState); + + const currentNodeCount = nodes.length; + const previousNodeCount = previousNodeCountRef.current; + const previousGroupNodeState = groupNodeRef.current; + const isStructuralChange = + currentNodeCount !== previousNodeCount || previousGroupNodeState != groupNodeState; + + if (isStructuralChange || previousNodeCount === 0) { + // Structural change: Create model WITH layout + const modelWithLayout: Model = { + nodes: nodes, + edges: initialEdges, + graph: { + id: 'g1', + type: 'graph', + layout: 'PipleineDagreLayout', + }, + }; + + controller.fromModel(modelWithLayout, false); + previousNodeCountRef.current = currentNodeCount; + groupNodeRef.current = groupNodeState; + } else { + // Data change only: Update ONLY changed nodes (no layout, no position changes) + let updateCount = 0; + nodes.forEach((nodeModel) => { + const existingNode = controller.getNodeById(nodeModel.id); + if (!existingNode) { + return; + } + + if (existingNode) { + const oldData = existingNode.getData(); + const newData = nodeModel.data; + + // Check if data actually changed + const dataChanged = JSON.stringify(oldData) !== JSON.stringify(newData); + + if (dataChanged) { + // Create a completely new object to ensure MobX detects the change + const freshData = JSON.parse(JSON.stringify(newData)); + existingNode.setData(freshData); + + // Also update the model data to ensure consistency + existingNode.setModel({ + ...existingNode.toModel(), + data: freshData, + status: nodeModel.status, + label: nodeModel.label, + }); + // Update other properties + if (nodeModel.label && existingNode.getLabel() !== nodeModel.label) { + existingNode.setLabel(nodeModel.label); + } + if (nodeModel.status !== undefined && existingNode.getNodeStatus() !== nodeModel.status) { + existingNode.setNodeStatus(nodeModel.status); + } + updateCount++; + } + } + }); + + if (updateCount > 0) { + // Force React to re-render the VisualizationSurface by changing key + setRenderKey((prev) => prev + 1); + } + } + + return ( + { + controller.getGraph().scaleBy(4 / 3); + }), + zoomOutCallback: action(() => { + controller.getGraph().scaleBy(0.75); + }), + fitToScreenCallback: action(() => { + controller.getGraph().fit(80); + }), + resetViewCallback: action(() => { + controller.getGraph().reset(); + controller.getGraph().layout(); + }), + customButtons: [ + { + id: 'use-group-nodes', + icon: , + tooltip: t('Group resources of the same kind into one node'), + ariaLabel: t('Group Nodes'), + callback: () => { + setGroupNodeState(!groupNodeState); + controller.getGraph().layout(); + }, + }, + ], + legend: false, + })} + /> + } + > + + + + + ); +}; +// diff --git a/src/gitops/components/application/graph/graph-utils.tsx b/src/gitops/components/application/graph/graph-utils.tsx new file mode 100644 index 000000000..28e742f19 --- /dev/null +++ b/src/gitops/components/application/graph/graph-utils.tsx @@ -0,0 +1,507 @@ +import { ApplicationKind, ApplicationResourceStatus } from '@gitops/models/ApplicationModel'; +import { HealthStatus, SyncStatus } from '@gitops/utils/constants'; +import { K8sModel } from '@openshift-console/dynamic-plugin-sdk'; +import { + EdgeStyle, + LabelPosition, + NodeModel, + NodeShape, + NodeStatus, +} from '@patternfly/react-topology'; + +import { RESOURCE_BADGE_COLORS, RESOURCE_COLORS } from './icons/resource-colours'; + +const NODE_DIAMETER = 50; + +export const kindToAbbr = (kind: string) => { + const abbrKind = (kind.replace(/[^A-Z]/g, '') || kind.toUpperCase()).slice(0, 4); + return abbrKind; +}; + +const NODE_TYPE_APPLICATION = 'application-node'; +const NODE_TYPE_APPLICATION_LABEL = 'Application'; + +// Map application health status with topology node status +const createApplicationNode = (application: ApplicationKind): NodeModel => { + // This is for the border color of the application node. It will be determined by the app's health status. + let nodeStatus = NodeStatus.default; + switch (application.status?.health?.status) { + case HealthStatus.HEALTHY: + nodeStatus = NodeStatus.success; + break; + case HealthStatus.MISSING: + nodeStatus = NodeStatus.warning; + break; + case HealthStatus.PROGRESSING: + nodeStatus = NodeStatus.info; + break; + case HealthStatus.DEGRADED: + nodeStatus = NodeStatus.danger; + break; + default: + nodeStatus = NodeStatus.default; + } + return { + id: + application.kind + + '-' + + (application?.metadata?.name ?? '') + + '-' + + application?.metadata?.namespace, + type: NODE_TYPE_APPLICATION, + label: NODE_TYPE_APPLICATION_LABEL, + status: nodeStatus, + width: 300, + height: 75, + data: { + name: application?.metadata?.name, + badge: 'A', + badgeColor: RESOURCE_COLORS.get( + RESOURCE_BADGE_COLORS.get('.co-m-resource-' + application?.kind.toLowerCase()), + ), + badgeBorderColor: RESOURCE_COLORS.get( + RESOURCE_BADGE_COLORS.get('.co-m-resource-' + application?.kind.toLowerCase()), + ), + rank: 0, + nodeStatus: nodeStatus, + reourceHealthStatus: application?.status?.health?.status, + appHealthStatus: application?.status?.health?.status, + syncStatus: application?.status?.sync?.status, + }, + }; +}; + +export const getResourceNodeSyncStatus = (resource: ApplicationResourceStatus): NodeStatus => { + switch (resource.status) { + case 'Synced': + return NodeStatus.success; + case 'OutOfSync': + return NodeStatus.warning; + case 'Progressing': + return NodeStatus.info; + default: + return NodeStatus.warning; + } +}; + +// For the border color of the resource node to indicate the health status +// If the resource has no health status (from the CR) then the color is default +const getResourceNodeHealthStatus = (resource: ApplicationResourceStatus): NodeStatus => { + switch (resource.health?.status) { + case HealthStatus.HEALTHY: + return NodeStatus.success; + case HealthStatus.PROGRESSING: + return NodeStatus.info; + case HealthStatus.SUSPENDED: + case HealthStatus.MISSING: + return NodeStatus.warning; + case HealthStatus.DEGRADED: + return NodeStatus.danger; + default: + return NodeStatus.default; + } +}; + +// For the border color of the group node to indicate the overall health status +const getGroupNodeHealthStatus = ( + resource: ApplicationResourceStatus, + resources: ApplicationResourceStatus[], +): NodeStatus => { + const resourceHealthyCount = resources.filter( + (res) => res.kind === resource.kind && res.health?.status === HealthStatus.HEALTHY, + ).length; + const resourceProgressingCount = resources.filter( + (res) => res.kind === resource.kind && res.health?.status === HealthStatus.PROGRESSING, + ).length; + const resourceNotHealthyCount = resources.filter( + (res) => + res.kind === resource.kind && + (res.health?.status === HealthStatus.SUSPENDED || + res.health?.status === HealthStatus.DEGRADED || + res.health?.status === HealthStatus.MISSING), + ).length; + + if (resourceNotHealthyCount === 0 && resourceProgressingCount === 0 && resourceHealthyCount > 0) { + return NodeStatus.success; + } else if (resourceProgressingCount > 0 && resourceNotHealthyCount === 0) { + return NodeStatus.info; + } else if (resourceNotHealthyCount > 0) { + return NodeStatus.warning; + } + return NodeStatus.default; +}; + +const createSpacerNode = (rank: number, id: string): NodeModel => { + return { + id: id, + type: 'spacer-node', + data: { + rank: rank, + }, + }; +}; + +const createGroupResourceNode = ( + kind: string, + resource: ApplicationResourceStatus, + groupResourceNodeMap: Map, + resources: ApplicationResourceStatus[], + allK8sModels: { [key: string]: K8sModel }, + resourceGroupExpandState: boolean, +): Map => { + const resourceCount = resources.filter((res) => res.kind === resource.kind).length; + const resourceHealthyCount = resource.health + ? resources.filter( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.HEALTHY, + ).length + : -1; + // For performance reasons, check if only one resource is in any one of these states, and show it in the group. Then, users + // can look at further details to find out which specific resources and how many are problematic. + let degradedCount = -1; + let missingCount = -1; + let progressingCount = -1; + let suspendedCount = -1; + let unknownCount = -1; + if (resource.health && resourceHealthyCount < resourceCount) { + degradedCount = + resources.findIndex( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.DEGRADED, + ) >= 0 + ? 1 + : 0; + missingCount = + resources.findIndex( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.MISSING, + ) >= 0 + ? 1 + : 0; + progressingCount = + resources.findIndex( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.PROGRESSING, + ) >= 0 + ? 1 + : 0; + suspendedCount = + resources.findIndex( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.SUSPENDED, + ) >= 0 + ? 1 + : 0; + unknownCount = + resources.findIndex( + (res) => + res.kind === resource.kind && + res.health?.hasOwnProperty('status') && + res.health.status === HealthStatus.UNKNOWN, + ) >= 0 + ? 1 + : 0; + } + + const resourceSyncedCount = resources.filter( + (res) => res.kind === resource.kind && res.status === 'Synced', + ).length; + const resourceOutOfSyncCount = resources.filter( + (res) => res.kind === resource.kind && res.status === 'OutOfSync', + ).length; + const resourceSyncUnknownCount = resources.filter( + (res) => res.kind === resource.kind && res.status === 'Unknown', + ).length; + const groupStatus = getGroupNodeHealthStatus(resource, resources); + + let groupResourceNode = groupResourceNodeMap.get(kind); + if (groupResourceNode === undefined || groupResourceNode === null) { + groupResourceNode = { + id: kind + '-node-group', + type: 'node-group', + label: allK8sModels[kind]?.labelPlural || kind + 's', + shape: NodeShape.stadium, + status: groupStatus, + width: 280, + height: 70, + data: { + rank: 2, + kind: kind, // Group's kind + kindPlural: allK8sModels[kind]?.labelPlural || kind + 's', + resourceGroupExpandState: resourceGroupExpandState, + nodeStatus: groupStatus, + healthStatus: groupStatus, + healthyCount: resourceHealthyCount, + hasDegraded: degradedCount > 0, + hasMissing: missingCount > 0, + hasProgressing: progressingCount > 0, + hasSuspended: suspendedCount > 0, + hasUnknown: unknownCount > 0, + syncStatus: groupStatus, + syncedCount: 0, + outOfSyncCount: 0, + syncUnknownCount: 0, + totalKindCount: 0, + resourceCount: resourceCount, + resourceSyncedCount: resourceSyncedCount, + resourceOutOfSyncCount: resourceOutOfSyncCount, + resourceSyncUnknownCount: resourceSyncUnknownCount, + badge: allK8sModels[kind]?.abbr || kindToAbbr(kind), + badgeColor: + RESOURCE_COLORS.get(RESOURCE_BADGE_COLORS.get('.co-m-resource-' + kind.toLowerCase())) || + RESOURCE_COLORS.get('color-container-dark'), + icon: kind, + resourceChildrenIds: [], + }, + }; + } + const nodeId = resource.kind + '-' + resource.name + '-' + resource.namespace; + groupResourceNode.data.resourceChildrenIds = [ + ...groupResourceNode.data.resourceChildrenIds, + nodeId, + ]; + if (resource.status === SyncStatus.SYNCED) { + const i = groupResourceNode.data?.syncedCount; + groupResourceNode.data.syncedCount = i + 1; + } else if (resource.status === SyncStatus.OUT_OF_SYNC) { + const i = groupResourceNode.data?.outOfSyncCount; + groupResourceNode.data.outOfSyncCount = i + 1; + } + groupResourceNode.data.totalKindCount++; + groupResourceNodeMap.set(kind, groupResourceNode); + return groupResourceNodeMap; +}; + +// Application Graph Nodes +export const getInitialNodes = ( + application: ApplicationKind, + resources: ApplicationResourceStatus[], + allK8sModels: { [key: string]: K8sModel }, + showGroupNodes: boolean, + groupNodeStates: string[], +) => { + // This contains all the nodes we want to add to the graph view + const initialNodes: NodeModel[] = []; + // This contains all the group nodes for each resource kind: kind to model map + let groupResourceNodeMap = new Map(); + + // Step 1. Create the Application Node + initialNodes.push(createApplicationNode(application)); + + // Step 2: Proceed with adding more nodes only if the application has resources + // If we use the resource tree in the future, this will change + if (resources && resources.length > 0) { + // Spacer node to the right of the application node. Fixed. + initialNodes.push(createSpacerNode(1, 'application-node-spacer')); + // Add child resources + resources.forEach((resource, count) => { + const kind = resource.kind; + const badgeLabel = allK8sModels[kind]?.abbr || kindToAbbr(kind); + const color = + RESOURCE_COLORS.get( + RESOURCE_BADGE_COLORS.get('.co-m-resource-' + resource.kind.toLowerCase()), + ) || RESOURCE_COLORS.get('color-container-dark'); + const nodeId = count + '-' + resource.kind + '-' + resource.name + '-' + resource.namespace; + const key = resource.kind + 's'; + const resourceGroupExpandState = groupNodeStates.includes(key); + + if (showGroupNodes && resources.filter((res) => res.kind === resource.kind).length > 1) { + groupResourceNodeMap = createGroupResourceNode( + kind, + resource, + groupResourceNodeMap, + resources, + allK8sModels, + resourceGroupExpandState, + ); + + if (!initialNodes.includes(groupResourceNodeMap.get(kind))) { + initialNodes.push(groupResourceNodeMap.get(kind)); + } + } + const healthStatus = getResourceNodeHealthStatus(resource); + if ( + !showGroupNodes || + !groupResourceNodeMap.has(kind) || + (showGroupNodes && resourceGroupExpandState) + ) { + initialNodes.push({ + id: nodeId, + type: 'node', + label: resource.kind, + width: 280, + height: NODE_DIAMETER, + labelPosition: LabelPosition.bottom, + shape: NodeShape.rect, + status: healthStatus, + data: { + name: resource.name, + group: resource.group, + kind: resource.kind, + version: resource.version, + namespace: resource.namespace, + indent: 100, + healthStatus: healthStatus, + resourceHealthStatus: resource.health?.status || undefined, + syncStatus: resource.status, + rank: 5, + badgeColor: color, + badge: badgeLabel, + icon: kind, + }, + }); + } + }); + showGroupNodes && + groupResourceNodeMap.forEach((groupNode) => { + const idsOfChildren: string[] = []; + initialNodes + .filter((node) => node.data.kind === groupNode.data.kind && node.type === 'node') + .forEach((n) => { + idsOfChildren.push(n.id); + }); + if (!initialNodes.includes(groupNode)) { + initialNodes.push(groupNode); + } + const key = groupNode.data.kind + 's'; + const resourceGroupExpandState = groupNodeStates.includes(key); + if (showGroupNodes && resourceGroupExpandState) { + const organizerResourceNode = { + id: groupNode.data.kind + '-container', + type: 'group', + group: true, + rank: 3, + children: [ + groupNode.data.kind + '-node-group', + groupNode.data.kind + '-node-spacer', + ...idsOfChildren, + ], + borderRadius: 0, + collapsible: false, + selectable: false, + hideContextMenuKebab: true, + hulledOutline: false, + style: { padding: 40 }, + data: { + kind: groupNode.data.kind, + }, + }; + initialNodes.push({ + id: groupNode.data.kind + '-node-spacer', + type: 'spacer-node', + data: { + rank: 4, + kind: groupNode.data.kind, + healthStatus: groupNode.data.healthStatus, + syncStatus: groupNode.data.syncStatus, + }, + }); + initialNodes.push(organizerResourceNode); + } + }); + if (showGroupNodes) { + const idsOfChildren: string[] = []; + groupResourceNodeMap.forEach((groupNode) => { + idsOfChildren.push(groupNode.id); + }); + const transparentGroupsOfGroups = { + id: 'transparent-group-of-groups-container', + type: 'group', + group: true, + children: [...idsOfChildren], + borderRadius: 0, + collapsible: false, + selectable: false, + hideContextMenuKebab: true, + hulledOutline: false, + style: { padding: 40 }, + }; + initialNodes.push(transparentGroupsOfGroups); + } + } + return initialNodes; +}; + +export const getInitialEdges = ( + application: ApplicationKind, + nodes: NodeModel[], + showGroupNodes: boolean, +) => { + const initialEdges = []; + if (nodes.length > 1) { + initialEdges.push({ + id: 'e-application', + type: 'edge', + source: + application.kind + + '-' + + (application.metadata?.name ?? '') + + '-' + + application.metadata?.namespace, + target: 'application-node-spacer', + edgeStyle: EdgeStyle.default, + }); + nodes.forEach((node: NodeModel, index: number) => { + // Application spacer to group node edge + if (showGroupNodes && node.type === 'node-group') { + initialEdges.push({ + id: 'e-' + node.data.kind + '-node-group', + type: 'edge', + source: 'application-node-spacer', + target: node.id, + edgeStyle: EdgeStyle.dotted, + data: { + indent: 100, + }, + }); + } + if (showGroupNodes && node.data?.kind && node.type === 'spacer-node') { + initialEdges.push({ + id: 'e-' + node.data.kind + '-node-group-connector', + type: 'data-edge', // + source: node.data.kind + '-node-group', + target: node.data.kind + '-node-spacer', + edgeStyle: EdgeStyle.dotted, + data: { + indent: 100, + }, + }); + } + if ( + node.type != 'application-node' && + node.type != 'spacer-node' && + node.type != 'node-group' && + node.type != 'group' + ) { + if (node.type === 'node') { + const b = + nodes.filter( + (res) => res.type === 'node-group' && res.id === node.label + '-node-group', + ).length > 0; + initialEdges.push({ + id: 'e-' + node.label + '-' + index, + type: 'edge', + nodeSeparation: 0, + source: showGroupNodes && b ? node.label + '-node-spacer' : 'application-node-spacer', + target: node.id, + edgeStyle: EdgeStyle.default, + data: { + indent: 100, + }, + }); + } + } + }); + } + return initialEdges; +}; diff --git a/src/gitops/components/application/graph/hooks/GraphResourceMenuItems.tsx b/src/gitops/components/application/graph/hooks/GraphResourceMenuItems.tsx new file mode 100644 index 000000000..fc88ef785 --- /dev/null +++ b/src/gitops/components/application/graph/hooks/GraphResourceMenuItems.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom-v5-compat'; + +import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; +import { modelToRef } from '@gitops/utils/utils'; +import { + useAnnotationsModal, + useDeleteModal, + useLabelsModal, +} from '@openshift-console/dynamic-plugin-sdk'; +import { useK8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/utils/k8s/hooks/useK8sModel'; +import { GraphElement } from '@patternfly/react-topology'; +import { ContextMenuItem } from '@patternfly/react-topology'; + +interface GraphResourceMenuItemProps { + graphElement: GraphElement; + label: string; +} + +export const GraphResourceMenuItem: React.FC = ({ + graphElement, + label, +}) => { + const data = graphElement.getData(); + const placeholderResource = React.useMemo( + () => ({ + apiVersion: data.group ? `${data.group}/${data.version}` : data.version, + kind: data.kind, + metadata: { + name: data.name, + namespace: data.namespace, + }, + }), + [data.group, data.version, data.kind, data.name, data.namespace], + ); + const launchResourceLabelsModal = useLabelsModal(placeholderResource); + const launchResourceAnnotationsModal = useAnnotationsModal(placeholderResource); + const [k8sModel] = useK8sModel({ group: data.group, version: data.version, kind: data.kind }); + const modelRef = modelToRef(k8sModel); + const launchResourceDeleteModal = useDeleteModal(placeholderResource, window.location); + const navigate = useNavigate(); + + return ( + { + if (label === t('Edit labels')) { + launchResourceLabelsModal(); + } else if (label === t('Edit annotations')) { + launchResourceAnnotationsModal(); + } else if (label === t('Delete {{x}}', { x: data.kind })) { + launchResourceDeleteModal(); + } else if (label === t('Edit {{x}}', { x: data.kind })) { + navigate(`/k8s/ns/${data.namespace}/${modelRef}/${data.name}/yaml`); + } + }} + > + {label} + + ); +}; diff --git a/src/gitops/components/application/graph/icons/resource-colours.tsx b/src/gitops/components/application/graph/icons/resource-colours.tsx new file mode 100644 index 000000000..4674e954a --- /dev/null +++ b/src/gitops/components/application/graph/icons/resource-colours.tsx @@ -0,0 +1,72 @@ +export const RESOURCE_COLORS = new Map([ + ['color-alertmanager-dark', '#773d00'], + ['color-application-dark', '#3e8635'], + ['color-application', '#E9654B'], + ['color-appproject', '#E9654B'], + ['color-configmap-dark', '#40199a'], + ['color-container-dark', '#2b9af3'], + ['color-ingress-dark', '#40199a'], + ['color-namespace-dark', '#1e4f18'], + ['color-node-dark', '#8476d1'], + ['color-pod-dark', '#009596'], + ['color-pod-overlord', '#004080'], + ['color-rbac-binding-dark', '#008bad'], + ['color-rbac-role-dark', '#795600'], + ['color-secret-dark', '#c46100'], + ['color-service-dark', '#6ca100'], +]); + +export const COLOR_MAP = new Map([ + ['$color-alert-dark', '$color-container-dark'], + ['$color-alertrule-dark', '$color-configmap-dark'], + ['$color-controller-dark', '$color-pod-overlord'], + ['$color-deployment-dark', '$color-controller-dark'], + ['$color-deploymentconfig-dark', '$color-controller-dark'], + ['$color-job-dark', '$color-controller-dark'], + ['$color-petset-dark', '$color-controller-dark'], + ['$color-replicaset-dark', '$color-controller-dark'], + ['$color-serviceaccount-dark', '$color-configmap-dark'], +]); + +export const RESOURCE_BADGE_COLORS = new Map([ + ['.co-m-resource-application', 'color-application'], + ['.co-m-resource-appproject', 'color-appproject'], + ['.co-m-resource-clusterrole', 'color-rbac-role-dark'], + ['.co-m-resource-role', 'color-rbac-role-dark'], + ['.co-m-resource-clusterrolebinding', 'color-rbac-binding-dark'], + ['.co-m-resource-rolebinding', 'color-rbac-binding-dark'], + + ['.co-m-resource-daemonset', 'color-pod-overlord'], + ['.co-m-resource-deployment', 'color-pod-overlord'], + ['.co-m-resource-deploymentconfig', 'color-pod-overlord'], + ['.co-m-resource-job', 'color-pod-overlord'], + ['.co-m-resource-petset', 'color-pod-overlord'], + ['.co-m-resource-replicaset', 'color-pod-overlord'], + ['.co-m-resource-replicationcontroller', 'color-pod-overlord'], + + ['.co-m-resource-machine', 'color-node-dark'], + ['.co-m-resource-machineautoscaler', 'color-node-dark'], + ['.co-m-resource-machineclass', 'color-node-dark'], + ['.co-m-resource-machineconfig', 'color-node-dark'], + ['.co-m-resource-machineconfigpool', 'color-node-dark'], + ['.co-m-resource-machinedeployment', 'color-node-dark'], + ['.co-m-resource-machinehealthcheck', 'color-node-dark'], + ['.co-m-resource-machineset', 'color-node-dark'], + ['.co-m-resource-node', 'color-node-dark'], + ['.co-m-resource-policy', 'color-node-dark'], + + ['.co-m-resource-alertrule', 'color-configmap-dark'], + ['.co-m-resource-configmap', 'color-configmap-dark'], + + ['.co-m-resource-alert', 'color-container-dark'], + ['.co-m-resource-container', 'color-container-dark'], + + ['.co-m-resource-pod', 'color-pod-dark'], + ['.co-m-resource-namespace', 'color-namespace-dark'], + ['.co-m-resource-project', 'color-namespace-dark'], + ['.co-m-resource-secret', 'color-secret-dark'], + ['.co-m-resource-alertmanager', 'color-alertmanager-dark'], + ['.co-m-resource-service', 'color-service-dark'], + ['.co-m-resource-serviceaccount', 'color-configmap-dark'], + ['.co-m-resource-ingress', 'color-ingress-dark'], +]); diff --git a/src/gitops/components/application/graph/icons/resource-icons.tsx b/src/gitops/components/application/graph/icons/resource-icons.tsx new file mode 100644 index 000000000..a3b169686 --- /dev/null +++ b/src/gitops/components/application/graph/icons/resource-icons.tsx @@ -0,0 +1,191 @@ +import * as React from 'react'; + +import { dangerColor, successColor, warningColor } from '@gitops/utils/components/Icons/Icons'; +import { HealthStatus, SyncStatus } from '@gitops/utils/constants'; +import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; +import ApplicationIcon from '@images/resources/application.svg'; +import ConfigMapIcon from '@images/resources/cm.svg'; +import DeploymentIcon from '@images/resources/deploy.svg'; +import JobIcon from '@images/resources/job.svg'; +import NamespaceIcon from '@images/resources/ns.svg'; +import PodIcon from '@images/resources/pod.svg'; +import PVCIcon from '@images/resources/pv.svg'; +import RoleBindingIcon from '@images/resources/rb.svg'; +import ServiceAccountIcon from '@images/resources/sa.svg'; +import SecretIcon from '@images/resources/secret.svg'; +import StatefulSetIcon from '@images/resources/sts.svg'; +import ServiceIcon from '@images/resources/svc.svg'; +import { Tooltip } from '@patternfly/react-core'; +import { + ArrowCircleUpIcon, + CheckCircleIcon, + CircleNotchIcon, + GhostIcon, + HeartBrokenIcon, + HeartIcon, + OutlinedCircleIcon, + PauseCircleIcon, + SyncAltIcon, +} from '@patternfly/react-icons'; + +interface ResourceIconProps { + kind: string; + badge: string; +} + +const iconHeight = 21; +const iconWidth = 21; + +export const ResourceSvgIcon: React.FC = ({ kind, badge }) => { + let targetIcon: React.ReactNode; + switch (kind) { + case 'Namespace': + targetIcon = ; + break; + case 'Secret': + targetIcon = ; + break; + case 'Service': + targetIcon = ; + break; + case 'ServiceAccount': + targetIcon = ; + break; + case 'Pod': + targetIcon = ; + break; + case 'PersistentVolumeClaim': + targetIcon = ; + break; + case 'Deployment': + targetIcon = ; + break; + case 'RoleBinding': + targetIcon = ; + break; + case 'ConfigMap': + targetIcon = ; + break; + case 'StatefulSet': + targetIcon = ; + break; + case 'Job': + targetIcon = ; + break; + case 'Application': + targetIcon = ; + break; + default: + targetIcon = ( + + + + {badge} + + + ); + break; + } + return <>{targetIcon}; +}; + +interface StatusIconProps { + status: string; + x?: number; + y?: number; + width?: number; + height?: number; +} + +export const StatusSvgIcon: React.FC = ({ status }) => { + let targetIcon: React.ReactNode; + switch (status) { + case HealthStatus.PROGRESSING: + targetIcon = ( + + + + ); + break; + } + return <>{targetIcon}; +}; + +export const HealthStatusSvgIcon: React.FC = ({ status, x, y, width, height }) => { + let icon = null; + if (status === HealthStatus.HEALTHY) { + icon = ; + } else if (status === HealthStatus.SUSPENDED) { + icon = ; + } else if (status === HealthStatus.DEGRADED) { + icon = ; + } else if (status === HealthStatus.MISSING) { + icon = ; + } else if (status === HealthStatus.PROGRESSING) { + icon = ; + } else { + icon = ; + } + return ( + +
+ + <>{icon} + +
+
+ ); +}; + +export const SyncStatusSvgIcon: React.FC = ({ status, x, y, width, height }) => { + let icon = null; + if (status === SyncStatus.SYNCED) { + icon = ; + } else if (status === SyncStatus.OUT_OF_SYNC) { + icon = ; + } else { + // status === SyncStatus.UNKNOWN) + icon = ( + + ); + } + return ( + +
+ + <>{icon} + +
+
+ ); +}; diff --git a/src/gitops/components/application/graph/nodes/ApplicationNode.tsx b/src/gitops/components/application/graph/nodes/ApplicationNode.tsx new file mode 100644 index 000000000..9df3b4411 --- /dev/null +++ b/src/gitops/components/application/graph/nodes/ApplicationNode.tsx @@ -0,0 +1,197 @@ +import * as React from 'react'; +import { observer } from 'mobx-react'; + +import SvgTextWithOverflow from '@gitops/components/graph/SvgTextWithOverflow'; +import { ARGO_GRAY4_COLOR } from '@gitops/components/shared/colors'; +import { dangerColor, successColor, warningColor } from '@gitops/utils/components/Icons/Icons'; +import { HealthStatus, SyncStatus } from '@gitops/utils/constants'; +import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; +import ApplicationIcon from '@images/resources/application.svg'; +import { Tooltip } from '@patternfly/react-core'; +import { + ArrowCircleUpIcon, + CheckCircleIcon, + CircleNotchIcon, + GhostIcon, + HeartBrokenIcon, + HeartIcon, + OutlinedCircleIcon, + PauseIcon, +} from '@patternfly/react-icons'; +import { + DefaultNode, + Node, + RectAnchor, + ShapeProps, + useAnchor, + useCombineRefs, + useSvgAnchor, + WithContextMenuProps, + WithSelectionProps, +} from '@patternfly/react-topology'; + +import { StatusSvgIcon } from '../icons/resource-icons'; + +interface CustomNodeProps { + element: Node; +} + +const ApplicationHealthStatusIcon = ({ status }: { status: HealthStatus }) => { + let icon = null; + switch (status) { + case HealthStatus.HEALTHY: + icon = ; + break; + case HealthStatus.MISSING: + icon = ; + break; + case HealthStatus.DEGRADED: + icon = ; + break; + case HealthStatus.PROGRESSING: + icon = ( + + + + ); + return <>{icon}; + case HealthStatus.UNKNOWN: + icon = ; + break; + case HealthStatus.SUSPENDED: + icon = ; + break; + default: + return <>; + } + return ( + +
+ {icon} +
+
+ ); +}; + +const ApplicationSyncStatusIcon = ({ status }: { status: SyncStatus }) => { + let icon = null; + switch (status) { + case SyncStatus.SYNCED: + icon = ; + break; + case SyncStatus.OUT_OF_SYNC: + icon = ( + + ); + break; + case SyncStatus.UNKNOWN: + icon = ( + + ); + break; + } + return ( + +
+ {icon} +
+
+ ); +}; + +const ApplicationShape: React.FunctionComponent = observer( + ({ element, className, width, height, filter, dndDropRef }) => { + useAnchor(RectAnchor); + const data = element.getData(); + const anchorRef = useSvgAnchor(); + const refs = useCombineRefs(dndDropRef, anchorRef); + // Arc first and then draw rectangular part + const applicationShapePath = `M 35 0 A 45 45 200 1 0 35 75 l 0 0 ${ + width - 35 + } 0 l 0 0 0 ${-height} l 0 0 ${-width + 35} 0`; + return ( + + + + + + + + + + + + + + + + + ); + }, +); + +export const ApplicationNode: React.FC< + CustomNodeProps & WithSelectionProps & WithContextMenuProps +> = observer(({ element, onContextMenu, contextMenuOpen, onSelect, selected }) => { + const data = element.getData(); + return ( + { + return ApplicationShape; + }} + /> + ); +}); diff --git a/src/gitops/components/application/graph/nodes/ResourceGroupNode.tsx b/src/gitops/components/application/graph/nodes/ResourceGroupNode.tsx new file mode 100644 index 000000000..ee19bf78f --- /dev/null +++ b/src/gitops/components/application/graph/nodes/ResourceGroupNode.tsx @@ -0,0 +1,209 @@ +import * as React from 'react'; +import { observer } from 'mobx-react'; + +import SvgTextWithOverflow from '@gitops/components/graph/SvgTextWithOverflow'; +import { dangerColor, successColor, warningColor } from '@gitops/utils/components/Icons/Icons'; +import { HealthStatus, SyncStatus } from '@gitops/utils/constants'; +import { t } from '@gitops/utils/hooks/useGitOpsTranslation'; +import { + GhostIcon, + HeartBrokenIcon, + HeartIcon, + PauseCircleIcon, + QuestionCircleIcon, +} from '@patternfly/react-icons'; +import { + DefaultNode, + Node as TopologyNode, + WithContextMenuProps, + WithSelectionProps, +} from '@patternfly/react-topology'; + +import { ResourceSvgIcon, StatusSvgIcon, SyncStatusSvgIcon } from '../icons/resource-icons'; + +interface CustomNodeProps { + element: TopologyNode; +} + +export const ResourceGroupNode: React.FC< + CustomNodeProps & WithSelectionProps & WithContextMenuProps +> = observer(({ element, onContextMenu, contextMenuOpen, onSelect, selected }) => { + const data = element.getData(); + // const Icon = data.icon ? data.icon : null; + const kind = data.icon as string; + return ( + onContextMenu(e)} + contextMenuOpen={contextMenuOpen} + onSelect={onSelect} + selected={selected} + badge={data.badge} + badgeColor={data.badgeColor} + badgeTextColor={'white'} + hover={false} // Need to set this to false for proper selection + badgeBorderColor={data.badgeColor} + > + + {kind !== null ? ( + + + + ) : ( + + + + {data.badge} + + + )} + + + + + {data.healthyCount === data.resourceCount && ( + + )} + {/* eslint-disable no-nested-ternary */} + {data.hasProgressing ? ( + + ) : data.hasMissing ? ( + + ) : data.hasDegraded ? ( + + ) : data.hasSuspended ? ( + + ) : data.hasUnknown ? ( + + ) : ( + <> + )} + {data.resourceSyncedCount === data.resourceCount && ( + + )} + {data.resourceOutOfSyncCount === data.resourceCount && ( + + )} + + + {data.healthyCount === data.resourceCount && ( + +
+ +
+
+ )} + {data.hasProgressing ? ( + <> + + + + {t('One or more resources are in Progressing state')} + + + + + ) : data.hasDegraded ? ( + +
+ +
+
+ ) : data.hasMissing ? ( + +
+ +
+
+ ) : data.hasSuspended ? ( + +
+ +
+
+ ) : data.hasUnknown ? ( + +
+ +
+
+ ) : ( + <> + )} + {data.resourceSyncedCount > 0 && ( + + )} + {data.resourceOutOfSyncCount > 0 && ( + + )} +
+ ); +}); diff --git a/src/gitops/components/application/graph/nodes/ResourceNode.tsx b/src/gitops/components/application/graph/nodes/ResourceNode.tsx new file mode 100644 index 000000000..bb212603d --- /dev/null +++ b/src/gitops/components/application/graph/nodes/ResourceNode.tsx @@ -0,0 +1,73 @@ +/** + * Resource Node for Argo CD Resources + */ +import * as React from 'react'; +import { observer } from 'mobx-react'; + +import SvgTextWithOverflow from '@gitops/components/graph/SvgTextWithOverflow'; +import { HealthStatus } from '@gitops/utils/constants'; +import { + BadgeLocation, + DefaultNode, + LabelPosition, + Node as TopologyNode, + WithContextMenuProps, + WithSelectionProps, +} from '@patternfly/react-topology'; + +import { + HealthStatusSvgIcon, + ResourceSvgIcon, + StatusSvgIcon, + SyncStatusSvgIcon, +} from '../icons/resource-icons'; + +interface CustomNodeProps { + element: TopologyNode; +} + +export const ResourceNode: React.FC = + observer(({ element, onContextMenu, contextMenuOpen, onSelect, selected }) => { + const data = element.getData(); + const kind = data.icon as string; + return ( + + + + + + + + + + + {data.resourceHealthStatus === HealthStatus.PROGRESSING ? ( + + + + ) : ( + + )} + + + ); + }); diff --git a/src/gitops/components/graph/SvgTextWithOverflow.tsx b/src/gitops/components/graph/SvgTextWithOverflow.tsx new file mode 100644 index 000000000..d5c58c218 --- /dev/null +++ b/src/gitops/components/graph/SvgTextWithOverflow.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; + +const SvgTextWithOverflow = ({ text, maxWidth, x, y }) => { + const textRef = React.useRef(null); + const [displayedText, setDisplayedText] = React.useState(text); + + // This truncation logic was done in part with the help of AI. + // However, I will likely replace this whole thing anyway in order to have similar behaviour as + // in Argo CD where you can toggle the field to show the start and end of the string. + // For now, all strings will be truncated to fit inside the node boundary. + React.useEffect(() => { + if (textRef.current) { + const textElement = textRef.current; + const textWidth = textElement.getComputedTextLength(); + + if (textWidth > maxWidth) { + let truncatedText = text; + while (textElement.getComputedTextLength() > maxWidth && truncatedText.length > 0) { + truncatedText = truncatedText.slice(0, -1); + textElement.textContent = truncatedText + '...'; + } + setDisplayedText(truncatedText + '...'); + } else { + setDisplayedText(text); + } + } + }, [text, maxWidth]); + + return ( + + {displayedText} + + ); +}; + +export default SvgTextWithOverflow; diff --git a/src/gitops/hooks/useApplicationActionsProvider.tsx b/src/gitops/hooks/useApplicationActionsProvider.tsx index 76031386d..d5ab271b3 100644 --- a/src/gitops/hooks/useApplicationActionsProvider.tsx +++ b/src/gitops/hooks/useApplicationActionsProvider.tsx @@ -17,10 +17,13 @@ import { useLabelsModal, } from '@openshift-console/dynamic-plugin-sdk'; -type UseApplicationActionsProvider = (application: ApplicationKind) => [actions: Action[]]; +type UseApplicationActionsProvider = ( + application: ApplicationKind, + href?: string, +) => [actions: Action[]]; const t = (key: string) => key; -export const useApplicationActionsProvider: UseApplicationActionsProvider = (application) => { +export const useApplicationActionsProvider: UseApplicationActionsProvider = (application, href) => { const navigate = useNavigate(); const launchLabelsModal = useLabelsModal(application); @@ -148,8 +151,22 @@ export const useApplicationActionsProvider: UseApplicationActionsProvider = (app }, cta: () => launchDeleteModal(), }, + { + id: 'gitops-action-view-in-argocd', + disabled: href === undefined, + label: t('View in Argo CD'), + accessReview: { + group: ApplicationModel.apiGroup, + verb: 'get' as K8sVerb, + resource: ApplicationModel.plural, + namespace: application?.metadata?.namespace, + }, + cta: () => { + window.open(href, '_blank'); + }, + }, ], - [application, navigate, launchLabelsModal, launchAnnotationsModal, launchDeleteModal], + [application, navigate, launchLabelsModal, launchAnnotationsModal, launchDeleteModal, href], ); return [actions]; diff --git a/src/gitops/hooks/useResourceActionsProvider.tsx b/src/gitops/hooks/useResourceActionsProvider.tsx index 6314f8f93..9ef43028e 100644 --- a/src/gitops/hooks/useResourceActionsProvider.tsx +++ b/src/gitops/hooks/useResourceActionsProvider.tsx @@ -51,9 +51,9 @@ export const useResourceActionsProvider: UseResourceActionsProvider = ( const actions = React.useMemo( () => [ { - id: 'gitops-action-edit-labels-application', + id: 'gitops-action-view-in-argocd', disabled: false, - label: t('Details'), + label: t('View in Argo CD'), accessReview: { group: ApplicationModel.apiGroup, verb: 'patch' as K8sVerb, diff --git a/src/gitops/models/ApplicationModel.ts b/src/gitops/models/ApplicationModel.ts index a459963c3..aea259c15 100644 --- a/src/gitops/models/ApplicationModel.ts +++ b/src/gitops/models/ApplicationModel.ts @@ -1,6 +1,7 @@ import { HealthStatus, PhaseStatus, SyncStatus } from 'src/gitops/utils/constants'; -import { modelToRef } from 'src/gitops/utils/utils'; +import { modelToRef, SyncStatusCode } from 'src/gitops/utils/utils'; +import { HealthStatusCode } from '@gitops/Statuses/HealthStatus'; import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk'; import { K8sModel } from '@openshift-console/dynamic-plugin-sdk/lib/api/common-types'; @@ -182,3 +183,158 @@ export type ApplicationKind = K8sResourceCommon & { }; export const applicationModelRef = modelToRef(ApplicationModel); + +export interface ApplicationTree { + nodes: ResourceNode[]; + orphanedNodes: ResourceNode[]; + hosts: Node[]; +} + +export interface Node { + name: string; + systemInfo: NodeSystemInfo; + resourcesInfo: HostResourceInfo[]; + labels: { [name: string]: string }; +} + +export interface NodeSystemInfo { + architecture: string; + operatingSystem: string; + kernelVersion: string; +} + +export interface NodeId { + kind: string; + namespace: string; + name: string; + group: string; + createdAt?: Time; +} + +export function nodeKey(node: NodeId) { + return [node.group, node.kind, node.namespace, node.name].join('/'); +} + +export interface ResourceRef { + uid: string; + kind: string; + namespace: string; + name: string; + version: string; + group: string; +} + +export interface InfoItem { + name: string; + value: string; +} + +export interface ResourceNetworkingInfo { + targetLabels: { [name: string]: string }; + targetRefs: ResourceRef[]; + labels: { [name: string]: string }; + ingress: LoadBalancerIngress[]; + externalURLs: string[]; +} + +export interface LoadBalancerIngress { + hostname: string; + ip: string; +} + +export type Time = string; + +export interface ResourceNode extends ResourceRef { + parentRefs: ResourceRef[]; + info: InfoItem[]; + networkingInfo?: ResourceNetworkingInfo; + images?: string[]; + resourceVersion: string; + createdAt?: Time; +} + +export type PodGroupType = 'topLevelResource' | 'parentResource' | 'node'; +export type SortOrder = 'asc' | 'desc'; + +export interface Pod extends ResourceNode { + fullName: string; + metadata: ObjectMeta; + spec: PodSpec; + health: HealthStatusCode; +} + +export interface PodSpec { + nodeName: string; +} + +export enum ResourceName { + ResourceCPU = 'cpu', + ResourceMemory = 'memory', + ResourceStorage = 'storage', +} + +export interface ResourceStatus { + group: string; + version: string; + kind: string; + namespace: string; + name: string; + status: SyncStatusCode; + health: HealthStatus; + createdAt?: Time; + hook?: boolean; + requiresPruning?: boolean; + requiresDeletionConfirmation?: boolean; + syncWave?: number; + orphaned?: boolean; +} + +export interface HostResourceInfo { + resourceName: ResourceName; + requestedByApp: number; + requestedByNeighbors: number; + capacity: number; +} + +export interface PodGroup extends Partial { + timestamp?: number; + type: PodGroupType; + pods: Pod[]; + info?: InfoItem[]; + hostResourcesInfo?: HostResourceInfo[]; + resourceStatus?: Partial; + renderMenu?: () => React.ReactNode; + renderQuickStarts?: () => React.ReactNode; + fullName?: string; + hostLabels?: { [name: string]: string }; +} + +export interface ResourceTreeNode extends ResourceNode { + status?: SyncStatusCode; + health?: HealthStatus; + hook?: boolean; + root?: ResourceTreeNode; + requiresPruning?: boolean; + orphaned?: boolean; + podGroup?: PodGroup; + isExpanded?: boolean; +} + +export interface ObjectMeta { + name?: string; + generateName?: string; + namespace?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: Time; + deletionTimestamp?: Time; + deletionGracePeriodSeconds?: number; + labels?: { [name: string]: string }; + annotations?: { [name: string]: string }; + ownerReferences?: any[]; + initializers?: any; + finalizers?: string[]; + clusterName?: string; +} diff --git a/src/gitops/utils/components/Icons/Icons.tsx b/src/gitops/utils/components/Icons/Icons.tsx index 890256e74..06e52bb51 100644 --- a/src/gitops/utils/components/Icons/Icons.tsx +++ b/src/gitops/utils/components/Icons/Icons.tsx @@ -27,12 +27,12 @@ import { // import { global_success_color_100 as successColor } from '@patternfly/react-tokens/dist/js/global_success_color_100'; // Modern PatternFly v5 CSS variables approach -const dangerColor = 'var(--pf-v5-global--danger-color--100)'; -const blueDefaultColor = 'var(--pf-v5-global--primary-color--200)'; -const disabledColor = 'var(--pf-v5-global--disabled-color--100)'; -const blueInfoColor = 'var(--pf-v5-global--palette--blue-300)'; -const warningColor = 'var(--pf-v5-global--warning-color--100)'; -const successColor = 'var(--pf-v5-global--success-color--100)'; +export const dangerColor = 'var(--pf-v5-global--danger-color--100)'; +export const blueDefaultColor = 'var(--pf-v5-global--primary-color--200)'; +export const disabledColor = 'var(--pf-v5-global--disabled-color--100)'; +export const blueInfoColor = 'var(--pf-v5-global--palette--blue-300)'; +export const warningColor = 'var(--pf-v5-global--warning-color--100)'; +export const successColor = 'var(--pf-v5-global--success-color--100)'; export { BlueInfoCircleIcon, diff --git a/src/gitops/utils/hooks/useGitOpsTranslation.ts b/src/gitops/utils/hooks/useGitOpsTranslation.ts index aa3f2eb03..5cd77be99 100644 --- a/src/gitops/utils/hooks/useGitOpsTranslation.ts +++ b/src/gitops/utils/hooks/useGitOpsTranslation.ts @@ -10,4 +10,5 @@ export const useGitOpsTranslation = () => useTranslation('plugin__gitops-plugin' * @param value string to translate */ // skipcq: JS-C1002 -export const t = (value: string) => getI18n().t(value, { ns: 'plugin__gitops-plugin' }); +export const t = (value: string, options?: { x: any }) => + getI18n().t(value, { ns: 'plugin__gitops-plugin', ...options }); diff --git a/src/images/README.md b/src/images/README.md new file mode 100644 index 000000000..7e42e0356 --- /dev/null +++ b/src/images/README.md @@ -0,0 +1,9 @@ +# Images in Resources Folder +## Images credits from the following Argo Projects: +1. https://github.com/argoproj/argo-cd.git - Argo CD +2. https://github.com/argoproj/argo-ui.git - Argo UI +```bash +Apache License Version 2.0, +January 2004 +http://www.apache.org/licenses/ +``` \ No newline at end of file diff --git a/src/images/resources/c-role-1.svg b/src/images/resources/c-role-1.svg new file mode 100644 index 000000000..931ad3d44 --- /dev/null +++ b/src/images/resources/c-role-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/c-role.svg b/src/images/resources/c-role.svg new file mode 100644 index 000000000..931ad3d44 --- /dev/null +++ b/src/images/resources/c-role.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/cm.svg b/src/images/resources/cm.svg new file mode 100644 index 000000000..3934ac27e --- /dev/null +++ b/src/images/resources/cm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/crb.svg b/src/images/resources/crb.svg new file mode 100644 index 000000000..dc2f9b2b9 --- /dev/null +++ b/src/images/resources/crb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/crd.svg b/src/images/resources/crd.svg new file mode 100644 index 000000000..729ec6880 --- /dev/null +++ b/src/images/resources/crd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/cronjob.svg b/src/images/resources/cronjob.svg new file mode 100644 index 000000000..8c6aa0d6a --- /dev/null +++ b/src/images/resources/cronjob.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/deploy.svg b/src/images/resources/deploy.svg new file mode 100644 index 000000000..14d716818 --- /dev/null +++ b/src/images/resources/deploy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/ds.svg b/src/images/resources/ds.svg new file mode 100644 index 000000000..a25378f51 --- /dev/null +++ b/src/images/resources/ds.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/ep.svg b/src/images/resources/ep.svg new file mode 100644 index 000000000..f4bd59e61 --- /dev/null +++ b/src/images/resources/ep.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/git.svg b/src/images/resources/git.svg new file mode 100644 index 000000000..9034d96a5 --- /dev/null +++ b/src/images/resources/git.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/images/resources/group.svg b/src/images/resources/group.svg new file mode 100644 index 000000000..8408f5ba7 --- /dev/null +++ b/src/images/resources/group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/helm.svg b/src/images/resources/helm.svg new file mode 100644 index 000000000..76015071c --- /dev/null +++ b/src/images/resources/helm.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/resources/hpa.svg b/src/images/resources/hpa.svg new file mode 100644 index 000000000..5c05a91fe --- /dev/null +++ b/src/images/resources/hpa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/ing.svg b/src/images/resources/ing.svg new file mode 100644 index 000000000..6d5afc419 --- /dev/null +++ b/src/images/resources/ing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/job.svg b/src/images/resources/job.svg new file mode 100644 index 000000000..630980796 --- /dev/null +++ b/src/images/resources/job.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/limits.svg b/src/images/resources/limits.svg new file mode 100644 index 000000000..10c614723 --- /dev/null +++ b/src/images/resources/limits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/netpol.svg b/src/images/resources/netpol.svg new file mode 100644 index 000000000..ec2590c40 --- /dev/null +++ b/src/images/resources/netpol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/ns.svg b/src/images/resources/ns.svg new file mode 100644 index 000000000..318ef350a --- /dev/null +++ b/src/images/resources/ns.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/oci.svg b/src/images/resources/oci.svg new file mode 100644 index 000000000..cdb1c73f3 --- /dev/null +++ b/src/images/resources/oci.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/src/images/resources/pod.svg b/src/images/resources/pod.svg new file mode 100644 index 000000000..5b9afbcff --- /dev/null +++ b/src/images/resources/pod.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/psp.svg b/src/images/resources/psp.svg new file mode 100644 index 000000000..8079d213a --- /dev/null +++ b/src/images/resources/psp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/pv.svg b/src/images/resources/pv.svg new file mode 100644 index 000000000..f81e0cf87 --- /dev/null +++ b/src/images/resources/pv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/pvc.svg b/src/images/resources/pvc.svg new file mode 100644 index 000000000..6b9b422aa --- /dev/null +++ b/src/images/resources/pvc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/quota.svg b/src/images/resources/quota.svg new file mode 100644 index 000000000..b28f00804 --- /dev/null +++ b/src/images/resources/quota.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/rb.svg b/src/images/resources/rb.svg new file mode 100644 index 000000000..f00261994 --- /dev/null +++ b/src/images/resources/rb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/role.svg b/src/images/resources/role.svg new file mode 100644 index 000000000..2b10435e3 --- /dev/null +++ b/src/images/resources/role.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/rs.svg b/src/images/resources/rs.svg new file mode 100644 index 000000000..8418fd802 --- /dev/null +++ b/src/images/resources/rs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/sa.svg b/src/images/resources/sa.svg new file mode 100644 index 000000000..6c3cd72ce --- /dev/null +++ b/src/images/resources/sa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/sc.svg b/src/images/resources/sc.svg new file mode 100644 index 000000000..7a72ccaeb --- /dev/null +++ b/src/images/resources/sc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/secret.svg b/src/images/resources/secret.svg new file mode 100644 index 000000000..40a174d34 --- /dev/null +++ b/src/images/resources/secret.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/sts.svg b/src/images/resources/sts.svg new file mode 100644 index 000000000..1d80ac751 --- /dev/null +++ b/src/images/resources/sts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/svc.svg b/src/images/resources/svc.svg new file mode 100644 index 000000000..562cab004 --- /dev/null +++ b/src/images/resources/svc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/user.svg b/src/images/resources/user.svg new file mode 100644 index 000000000..072d28f83 --- /dev/null +++ b/src/images/resources/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/resources/vol.svg b/src/images/resources/vol.svg new file mode 100644 index 000000000..2e807dbd7 --- /dev/null +++ b/src/images/resources/vol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.d.ts b/src/index.d.ts index d80f426fe..01afb7895 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -4,6 +4,7 @@ declare module '*.png' { } declare module '*.svg' { - const value: any; - export = value; + import * as React from 'react'; + const ReactComponent: React.FunctionComponent & { title?: string }>; + export default ReactComponent; } diff --git a/webpack.config.ts b/webpack.config.ts index 1a7991227..6c0996c4b 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -73,7 +73,20 @@ const config: Configuration = { use: ['style-loader', 'css-loader'], }, { - test: /\.(png|jpg|jpeg|gif|svg|woff2?|ttf|eot|otf)(\?.*$|$)/, + test: /\.svg$/, + issuer: /\.[jt]sx?$/, + use: [ + { + loader: '@svgr/webpack', + options: { + typescript: true, + ext: 'tsx', + }, + }, + ], + }, + { + test: /\.(png|jpg|jpeg|gif|woff2?|ttf|eot|otf)(\?.*$|$)/, loader: 'file-loader', options: { name: 'assets/[name].[ext]', diff --git a/yarn.lock b/yarn.lock index a69680a9f..ea4de2418 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,11 +18,208 @@ js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" + integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== + +"@babel/core@^7.21.3": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322" + integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.28.6" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" + integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== + dependencies: + "@babel/types" "^7.27.3" + +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" + integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== + dependencies: + "@babel/compat-data" "^7.28.6" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz#611ff5482da9ef0db6291bcd24303400bca170fb" + integrity sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.28.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1", "@babel/helper-create-regexp-features-plugin@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" + integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + regexpu-core "^6.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz#714dfe33d8bd710f556df59953720f6eeb6c1a14" + integrity sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA== + dependencies: + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + debug "^4.4.3" + lodash.debounce "^4.0.8" + resolve "^1.22.11" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== + dependencies: + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" + +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + +"@babel/helper-optimise-call-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" + integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== + dependencies: + "@babel/types" "^7.27.1" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + +"@babel/helper-remap-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" + integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-wrap-function" "^7.27.1" + "@babel/traverse" "^7.27.1" + +"@babel/helper-replace-supers@^7.27.1", "@babel/helper-replace-supers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz#94aa9a1d7423a00aead3f204f78834ce7d53fe44" + integrity sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.28.6" + +"@babel/helper-skip-transparent-expression-wrappers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" + integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helper-wrap-function@^7.27.1": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz#4e349ff9222dab69a93a019cc296cdd8442e279a" + integrity sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ== + dependencies: + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helpers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7" + integrity sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw== + dependencies: + "@babel/template" "^7.28.6" + "@babel/types" "^7.28.6" + "@babel/highlight@^7.10.4": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.9.tgz#8141ce68fc73757946f983b343f1231f4691acc6" @@ -33,6 +230,649 @@ js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" + integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== + dependencies: + "@babel/types" "^7.29.0" + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" + integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" + integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" + integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz#0e8289cec28baaf05d54fd08d81ae3676065f69f" + integrity sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/traverse" "^7.28.6" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-syntax-import-assertions@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz#ae9bc1923a6ba527b70104dd2191b0cd872c8507" + integrity sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-import-attributes@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz#b71d5914665f60124e133696f17cd7669062c503" + integrity sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-jsx@^7.27.1", "@babel/plugin-syntax-jsx@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz#f8ca28bbd84883b5fea0e447c635b81ba73997ee" + integrity sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-typescript@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz#c7b2ddf1d0a811145b1de800d1abd146af92e3a2" + integrity sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" + integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-async-generator-functions@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz#63ed829820298f0bf143d5a4a68fb8c06ffd742f" + integrity sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-remap-async-to-generator" "^7.27.1" + "@babel/traverse" "^7.29.0" + +"@babel/plugin-transform-async-to-generator@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz#bd97b42237b2d1bc90d74bcb486c39be5b4d7e77" + integrity sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-remap-async-to-generator" "^7.27.1" + +"@babel/plugin-transform-block-scoped-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" + integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-block-scoping@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz#e1ef5633448c24e76346125c2534eeb359699a99" + integrity sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-class-properties@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz#d274a4478b6e782d9ea987fda09bdb6d28d66b72" + integrity sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-class-static-block@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz#1257491e8259c6d125ac4d9a6f39f9d2bf3dba70" + integrity sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-classes@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz#8f6fb79ba3703978e701ce2a97e373aae7dda4b7" + integrity sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-globals" "^7.28.0" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-replace-supers" "^7.28.6" + "@babel/traverse" "^7.28.6" + +"@babel/plugin-transform-computed-properties@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz#936824fc71c26cb5c433485776d79c8e7b0202d2" + integrity sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/template" "^7.28.6" + +"@babel/plugin-transform-destructuring@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" + +"@babel/plugin-transform-dotall-regex@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz#def31ed84e0fb6e25c71e53c124e7b76a4ab8e61" + integrity sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-duplicate-keys@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" + integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz#8014b8a6cfd0e7b92762724443bf0d2400f26df1" + integrity sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-dynamic-import@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" + integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-explicit-resource-management@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz#dd6788f982c8b77e86779d1d029591e39d9d8be7" + integrity sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/plugin-transform-destructuring" "^7.28.5" + +"@babel/plugin-transform-exponentiation-operator@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz#5e477eb7eafaf2ab5537a04aaafcf37e2d7f1091" + integrity sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-export-namespace-from@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" + integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-for-of@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" + integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + +"@babel/plugin-transform-function-name@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" + integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== + dependencies: + "@babel/helper-compilation-targets" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" + +"@babel/plugin-transform-json-strings@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz#4c8c15b2dc49e285d110a4cf3dac52fd2dfc3038" + integrity sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" + integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-logical-assignment-operators@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz#53028a3d77e33c50ef30a8fce5ca17065936e605" + integrity sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-member-expression-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" + integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-modules-amd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" + integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== + dependencies: + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-modules-commonjs@^7.27.1", "@babel/plugin-transform-modules-commonjs@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz#c0232e0dfe66a734cc4ad0d5e75fc3321b6fdef1" + integrity sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA== + dependencies: + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-modules-systemjs@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz#e458a95a17807c415924106a3ff188a3b8dee964" + integrity sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ== + dependencies: + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.29.0" + +"@babel/plugin-transform-modules-umd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" + integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== + dependencies: + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz#a26cd51e09c4718588fc4cce1c5d1c0152102d6a" + integrity sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-new-target@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" + integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz#9bc62096e90ab7a887f3ca9c469f6adec5679757" + integrity sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-numeric-separator@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz#1310b0292762e7a4a335df5f580c3320ee7d9e9f" + integrity sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-object-rest-spread@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz#fdd4bc2d72480db6ca42aed5c051f148d7b067f7" + integrity sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA== + dependencies: + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/plugin-transform-destructuring" "^7.28.5" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/traverse" "^7.28.6" + +"@babel/plugin-transform-object-super@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" + integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + +"@babel/plugin-transform-optional-catch-binding@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz#75107be14c78385978201a49c86414a150a20b4c" + integrity sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz#926cf150bd421fc8362753e911b4a1b1ce4356cd" + integrity sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + +"@babel/plugin-transform-parameters@^7.27.7": + version "7.27.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" + integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-private-methods@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz#c76fbfef3b86c775db7f7c106fff544610bdb411" + integrity sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-private-property-in-object@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz#4fafef1e13129d79f1d75ac180c52aafefdb2811" + integrity sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-property-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" + integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-react-constant-elements@^7.21.3": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz#6c6b50424e749a6e48afd14cf7b92f98cb9383f9" + integrity sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-react-display-name@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-react-jsx-development@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" + integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.27.1" + +"@babel/plugin-transform-react-jsx@^7.27.1": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz#f51cb70a90b9529fbb71ee1f75ea27b7078eed62" + integrity sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/plugin-syntax-jsx" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/plugin-transform-react-pure-annotations@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" + integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-regenerator@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz#dec237cec1b93330876d6da9992c4abd42c9d18b" + integrity sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-regexp-modifiers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz#7ef0163bd8b4a610481b2509c58cf217f065290b" + integrity sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-reserved-words@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" + integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-shorthand-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" + integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-spread@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz#40a2b423f6db7b70f043ad027a58bcb44a9757b6" + integrity sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + +"@babel/plugin-transform-sticky-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" + integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-template-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" + integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typeof-symbol@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" + integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz#1e93d96da8adbefdfdade1d4956f73afa201a158" + integrity sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.28.6" + +"@babel/plugin-transform-unicode-escapes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" + integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-property-regex@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz#63a7a6c21a0e75dae9b1861454111ea5caa22821" + integrity sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/plugin-transform-unicode-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" + integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-sets-regex@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz#924912914e5df9fe615ec472f88ff4788ce04d4e" + integrity sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.28.6" + +"@babel/preset-env@^7.20.2": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.0.tgz#c55db400c515a303662faaefd2d87e796efa08d0" + integrity sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w== + dependencies: + "@babel/compat-data" "^7.29.0" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.6" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions" "^7.28.6" + "@babel/plugin-syntax-import-attributes" "^7.28.6" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.27.1" + "@babel/plugin-transform-async-generator-functions" "^7.29.0" + "@babel/plugin-transform-async-to-generator" "^7.28.6" + "@babel/plugin-transform-block-scoped-functions" "^7.27.1" + "@babel/plugin-transform-block-scoping" "^7.28.6" + "@babel/plugin-transform-class-properties" "^7.28.6" + "@babel/plugin-transform-class-static-block" "^7.28.6" + "@babel/plugin-transform-classes" "^7.28.6" + "@babel/plugin-transform-computed-properties" "^7.28.6" + "@babel/plugin-transform-destructuring" "^7.28.5" + "@babel/plugin-transform-dotall-regex" "^7.28.6" + "@babel/plugin-transform-duplicate-keys" "^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.29.0" + "@babel/plugin-transform-dynamic-import" "^7.27.1" + "@babel/plugin-transform-explicit-resource-management" "^7.28.6" + "@babel/plugin-transform-exponentiation-operator" "^7.28.6" + "@babel/plugin-transform-export-namespace-from" "^7.27.1" + "@babel/plugin-transform-for-of" "^7.27.1" + "@babel/plugin-transform-function-name" "^7.27.1" + "@babel/plugin-transform-json-strings" "^7.28.6" + "@babel/plugin-transform-literals" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.28.6" + "@babel/plugin-transform-member-expression-literals" "^7.27.1" + "@babel/plugin-transform-modules-amd" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.28.6" + "@babel/plugin-transform-modules-systemjs" "^7.29.0" + "@babel/plugin-transform-modules-umd" "^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.29.0" + "@babel/plugin-transform-new-target" "^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.28.6" + "@babel/plugin-transform-numeric-separator" "^7.28.6" + "@babel/plugin-transform-object-rest-spread" "^7.28.6" + "@babel/plugin-transform-object-super" "^7.27.1" + "@babel/plugin-transform-optional-catch-binding" "^7.28.6" + "@babel/plugin-transform-optional-chaining" "^7.28.6" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/plugin-transform-private-methods" "^7.28.6" + "@babel/plugin-transform-private-property-in-object" "^7.28.6" + "@babel/plugin-transform-property-literals" "^7.27.1" + "@babel/plugin-transform-regenerator" "^7.29.0" + "@babel/plugin-transform-regexp-modifiers" "^7.28.6" + "@babel/plugin-transform-reserved-words" "^7.27.1" + "@babel/plugin-transform-shorthand-properties" "^7.27.1" + "@babel/plugin-transform-spread" "^7.28.6" + "@babel/plugin-transform-sticky-regex" "^7.27.1" + "@babel/plugin-transform-template-literals" "^7.27.1" + "@babel/plugin-transform-typeof-symbol" "^7.27.1" + "@babel/plugin-transform-unicode-escapes" "^7.27.1" + "@babel/plugin-transform-unicode-property-regex" "^7.28.6" + "@babel/plugin-transform-unicode-regex" "^7.27.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.28.6" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.15" + babel-plugin-polyfill-corejs3 "^0.14.0" + babel-plugin-polyfill-regenerator "^0.6.6" + core-js-compat "^3.48.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.18.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" + integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-transform-react-display-name" "^7.28.0" + "@babel/plugin-transform-react-jsx" "^7.27.1" + "@babel/plugin-transform-react-jsx-development" "^7.27.1" + "@babel/plugin-transform-react-pure-annotations" "^7.27.1" + +"@babel/preset-typescript@^7.21.0": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" + "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.14.5", "@babel/runtime@^7.7.6": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" @@ -57,6 +897,36 @@ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.2.tgz#2ae5a9d51cc583bd1f5673b3bb70d6d819682473" integrity sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA== +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + +"@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.4.4": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -71,11 +941,23 @@ dependencies: "@dagrejs/graphlib" "2.2.2" +"@dagrejs/dagre@^1.1.8": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.8.tgz#fcbee59344c7b4f48b711ba30783543b70029310" + integrity sha512-5SEDlndt4W/LaVzPYJW+bSmSEZc9EzTf8rJ20WCKvjS5EAZAN0b+x0Yww7VMT4R3Wootkg+X9bUfUxazYw6Blw== + dependencies: + "@dagrejs/graphlib" "2.2.4" + "@dagrejs/graphlib@2.2.2": version "2.2.2" resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.2.tgz#74154d5cb880a23b4fae71034a09b4b5aef06feb" integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg== +"@dagrejs/graphlib@2.2.4": + version "2.2.4" + resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.4.tgz#d77bfa9ff49e2307c0c6e6b8b26b5dd3c05816c4" + integrity sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw== + "@discoveryjs/json-ext@^0.5.0": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -143,6 +1025,14 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@jridgewell/gen-mapping@^0.3.12": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" @@ -152,6 +1042,14 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -175,6 +1073,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -191,6 +1094,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@jsonjoy.com/base64@^1.1.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578" @@ -397,7 +1308,7 @@ "@parcel/watcher-win32-ia32" "2.5.0" "@parcel/watcher-win32-x64" "2.5.0" -"@patternfly/quickstarts@^6.2.0": +"@patternfly/quickstarts@^6.4.0": version "6.4.0" resolved "https://registry.yarnpkg.com/@patternfly/quickstarts/-/quickstarts-6.4.0.tgz#01c47c68baefa950c840fd3e0650b50bec5c6b91" integrity sha512-A9XMlhY9aUhPT5+KVHOL8mxfXYNVQAhMRB4LWTd7vT9tby3mPfGcayrm9saW6CNCjSpgKpEvfsX+dcKsCccAaA== @@ -405,15 +1316,15 @@ dompurify "^3.2.4" history "^5.0.0" -"@patternfly/react-charts@^8.2.0": - version "8.4.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-8.4.0.tgz#2671542c91c714ecbec03798cfb2adab81bd44af" - integrity sha512-lxfH2gVDg4Pd+D6TQ2SSqc5fQPk1UvhHbuP+7YZJdPhk2PzhhbaT3CE+kp5ZEU2y/lJb8L5kZ5lOk8tvPn6PQw== +"@patternfly/react-charts@^8.4.0": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@patternfly/react-charts/-/react-charts-8.4.1.tgz#93e9cd1c50f3e950bc02dc55b93ec19e65b989ea" + integrity sha512-kqP5TFr9F/SDTp+nXfcX8gMuZIQ6Uxl55qqiWYgR2zflo0UZWnyL/d2s1fI6Bfi5IuycNdlvJJ/i8QdOsLr5mw== dependencies: "@patternfly/react-styles" "^6.4.0" "@patternfly/react-tokens" "^6.4.0" hoist-non-react-statics "^3.3.2" - lodash "^4.17.21" + lodash "^4.17.23" tslib "^2.8.1" "@patternfly/react-component-groups@^6.1.0": @@ -439,18 +1350,6 @@ react-dropzone "^14.3.5" tslib "^2.8.1" -"@patternfly/react-core@^6.2.0", "@patternfly/react-core@^6.2.2": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-6.4.0.tgz#a2c0b60c1a4f34f708d079e92e86b007b0c88c3c" - integrity sha512-zMgJmcFohp2FqgAoZHg7EXZS7gnaFESquk0qIavemYI0FsqspVlzV2/PUru7w+86+jXfqebRhgubPRsv1eJwEg== - dependencies: - "@patternfly/react-icons" "^6.4.0" - "@patternfly/react-styles" "^6.4.0" - "@patternfly/react-tokens" "^6.4.0" - focus-trap "7.6.4" - react-dropzone "^14.3.5" - tslib "^2.8.1" - "@patternfly/react-core@^6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-6.3.0.tgz#cf1002e38741ecf12bd8ba24e57618a513212e62" @@ -463,15 +1362,27 @@ react-dropzone "^14.3.5" tslib "^2.8.1" -"@patternfly/react-data-view@^6.2.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-data-view/-/react-data-view-6.3.0.tgz#28b80d95f8c72c6c51e2f9adb061206012f8c737" - integrity sha512-0bdJl/BWDYmHQH8CyLoI59FTYVnEQ3e50ero8RvCYe+k5qnX1t/1KC/bJWosIxGROUBNtOWn6OEOKzfd8+BCTQ== +"@patternfly/react-core@^6.4.0", "@patternfly/react-core@^6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-6.4.1.tgz#219afce931b49804903f2e12156f9bb4d46f91b7" + integrity sha512-EUSV76Eifkt4R3q2JIaiB6/FHeQqOCttK1DQMXNoOCNa3ODkZ7H+KlMdminufMDfRzhwAgTVihZ62K9PFfc8Vg== + dependencies: + "@patternfly/react-icons" "^6.4.0" + "@patternfly/react-styles" "^6.4.0" + "@patternfly/react-tokens" "^6.4.0" + focus-trap "7.6.4" + react-dropzone "^14.3.5" + tslib "^2.8.1" + +"@patternfly/react-data-view@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-data-view/-/react-data-view-6.4.0.tgz#0f89c28b74f7a755fa2837c2087772b20fde4d10" + integrity sha512-AYIJvWLSoZaf3askvBjyyFQEvSCiquw5PFzEOiTsNoM2pDYkRagzppjclpI+MRJr44ZrfpljC6ZKE4f5Ni2p+w== dependencies: "@patternfly/react-component-groups" "^6.1.0" - "@patternfly/react-core" "^6.0.0" - "@patternfly/react-icons" "^6.0.0" - "@patternfly/react-table" "^6.0.0" + "@patternfly/react-core" "^6.4.0" + "@patternfly/react-icons" "^6.4.0" + "@patternfly/react-table" "^6.4.0" clsx "^2.1.1" react-jss "^10.10.0" @@ -480,11 +1391,6 @@ resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-6.1.0.tgz#4f982f2b8dc0b9366acca1170fcd52fa8c16b85f" integrity sha512-V1w/j19YmOgvh72IRRf1p07k+u4M5+9P+o/IxunlF0fWzLDX4Hf+utBI11A8cRfUzpQN7eLw/vZIS3BLM8Ge3Q== -"@patternfly/react-icons@^6.2.0", "@patternfly/react-icons@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-6.2.2.tgz#6b19359df7618ea4ec6aa6da3af2a9a287666f23" - integrity sha512-XkBwzuV/uiolX+T6QgB3RIqphM1m+vAZjAe3McYtyY22j1rsOdlWDE4RtRrJ1q7EoIZwyZHj0h8T9vMfUsLn4Q== - "@patternfly/react-icons@^6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-6.3.0.tgz#08bf0f05e06a367962b15f0810f20e45eb7c2ea0" @@ -500,11 +1406,6 @@ resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-6.1.0.tgz#e8aa12c6b1417ba1a739ea435bc02f7f8d516132" integrity sha512-JQ3zIl5SFiSB0YWVYibcUwgZdsp6Wn8hkfZ7KhtCjHFccSDdJexPOXVV1O9f2h4PfxTlY3YntZ81ZsguBx/Q7A== -"@patternfly/react-styles@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-6.2.2.tgz#ff6d31266ba03df9be8095f189d1399a8cc3b66d" - integrity sha512-rncRDq66H8VnLyb9DrHHlZtPddlpNL9+W0XuQC0L7F6p78hOwSZmoGTW2Vq8/wJplDj8h/61qRpfRF9VEYPW0g== - "@patternfly/react-styles@^6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-6.3.0.tgz#b32bf47c9688dd4e969c90bdd12eef8532616c22" @@ -527,43 +1428,33 @@ lodash "^4.17.21" tslib "^2.8.1" -"@patternfly/react-table@^6.2.0": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-6.2.2.tgz#9ca4f1b4e5558cafd712c66a599b097a475acb30" - integrity sha512-7CxVKhnpA+f8dLJ0hVvzZOe4Djx/nE+w70ipeAHf4Yi5JwfDWmbK97YvjYPfamp/bsXTLtPcK2n4AoY5DQX6Pg== +"@patternfly/react-table@^6.4.0": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-6.4.1.tgz#9074101de89d4c22abc49a7a90314cc9ffba2a71" + integrity sha512-dceS5X1I5gmhRfEf6gsLIdFhrQd5hY+SWRIYzEvI19rrdN9VwCVWg+bhSsNv05pQnGs8uOlzYVBI25p7PJtFeA== dependencies: - "@patternfly/react-core" "^6.2.2" - "@patternfly/react-icons" "^6.2.2" - "@patternfly/react-styles" "^6.2.2" - "@patternfly/react-tokens" "^6.2.2" - lodash "^4.17.21" + "@patternfly/react-core" "^6.4.1" + "@patternfly/react-icons" "^6.4.0" + "@patternfly/react-styles" "^6.4.0" + "@patternfly/react-tokens" "^6.4.0" + lodash "^4.17.23" tslib "^2.8.1" -"@patternfly/react-tokens@6.2.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.2.0.tgz#7535256d934a27ba6ba4a1f80588e244811e953b" - integrity sha512-KyzbsQYXTCxTmwkLlN4GdmTCNlOKnPUpY389loaC4/B0wHNq8Vw4OMIsAPVi4RSSvTaSxitlPAwt3xBTjNIzFA== +"@patternfly/react-tokens@6.4.0", "@patternfly/react-tokens@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.4.0.tgz#15e0deb5205db8322bed064958162fb98046966f" + integrity sha512-iZthBoXSGQ/+PfGTdPFJVulaJZI3rwE+7A/whOXPGp3Jyq3k6X52pr1+5nlO6WHasbZ9FyeZGqXf4fazUZNjbw== "@patternfly/react-tokens@^6.1.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.1.0.tgz#c2a64e68568bde81e56f4b5a8f9ac3ad8cd06e8a" integrity sha512-t1UcHbOa4txczTR5UlnG4XcAAdnDSfSlCaOddw/HTqRF59pn2ks2JUu9sfnFRZ8SiAAxKRiYdX5bT7Mf4R24+w== -"@patternfly/react-tokens@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.2.2.tgz#4ab12cf77fab60a730f52aed2433dbf892d47509" - integrity sha512-2GRWDPBTrcTlGNFc5NPJjrjEVU90RpgcGX/CIe2MplLgM32tpVIkeUtqIoJPLRk5GrbhyFuHJYRU+O93gU4o3Q== - "@patternfly/react-tokens@^6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.3.0.tgz#2d7173db1e26cf7b414dd569feb129a335ae5e17" integrity sha512-yWStfkbxg4RWAExFKS/JRGScyadOy35yr4DFispNeHrkZWMp4pwKf0VdwlQZ7+ZtSgEWtzzy1KFxMLmWh3mEqA== -"@patternfly/react-tokens@^6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-6.4.0.tgz#15e0deb5205db8322bed064958162fb98046966f" - integrity sha512-iZthBoXSGQ/+PfGTdPFJVulaJZI3rwE+7A/whOXPGp3Jyq3k6X52pr1+5nlO6WHasbZ9FyeZGqXf4fazUZNjbw== - "@patternfly/react-topology@^6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@patternfly/react-topology/-/react-topology-6.2.0.tgz#3a853731c6a3aa5b014596ec368cfc34fb0927b3" @@ -585,6 +1476,25 @@ tslib "^2.0.0" webcola "3.4.0" +"@patternfly/react-topology@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@patternfly/react-topology/-/react-topology-6.4.0.tgz#d5ddd2f76ee4c3b585462ec94cb533b16bf6be04" + integrity sha512-Uy2ofRnI0apYiPWUYIAlXifl+4QPx/sqsVku1WglCkqjMPwuR8vC/GTIJEq2qW7mucDAcWSTFAPc5+zqyPRrlQ== + dependencies: + "@dagrejs/dagre" "1.1.2" + "@patternfly/react-core" "^6.0.0" + "@patternfly/react-icons" "^6.0.0" + "@patternfly/react-styles" "^6.0.0" + "@types/d3" "^7.4.0" + "@types/d3-force" "^1.2.1" + d3 "^7.8.0" + mobx "^6.9.0" + mobx-react "^7.6.0" + point-in-svg-path "^1.0.1" + popper.js "^1.16.1" + tslib "^2.0.0" + webcola "3.4.0" + "@pkgr/core@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" @@ -605,6 +1515,117 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== +"@svgr/babel-plugin-add-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== + +"@svgr/babel-plugin-remove-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== + +"@svgr/babel-plugin-svg-dynamic-title@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== + +"@svgr/babel-plugin-svg-em-dimensions@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== + +"@svgr/babel-plugin-transform-react-native-svg@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== + +"@svgr/babel-plugin-transform-svg-component@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== + +"@svgr/babel-preset@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "8.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "8.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" + "@svgr/babel-plugin-transform-svg-component" "8.0.0" + +"@svgr/core@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + camelcase "^6.2.0" + cosmiconfig "^8.1.3" + snake-case "^3.0.4" + +"@svgr/hast-util-to-babel-ast@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== + dependencies: + "@babel/types" "^7.21.3" + entities "^4.4.0" + +"@svgr/plugin-jsx@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + "@svgr/hast-util-to-babel-ast" "8.0.0" + svg-parser "^2.0.4" + +"@svgr/plugin-svgo@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz#b115b7b967b564f89ac58feae89b88c3decd0f00" + integrity sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA== + dependencies: + cosmiconfig "^8.1.3" + deepmerge "^4.3.1" + svgo "^3.0.2" + +"@svgr/webpack@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-8.1.0.tgz#16f1b5346f102f89fda6ec7338b96a701d8be0c2" + integrity sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA== + dependencies: + "@babel/core" "^7.21.3" + "@babel/plugin-transform-react-constant-elements" "^7.21.3" + "@babel/preset-env" "^7.20.2" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.21.0" + "@svgr/core" "8.1.0" + "@svgr/plugin-jsx" "8.1.0" + "@svgr/plugin-svgo" "8.1.0" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -877,6 +1898,11 @@ "@types/d3-transition" "*" "@types/d3-zoom" "*" +"@types/dagre@^0.7.53": + version "0.7.53" + resolved "https://registry.yarnpkg.com/@types/dagre/-/dagre-0.7.53.tgz#4dab441bf31b6fb08af0b3e2a3f5ab0c0217a701" + integrity sha512-f4gkWqzPZvYmKhOsDnhq/R8mO4UMcKdxZo+i5SCkOU1wvGeHJeUXGIHeE9pnwGyPMDof1Vx5ZQo4nxpeg2TTVQ== + "@types/eslint-scope@^3.7.7": version "3.7.7" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" @@ -1888,6 +2914,30 @@ babel-plugin-jest-hoist@^21.2.0: resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006" integrity sha512-yi5QuiVyyvhBUDLP4ButAnhYzkdrUwWDtvUJv71hjH3fclhnZg4HkDeqaitcR2dZZx/E67kGkRcPVjtVu+SJfQ== +babel-plugin-polyfill-corejs2@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz#808fa349686eea4741807cfaaa2aa3aa57ce120a" + integrity sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw== + dependencies: + "@babel/compat-data" "^7.28.6" + "@babel/helper-define-polyfill-provider" "^0.6.6" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz#65b06cda48d6e447e1e926681f5a247c6ae2b9cf" + integrity sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.6" + core-js-compat "^3.48.0" + +babel-plugin-polyfill-regenerator@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz#69f5dd263cab933c42fe5ea05e83443b374bd4bf" + integrity sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.6" + babel-plugin-syntax-object-rest-spread@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -1981,6 +3031,11 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + basic-auth@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884" @@ -2135,6 +3190,17 @@ browserslist@^4.24.0: node-releases "^2.0.19" update-browserslist-db "^1.1.3" +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -2225,11 +3291,21 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-lite@^1.0.30001716: version "1.0.30001718" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz#dae13a9c80d517c30c6197515a96131c194d8f82" integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== + capture-exit@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" @@ -2447,7 +3523,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@7, commander@^7.0.0, commander@~7.2.0: +commander@7, commander@^7.0.0, commander@^7.2.0, commander@~7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -2545,6 +3621,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -2572,6 +3653,13 @@ copy-webpack-plugin@12.0.2: schema-utils "^4.2.0" serialize-javascript "^6.0.2" +core-js-compat@^3.48.0: + version "3.48.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.48.0.tgz#7efbe1fc1cbad44008190462217cc5558adaeaa6" + integrity sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q== + dependencies: + browserslist "^4.28.1" + core-js@^2.4.0, core-js@^2.5.0: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -2592,6 +3680,16 @@ corser@^2.0.1: resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" integrity sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ== +cosmiconfig@^8.1.3: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -2651,6 +3749,22 @@ css-select@^5.1.0: domutils "^3.0.1" nth-check "^2.0.1" +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + css-vendor@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" @@ -2669,6 +3783,13 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +csso@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -2965,6 +4086,14 @@ d3@^7.8.0: d3-transition "3" d3-zoom "3" +dagre@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" + integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== + dependencies: + graphlib "^2.1.8" + lodash "^4.17.15" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3025,6 +4154,13 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.4, debug@^4.3.5, debug@^4.3 dependencies: ms "^2.1.3" +debug@^4.3.1, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3040,7 +4176,7 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^4.2.2: +deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -3241,6 +4377,14 @@ domutils@^3.0.1, domutils@^3.1.0: domelementtype "^2.3.0" domhandler "^5.0.3" +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + dunder-proto@^1.0.0, dunder-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" @@ -3288,6 +4432,11 @@ electron-to-chromium@^1.5.149: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.154.tgz#82430d66848efef703a3b643fb2a682bd08ae26b" integrity sha512-G4VCFAyKbp1QJ+sWdXYIRYsPGvlV5sDACfCmoMFog3rjm1syLhI41WXm/swZypwCIWIm4IFLWzHY14joWMQ5Fw== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4359,6 +5508,11 @@ generator-function@^2.0.0: resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2" integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -4546,6 +5700,13 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== + dependencies: + lodash "^4.17.15" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -4968,6 +6129,14 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-fresh@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-local@^3.0.2: version "3.2.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" @@ -5126,7 +6295,7 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" -is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.16.0: +is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.16.0, is-core-module@^2.16.1: version "2.16.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== @@ -5903,6 +7072,13 @@ js-yaml@^3.13.1, js-yaml@^3.7.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5943,6 +7119,11 @@ jsesc@^1.3.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== +jsesc@^3.0.2, jsesc@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -6001,7 +7182,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -6317,10 +7498,15 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash-es@^4.17.21, lodash-es@^4.17.23: + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.23.tgz#58c4360fd1b5d33afc6c0bbd3d1149349b1138e0" + integrity sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg== + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.merge@^4.6.2: version "4.6.2" @@ -6332,10 +7518,10 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.17.14, lodash@^4.17.21, lodash@^4.17.4: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.23, lodash@^4.17.4: + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" + integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" @@ -6344,6 +7530,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3 dependencies: js-tokens "^3.0.0 || ^4.0.0" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -6352,6 +7545,13 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -6406,6 +7606,16 @@ math-random@^1.0.1: resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6667,6 +7877,14 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + node-addon-api@^7.0.0: version "7.1.1" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" @@ -6698,6 +7916,11 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -7071,7 +8294,7 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -7811,6 +9034,18 @@ reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: get-proto "^1.0.1" which-builtin-type "^1.2.1" +regenerate-unicode-properties@^10.2.2: + version "10.2.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz#aa113812ba899b630658c7623466be71e1f86f66" + integrity sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" @@ -7853,6 +9088,30 @@ regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +regexpu-core@^6.3.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" + integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.2" + regjsgen "^0.8.0" + regjsparser "^0.13.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.2.1" + +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" + integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== + dependencies: + jsesc "~3.1.0" + remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -8001,6 +9260,15 @@ resolve@^1.10.0, resolve@^1.22.0, resolve@^1.22.4, resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.11: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^2.0.0-next.5: version "2.0.0-next.5" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" @@ -8488,6 +9756,14 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -8527,7 +9803,7 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.1: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -8899,6 +10175,24 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^3.0.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.2.tgz#ad58002652dffbb5986fc9716afe52d869ecbda8" + integrity sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.3.1" + css-what "^6.1.0" + csso "^5.0.5" + picocolors "^1.0.0" + symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -9201,7 +10495,7 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.6.2, tslib@^2.7.0, tslib@^2.8.1: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.2, tslib@^2.7.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -9365,6 +10659,29 @@ undici@^6.19.5: resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.1.tgz#336025a14162e6837e44ad7b819b35b6c6af0e05" integrity sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz#65a7adfad8574c219890e219285ce4c64ed67eaa" + integrity sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz#301d4f8a43d2b75c97adfad87c9dd5350c9475d1" + integrity sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ== + unicorn-magic@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" @@ -9426,6 +10743,14 @@ update-browserslist-db@^1.1.3: escalade "^3.2.0" picocolors "^1.1.1" +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -9967,6 +11292,11 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From 7ab82035c9257bc8828a22a3237733d0dc8f5dfb Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Tue, 17 Feb 2026 17:08:09 -0500 Subject: [PATCH 2/2] Changes based on Atif's review; Update SDK version Signed-off-by: Keith Chong --- package.json | 6 ++--- src/gitops/Statuses/SyncStatus.tsx | 5 +--- .../graph/ApplicationGraphView.tsx | 12 ++++++--- .../application/graph/graph-utils.tsx | 6 ++--- .../graph/nodes/ApplicationNode.tsx | 1 + .../graph/nodes/ResourceGroupNode.tsx | 4 +-- yarn.lock | 25 +++++++++---------- 7 files changed, 31 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 6aa7453d3..6fda10701 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,9 @@ }, "devDependencies": { "@dagrejs/dagre": "^1.1.8", - "@openshift-console/dynamic-plugin-sdk": "^4.19.0-prerelease.2", - "@openshift-console/dynamic-plugin-sdk-internal": "^4.19.0-prerelease.2", - "@openshift-console/dynamic-plugin-sdk-webpack": "^4.19.0-prerelease.2", + "@openshift-console/dynamic-plugin-sdk": "^4.19.1", + "@openshift-console/dynamic-plugin-sdk-internal": "^4.19.1", + "@openshift-console/dynamic-plugin-sdk-webpack": "^4.19.1", "@openshift-console/plugin-shared": "^0.0.3", "@patternfly/quickstarts": "^6.4.0", "@patternfly/react-charts": "^8.4.0", diff --git a/src/gitops/Statuses/SyncStatus.tsx b/src/gitops/Statuses/SyncStatus.tsx index 0727368d4..8e5901cb3 100644 --- a/src/gitops/Statuses/SyncStatus.tsx +++ b/src/gitops/Statuses/SyncStatus.tsx @@ -1,8 +1,5 @@ import * as React from 'react'; -import { - OutOfSyncIcon, - SyncUnknownIcon, -} from 'src/gitops/utils/components/Icons/Icons'; +import { OutOfSyncIcon, SyncUnknownIcon } from 'src/gitops/utils/components/Icons/Icons'; import { SyncStatus as SS } from 'src/gitops/utils/constants'; import { GreenCheckCircleIcon } from '@openshift-console/dynamic-plugin-sdk'; diff --git a/src/gitops/components/application/graph/ApplicationGraphView.tsx b/src/gitops/components/application/graph/ApplicationGraphView.tsx index 7fe8201b7..f44342ef8 100644 --- a/src/gitops/components/application/graph/ApplicationGraphView.tsx +++ b/src/gitops/components/application/graph/ApplicationGraphView.tsx @@ -198,8 +198,14 @@ const customComponentFactory = } else if (label === t('Delete Application')) { launchDeleteModal(); } else if ( - label === 'Show ' + graphElement.getData().kindPlural || - label === 'Hide ' + graphElement.getData().kindPlural + label === + t('Show {{x}}', { + x: graphElement.getData().kindPlural, + }) || + label === + t('Hide {{x}}', { + x: graphElement.getData().kindPlural, + }) ) { const key = graphElement.getData().kindPlural; setGroupNodeStates((prev) => { @@ -382,7 +388,7 @@ export const ApplicationGraphView: React.FC<{ graph: { id: 'g1', type: 'graph', - layout: 'PipleineDagreLayout', + layout: 'Dagre', }, }; diff --git a/src/gitops/components/application/graph/graph-utils.tsx b/src/gitops/components/application/graph/graph-utils.tsx index 28e742f19..08fe1aa1a 100644 --- a/src/gitops/components/application/graph/graph-utils.tsx +++ b/src/gitops/components/application/graph/graph-utils.tsx @@ -64,7 +64,7 @@ const createApplicationNode = (application: ApplicationKind): NodeModel => { ), rank: 0, nodeStatus: nodeStatus, - reourceHealthStatus: application?.status?.health?.status, + resourceHealthStatus: application?.status?.health?.status, appHealthStatus: application?.status?.health?.status, syncStatus: application?.status?.sync?.status, }, @@ -304,14 +304,14 @@ export const getInitialNodes = ( // Spacer node to the right of the application node. Fixed. initialNodes.push(createSpacerNode(1, 'application-node-spacer')); // Add child resources - resources.forEach((resource, count) => { + resources.forEach((resource) => { const kind = resource.kind; const badgeLabel = allK8sModels[kind]?.abbr || kindToAbbr(kind); const color = RESOURCE_COLORS.get( RESOURCE_BADGE_COLORS.get('.co-m-resource-' + resource.kind.toLowerCase()), ) || RESOURCE_COLORS.get('color-container-dark'); - const nodeId = count + '-' + resource.kind + '-' + resource.name + '-' + resource.namespace; + const nodeId = resource.kind + '-' + resource.name + '-' + resource.namespace; const key = resource.kind + 's'; const resourceGroupExpandState = groupNodeStates.includes(key); diff --git a/src/gitops/components/application/graph/nodes/ApplicationNode.tsx b/src/gitops/components/application/graph/nodes/ApplicationNode.tsx index 9df3b4411..1e795f7d3 100644 --- a/src/gitops/components/application/graph/nodes/ApplicationNode.tsx +++ b/src/gitops/components/application/graph/nodes/ApplicationNode.tsx @@ -93,6 +93,7 @@ const ApplicationSyncStatusIcon = ({ status }: { status: SyncStatus }) => { ); break; case SyncStatus.UNKNOWN: + default: icon = ( - ) : data.hasMissing ? ( - ) : data.hasDegraded ? ( + ) : data.hasMissing ? ( + ) : data.hasSuspended ? ( ) : data.hasUnknown ? ( diff --git a/yarn.lock b/yarn.lock index ea4de2418..3e905378b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1148,10 +1148,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@openshift-console/dynamic-plugin-sdk-internal@^4.19.0-prerelease.2": - version "4.19.0" - resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk-internal/-/dynamic-plugin-sdk-internal-4.19.0.tgz#df9ec5191d002f57250064c40bda6b8f0528bad9" - integrity sha512-OnC/2CV/oejtOzXQujYk/0JGSPuFjR6F51KsKKPelX9KqF+A2G2GW/yESR3n/FkGMtXxl6ZCUXUBCDMLXVRH/g== +"@openshift-console/dynamic-plugin-sdk-internal@^4.19.1": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk-internal/-/dynamic-plugin-sdk-internal-4.20.0.tgz#938702cf6e79dbf732dddb98a24c22680a0b049c" + integrity sha512-QEV0XiydJBA33gtVz1g92HLTvG1n99igQ3FR+UBr+ufzl3DvW0hwXH+EZgskff3WBVnEHWlOAI2SGy8ujdfdjg== dependencies: "@patternfly/react-topology" "^6.2.0" immutable "3.x" @@ -1164,10 +1164,10 @@ redux "4.0.1" redux-thunk "2.4.0" -"@openshift-console/dynamic-plugin-sdk-webpack@^4.19.0-prerelease.2": - version "4.19.0" - resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk-webpack/-/dynamic-plugin-sdk-webpack-4.19.0.tgz#6a0171702d9089f6cbe6cb74665ea855bb42af7e" - integrity sha512-a4zxkrEe4qhKir5R21OK/wJVCn8Gzm/y3smLxRDi/BjHFgcnNQKEgCMP4IhvTlT0NRJQ4Q9AmPT1WXBlV3ip3g== +"@openshift-console/dynamic-plugin-sdk-webpack@^4.19.1": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk-webpack/-/dynamic-plugin-sdk-webpack-4.20.0.tgz#5b42772625bf44fc3faf76ecf94b5223ed3e6644" + integrity sha512-cTpBy8Jz2C65Qy/3fXIRv8IehvKRkms8rMcjz0KGo7DRoaDPnSyMXi5gH0BIA01nr5U6sBncNSbaD/3PXaZaig== dependencies: "@openshift/dynamic-plugin-sdk-webpack" "^4.0.2" ajv "^6.12.3" @@ -1180,13 +1180,12 @@ semver "6.x" webpack "^5.75.0" -"@openshift-console/dynamic-plugin-sdk@^4.19.0-prerelease.2": - version "4.19.0" - resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk/-/dynamic-plugin-sdk-4.19.0.tgz#c9b6c1338b14c174520bff827f4e2be5ab2290a4" - integrity sha512-v1pNt2eDCyXwRZX+66QDnaYtrwbLapRMtCQql65pgePsE5/5aoOSGIsTjIB812j+oagAB1yk4r7OUlopA2F8kw== +"@openshift-console/dynamic-plugin-sdk@^4.19.1": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@openshift-console/dynamic-plugin-sdk/-/dynamic-plugin-sdk-4.20.0.tgz#f5e6aaa147f02f651e3e6a734a1fb55555bad56a" + integrity sha512-Rf6XfWweXccmz10UpBT0tJTXBDf6jqRaiwQjzXGJ4W+ewVh5BQwxXIeBwzxjuAr3Bt972MhIqksHrlh54moERA== dependencies: "@patternfly/react-topology" "^6.2.0" - classnames "2.x" immutable "3.x" lodash "^4.17.21" react "^17.0.1"