dashboard-shell-shell 3.0.2-test.20250913 → 3.0.5-test.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/data/aws-regions.json +3 -0
- package/assets/icons/demo.css:Zone.Identifier +0 -0
- package/assets/icons/demo_index.html:Zone.Identifier +0 -0
- package/assets/icons/iconfont.css:Zone.Identifier +0 -0
- package/assets/icons/iconfont.js:Zone.Identifier +0 -0
- package/assets/icons/iconfont.json:Zone.Identifier +0 -0
- package/assets/icons/iconfont.ttf:Zone.Identifier +0 -0
- package/assets/icons/iconfont.woff2:Zone.Identifier +0 -0
- package/assets/icons/iconfont.woff:Zone.Identifier +0 -0
- package/assets/images/icons/document.svg +3 -0
- package/assets/images/key.svg +17 -0
- package/assets/images/providers/sks.svg +1 -0
- package/assets/images/vendor/cognito.svg +1 -0
- package/assets/styles/app.scss +3 -0
- package/assets/styles/base/_basic.scss +10 -0
- package/assets/styles/base/_spacing.scss +29 -0
- package/assets/styles/base/_variables.scss +16 -10
- package/assets/styles/global/_labeled-input.scss +1 -1
- package/assets/styles/global/_layout.scss +1 -1
- package/assets/styles/themes/_dark.scss +30 -0
- package/assets/styles/themes/_light.scss +80 -2
- package/assets/translations/en-us.yaml +822 -105
- package/assets/translations/zh-hans.yaml +13 -3
- package/chart/__tests__/S3.test.ts +2 -1
- package/chart/monitoring/index.vue +1 -1
- package/cloud-credential/gcp.vue +9 -1
- package/components/ActionMenuShell.vue +3 -7
- package/components/AppModal.vue +9 -28
- package/components/AsyncButton.vue +2 -0
- package/components/BrandImage.vue +0 -21
- package/components/Certificates.vue +5 -0
- package/components/CodeMirror.vue +3 -3
- package/components/CommunityLinks.vue +3 -58
- package/components/ConfigMapSettings/Settings.vue +377 -0
- package/components/ConfigMapSettings/index.vue +354 -0
- package/components/CruResource.vue +103 -16
- package/components/DetailText.vue +61 -11
- package/components/Drawer/Chrome.vue +115 -0
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
- package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +106 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
- package/components/Drawer/ResourceDetailDrawer/composables.ts +53 -0
- package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
- package/components/Drawer/ResourceDetailDrawer/index.vue +123 -0
- package/components/ExplorerProjectsNamespaces.vue +46 -29
- package/components/FilterPanel.vue +156 -0
- package/components/FixedBanner.vue +19 -5
- package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
- package/components/GrowlManager.vue +16 -15
- package/components/IconOrSvg.vue +19 -35
- package/components/KeyValueView.vue +1 -1
- package/components/LandingPagePreference.vue +2 -0
- package/components/Loading.vue +1 -1
- package/components/LocaleSelector.vue +10 -2
- package/components/PaginatedResourceTable.vue +53 -1
- package/components/ProgressBarMulti.vue +1 -0
- package/components/PromptModal.vue +38 -7
- package/components/PromptRemove.vue +5 -1
- package/components/PromptRestore.vue +22 -44
- package/components/RelatedResources.vue +4 -12
- package/components/Resource/Detail/Additional.vue +46 -0
- package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
- package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
- package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
- package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
- package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
- package/components/Resource/Detail/Card/Scaler.vue +89 -0
- package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
- package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
- package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
- package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
- package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
- package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
- package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
- package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
- package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
- package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
- package/components/Resource/Detail/Card/index.vue +56 -0
- package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
- package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
- package/components/Resource/Detail/Metadata/Annotations/index.vue +31 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +72 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +317 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +140 -0
- package/components/Resource/Detail/Metadata/KeyValue.vue +140 -0
- package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
- package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
- package/components/Resource/Detail/Metadata/Labels/index.vue +31 -0
- package/components/Resource/Detail/Metadata/Rectangle.vue +34 -0
- package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
- package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
- package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
- package/components/Resource/Detail/Metadata/composables.ts +81 -0
- package/components/Resource/Detail/Metadata/index.vue +88 -0
- package/components/Resource/Detail/Page.vue +37 -0
- package/components/Resource/Detail/PercentageBar.vue +40 -0
- package/components/Resource/Detail/ResourceRow.vue +138 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
- package/components/Resource/Detail/SpacedRow.vue +14 -0
- package/components/Resource/Detail/StatusBar.vue +59 -0
- package/components/Resource/Detail/StatusRow.vue +61 -0
- package/components/Resource/Detail/TitleBar/Title.vue +14 -0
- package/components/Resource/Detail/TitleBar/Top.vue +14 -0
- package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
- package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
- package/components/Resource/Detail/TitleBar/composables.ts +46 -0
- package/components/Resource/Detail/TitleBar/index.vue +204 -0
- package/components/Resource/Detail/Top/index.vue +34 -0
- package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
- package/components/Resource/Detail/composables.ts +45 -0
- package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
- package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
- package/components/ResourceDetail/Masthead/index.vue +65 -0
- package/components/ResourceDetail/Masthead/latest.vue +44 -0
- package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -1
- package/components/ResourceDetail/__tests__/index.test.ts +135 -0
- package/components/ResourceDetail/index.vue +75 -575
- package/components/ResourceDetail/legacy.vue +564 -0
- package/components/ResourceList/Masthead.vue +69 -20
- package/components/ResourceList/index.vue +3 -2
- package/components/ResourceTable.vue +59 -85
- package/components/ResourceYaml.vue +15 -2
- package/components/RichTranslation.vue +106 -0
- package/components/SlideInPanelManager.vue +116 -14
- package/components/SortableTable/index.vue +10 -2
- package/components/SortableTable/paging.js +15 -16
- package/components/SortableTable/selection.js +22 -10
- package/components/StateDot/index.vue +28 -0
- package/components/StatusBadge.vue +6 -4
- package/components/SubtleLink.vue +25 -0
- package/components/Tabbed/index.vue +38 -22
- package/components/Wizard.vue +16 -3
- package/components/YamlEditor.vue +1 -2
- package/components/__tests__/AsyncButton.test.ts +39 -0
- package/components/__tests__/ConfigMapSettings.test.ts +376 -0
- package/components/__tests__/CruResource.test.ts +63 -0
- package/components/__tests__/FilterPanel.test.ts +81 -0
- package/components/__tests__/GrowlManager.test.ts +0 -25
- package/components/__tests__/PromptModal.test.ts +146 -0
- package/components/__tests__/PromptRestore.test.ts +1 -65
- package/components/__tests__/RichTranslation.test.ts +115 -0
- package/components/auth/AuthBanner.vue +15 -14
- package/components/auth/Principal.vue +0 -1
- package/components/auth/RoleDetailEdit.vue +44 -4
- package/components/auth/login/ldap.vue +2 -2
- package/components/auth/login/oidc.vue +6 -1
- package/components/fleet/FleetApplications.vue +174 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
- package/components/fleet/FleetClusterTargets/index.vue +455 -0
- package/components/fleet/FleetClusters.vue +25 -6
- package/components/fleet/FleetGitRepoPaths.vue +476 -0
- package/components/fleet/FleetHelmOps.vue +123 -0
- package/components/fleet/FleetIntro.vue +58 -28
- package/components/fleet/FleetNoWorkspaces.vue +5 -1
- package/components/fleet/FleetOCIStorageSecret.vue +171 -0
- package/components/fleet/FleetRepos.vue +37 -80
- package/components/fleet/FleetResources.vue +69 -27
- package/components/fleet/FleetSummary.vue +26 -51
- package/components/fleet/FleetValuesFrom.vue +295 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
- package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
- package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
- package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
- package/components/fleet/dashboard/Empty.vue +73 -0
- package/components/fleet/dashboard/ResourceCard.vue +184 -0
- package/components/fleet/dashboard/ResourceCardSummary.vue +195 -0
- package/components/fleet/dashboard/ResourceDetails.vue +194 -0
- package/components/fleet/dashboard/ResourcePanel.vue +384 -0
- package/components/form/ArrayList.vue +144 -116
- package/components/form/BannerSettings.vue +117 -50
- package/components/form/ChangePassword.vue +3 -1
- package/components/form/ColorInput.vue +35 -6
- package/components/form/FileImageSelector.vue +1 -1
- package/components/form/Footer.vue +10 -4
- package/components/form/KeyValue.vue +92 -51
- package/components/form/LabeledSelect.vue +72 -54
- package/components/form/Labels.vue +91 -21
- package/components/form/MatchExpressions.vue +56 -9
- package/components/form/NameNsDescription.vue +12 -8
- package/components/form/Networking.vue +24 -19
- package/components/form/NotificationSettings.vue +15 -1
- package/components/form/ResourceLabeledSelect.vue +22 -8
- package/components/form/ResourceSelector.vue +27 -23
- package/components/form/ResourceTabs/index.vue +7 -1
- package/components/form/SSHKnownHosts/index.vue +14 -11
- package/components/form/SecretSelector.vue +18 -2
- package/components/form/Select.vue +57 -26
- package/components/form/SelectOrCreateAuthSecret.vue +6 -3
- package/components/form/SimpleSecretSelector.vue +17 -4
- package/components/form/Taints.vue +21 -2
- package/components/form/UnitInput.vue +21 -0
- package/components/form/ValueFromResource.vue +31 -19
- package/components/form/__tests__/ArrayList.test.ts +32 -0
- package/components/form/__tests__/ColorInput.test.ts +35 -0
- package/components/form/__tests__/KeyValue.test.ts +36 -0
- package/components/form/__tests__/LabeledSelect.test.ts +79 -2
- package/components/form/__tests__/Labels.test.ts +360 -0
- package/components/form/__tests__/MatchExpressions.test.ts +16 -13
- package/components/form/__tests__/Networking.test.ts +116 -0
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -2
- package/components/form/__tests__/Select.test.ts +37 -1
- package/components/form/__tests__/UnitInput.test.ts +23 -1
- package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
- package/components/formatter/ClusterLink.vue +5 -8
- package/components/formatter/Description.vue +30 -0
- package/components/formatter/FleetApplicationClustersReady.vue +77 -0
- package/components/formatter/FleetApplicationSource.vue +79 -0
- package/components/formatter/FleetSummaryGraph.vue +7 -0
- package/components/formatter/PodImages.vue +1 -1
- package/components/formatter/WorkloadHealthScale.vue +1 -1
- package/components/formatter/__tests__/ClusterLink.test.ts +2 -32
- package/components/formatter/__tests__/LiveDate.test.ts +10 -2
- package/components/google/AccountAccess.vue +209 -0
- package/components/google/types/gcp.d.ts +136 -0
- package/components/google/types/index.d.ts +101 -0
- package/components/google/util/__mocks__/gcp.ts +465 -0
- package/components/google/util/formatter.ts +82 -0
- package/components/google/util/gcp.ts +134 -0
- package/components/google/util/index.d.ts +11 -0
- package/components/nav/Favorite.vue +1 -1
- package/components/nav/Group.vue +5 -0
- package/components/nav/Header.vue +24 -38
- package/components/nav/NamespaceFilter.vue +141 -84
- package/components/nav/NotificationCenter/Notification.vue +484 -0
- package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
- package/components/nav/NotificationCenter/index.vue +148 -0
- package/components/nav/TopLevelMenu.helper.ts +55 -34
- package/components/nav/TopLevelMenu.vue +11 -0
- package/components/nav/Type.vue +4 -1
- package/components/nav/WindowManager/ContainerLogs.vue +87 -61
- package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
- package/components/nav/WindowManager/index.vue +3 -2
- package/components/templates/default.vue +0 -3
- package/components/templates/plain.vue +0 -3
- package/composables/drawer.ts +26 -0
- package/composables/focusTrap.ts +3 -3
- package/composables/resources.test.ts +63 -0
- package/composables/resources.ts +38 -0
- package/composables/useI18n.ts +12 -11
- package/composables/useIsNewDetailPageEnabled.ts +17 -0
- package/config/labels-annotations.js +22 -11
- package/config/pagination-table-headers.js +8 -1
- package/config/private-label.js +0 -1
- package/config/product/auth.js +20 -3
- package/config/product/{cis.js → compliance.js} +23 -26
- package/config/product/explorer.js +49 -17
- package/config/product/fleet.js +77 -17
- package/config/product/manager.js +1 -29
- package/config/product/settings.js +23 -11
- package/config/query-params.js +16 -1
- package/config/roles.ts +2 -1
- package/config/router/navigation-guards/authentication.js +51 -2
- package/config/router/navigation-guards/index.js +5 -67
- package/config/router/routes.js +65 -31
- package/config/secret.ts +15 -0
- package/config/settings.ts +33 -16
- package/config/store.js +2 -0
- package/config/system-namespaces.js +1 -1
- package/config/table-headers.js +91 -30
- package/config/types.js +18 -7
- package/config/version.js +1 -1
- package/core/plugin-helpers.ts +3 -2
- package/core/plugin.ts +32 -7
- package/core/types.ts +25 -7
- package/detail/catalog.cattle.io.app.vue +5 -1
- package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
- package/detail/fleet.cattle.io.bundle.vue +70 -6
- package/detail/fleet.cattle.io.cluster.vue +28 -15
- package/detail/fleet.cattle.io.gitrepo.vue +11 -2
- package/detail/fleet.cattle.io.helmop.vue +157 -0
- package/detail/management.cattle.io.fleetworkspace.vue +18 -27
- package/detail/management.cattle.io.oidcclient.vue +369 -0
- package/detail/namespace.vue +0 -3
- package/detail/node.vue +20 -16
- package/detail/pod.vue +2 -2
- package/detail/provisioning.cattle.io.cluster.vue +16 -50
- package/detail/service.vue +10 -2
- package/detail/workload/index.vue +48 -39
- package/dialog/AddCustomBadgeDialog.vue +0 -1
- package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
- package/dialog/AddonConfigConfirmationDialog.vue +1 -1
- package/dialog/AssignToDialog.vue +176 -0
- package/dialog/ChangePasswordDialog.vue +106 -0
- package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
- package/dialog/DisableAuthProviderDialog.vue +101 -0
- package/dialog/DrainNode.vue +1 -1
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +87 -66
- package/dialog/FeatureFlagListDialog.vue +288 -0
- package/dialog/ForceMachineRemoveDialog.vue +1 -1
- package/dialog/GenericPrompt.vue +1 -1
- package/dialog/HelmOpForceUpdateDialog.vue +132 -0
- package/{components/Import.vue → dialog/ImportDialog.vue} +8 -13
- package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
- package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -62
- package/dialog/MoveNamespaceDialog.vue +157 -0
- package/dialog/OidcClientSecretDialog.vue +117 -0
- package/dialog/RedeployWorkloadDialog.vue +164 -0
- package/dialog/RotateEncryptionKeyDialog.vue +10 -30
- package/dialog/ScalePoolDownDialog.vue +1 -1
- package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
- package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
- package/dialog/WechatDialog.vue +57 -0
- package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +15 -34
- package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +60 -68
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/edit/__tests__/service.test.ts +2 -1
- package/edit/auth/ldap/__tests__/config.test.ts +14 -0
- package/edit/auth/ldap/config.vue +24 -0
- package/edit/auth/oidc.vue +159 -93
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
- package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
- package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
- package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
- package/edit/configmap.vue +8 -2
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.gitrepo.vue +70 -256
- package/edit/fleet.cattle.io.helmop.vue +786 -0
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
- package/edit/logging-flow/index.vue +1 -0
- package/edit/logging.banzaicloud.io.output/index.vue +2 -1
- package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
- package/edit/management.cattle.io.fleetworkspace.vue +44 -10
- package/edit/management.cattle.io.oidcclient.vue +162 -0
- package/edit/management.cattle.io.project.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/auth.vue +3 -3
- package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
- package/edit/monitoring.coreos.com.route.vue +1 -0
- package/edit/namespace.vue +2 -4
- package/edit/networking.istio.io.destinationrule/index.vue +4 -1
- package/edit/networking.k8s.io.ingress/Certificate.vue +11 -3
- package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +37 -0
- package/edit/networking.k8s.io.ingress/index.vue +4 -1
- package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -14
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +57 -62
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +10 -16
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.test.ts +72 -41
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +17 -1
- package/edit/networking.k8s.io.networkpolicy/index.vue +23 -31
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +69 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +21 -73
- package/edit/provisioning.cattle.io.cluster/rke2.vue +535 -428
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +48 -39
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -2
- package/edit/resources.cattle.io.restore.vue +1 -1
- package/edit/secret/basic.vue +1 -0
- package/edit/secret/index.vue +127 -15
- package/edit/service.vue +17 -29
- package/edit/serviceaccount.vue +4 -1
- package/edit/storage.k8s.io.storageclass/index.vue +4 -1
- package/edit/workload/index.vue +11 -15
- package/edit/workload/mixins/workload.js +0 -2
- package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
- package/list/fleet.cattle.io.gitrepo.vue +1 -1
- package/list/fleet.cattle.io.helmop.vue +108 -0
- package/list/harvesterhci.io.management.cluster.vue +0 -17
- package/list/management.cattle.io.feature.vue +4 -288
- package/list/management.cattle.io.oidcclient.vue +108 -0
- package/list/management.cattle.io.user.vue +13 -20
- package/list/namespace.vue +6 -2
- package/list/node.vue +2 -0
- package/list/projectsecret.vue +345 -0
- package/list/secret.vue +109 -0
- package/list/workload.vue +6 -2
- package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
- package/machine-config/amazonec2.vue +3 -24
- package/machine-config/components/GCEImage.vue +374 -0
- package/machine-config/google.vue +617 -0
- package/machine-config/vmwarevsphere.vue +7 -17
- package/mixins/__tests__/brand.spec.ts +170 -0
- package/mixins/auth-config.js +8 -1
- package/mixins/brand.js +16 -17
- package/mixins/create-edit-view/impl.js +10 -1
- package/mixins/create-edit-view/index.js +5 -0
- package/mixins/preset.js +100 -0
- package/mixins/resource-fetch-api-pagination.js +73 -44
- package/mixins/resource-fetch.js +18 -8
- package/mixins/resource-table-watch.js +45 -0
- package/mixins/vue-select-overrides.js +1 -4
- package/models/__tests__/chart.test.ts +296 -0
- package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/models/__tests__/node.test.ts +7 -63
- package/models/__tests__/workload.test.ts +1 -0
- package/models/chart.js +157 -2
- package/models/cluster/node.js +2 -1
- package/models/cluster.js +32 -2
- package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
- package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
- package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
- package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
- package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
- package/models/fleet-application.js +297 -0
- package/models/fleet.cattle.io.bundle.js +9 -8
- package/models/fleet.cattle.io.cluster.js +21 -4
- package/models/fleet.cattle.io.gitrepo.js +46 -382
- package/models/fleet.cattle.io.helmop.js +202 -0
- package/models/management.cattle.io.authconfig.js +1 -0
- package/models/management.cattle.io.cluster.js +0 -20
- package/models/management.cattle.io.feature.js +7 -1
- package/models/management.cattle.io.fleetworkspace.js +14 -1
- package/models/management.cattle.io.node.js +7 -22
- package/models/management.cattle.io.nodepool.js +12 -0
- package/models/management.cattle.io.oidcclient.js +18 -0
- package/models/management.cattle.io.registration.js +3 -0
- package/models/management.cattle.io.setting.js +0 -1
- package/models/namespace.js +12 -1
- package/models/provisioning.cattle.io.cluster.js +60 -97
- package/models/secret.js +157 -2
- package/models/service.js +28 -9
- package/models/storage.k8s.io.storageclass.js +2 -2
- package/models/workload.js +91 -51
- package/package.json +6 -5
- package/pages/about.vue +17 -61
- package/pages/account/index.vue +9 -1
- package/pages/auth/login.vue +2 -3
- package/pages/auth/verify.vue +13 -1
- package/pages/c/_cluster/apps/charts/AddRepoLink.vue +36 -0
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +57 -0
- package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
- package/pages/c/_cluster/apps/charts/index.vue +501 -468
- package/pages/c/_cluster/apps/charts/install.vue +0 -1
- package/pages/c/_cluster/auth/roles/index.vue +19 -48
- package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
- package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +14 -3
- package/pages/c/_cluster/explorer/projectsecret.vue +34 -0
- package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
- package/pages/c/_cluster/fleet/__tests__/index.test.ts +720 -0
- package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
- package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
- package/pages/c/_cluster/fleet/application/create.vue +341 -0
- package/pages/c/_cluster/fleet/application/index.vue +139 -0
- package/pages/c/_cluster/fleet/graph/config.js +277 -0
- package/pages/c/_cluster/fleet/index.vue +866 -328
- package/pages/c/_cluster/fleet/settings/index.vue +229 -0
- package/pages/c/_cluster/longhorn/index.vue +5 -2
- package/pages/c/_cluster/settings/banners.vue +56 -2
- package/pages/c/_cluster/settings/brand.vue +2 -1
- package/pages/c/_cluster/settings/performance.vue +7 -26
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
- package/pages/c/_cluster/uiplugins/index.vue +98 -55
- package/pages/explorer/resource/detail/configmap.vue +42 -0
- package/pages/explorer/resource/detail/projectsecret.vue +9 -0
- package/pages/explorer/resource/detail/secret.vue +63 -0
- package/pages/home.vue +8 -104
- package/pages/prefs.vue +0 -1
- package/pages/support/index.vue +4 -6
- package/plugins/clean-html.js +2 -0
- package/plugins/dashboard-store/__tests__/actions.test.ts +4 -1
- package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
- package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
- package/plugins/dashboard-store/actions.js +212 -55
- package/plugins/dashboard-store/getters.js +112 -24
- package/plugins/dashboard-store/mutations.js +61 -12
- package/plugins/dashboard-store/normalize.js +29 -19
- package/plugins/dashboard-store/resource-class.js +132 -49
- package/plugins/steve/__tests__/getters.test.ts +19 -12
- package/plugins/steve/__tests__/steve-class.test.ts +1 -0
- package/plugins/steve/__tests__/subscribe.spec.ts +324 -1
- package/plugins/steve/actions.js +37 -24
- package/plugins/steve/getters.js +47 -12
- package/plugins/steve/resourceWatcher.js +10 -3
- package/plugins/steve/steve-class.js +5 -0
- package/plugins/steve/steve-pagination-utils.ts +225 -43
- package/plugins/steve/subscribe.js +418 -53
- package/plugins/steve/worker/web-worker.advanced.js +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -3
- package/rancher-components/Banner/Banner.vue +37 -6
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -9
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +51 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +21 -3
- package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
- package/rancher-components/Form/Radio/RadioButton.vue +21 -5
- package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +81 -38
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +4 -0
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +22 -1
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
- package/rancher-components/RcButton/RcButton.vue +1 -1
- package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +6 -0
- package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -55
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +69 -0
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +93 -0
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +7 -8
- package/rancher-components/RcDropdown/index.ts +2 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
- package/rancher-components/RcDropdown/useDropdownItem.ts +92 -0
- package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +430 -0
- package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
- package/rancher-components/RcItemCard/index.ts +2 -0
- package/rancher-components/StringList/StringList.vue +1 -1
- package/scripts/extension/publish +1 -1
- package/static/loading-indicator.html +1 -1
- package/store/action-menu.js +26 -56
- package/store/auth.js +3 -0
- package/store/catalog.js +85 -25
- package/store/features.js +0 -1
- package/store/growl.js +97 -8
- package/store/i18n.js +1 -1
- package/store/index.js +44 -14
- package/store/notifications.ts +426 -0
- package/store/prefs.js +2 -8
- package/store/slideInPanel.ts +6 -0
- package/store/type-map.js +34 -17
- package/store/type-map.utils.ts +49 -6
- package/store/uiplugins.ts +15 -1
- package/types/fleet.d.ts +60 -1
- package/types/kube/kube-api.ts +34 -0
- package/types/notifications/index.ts +74 -0
- package/types/resources/fleet.d.ts +43 -0
- package/types/resources/pod-security-admission.ts +36 -0
- package/types/resources/settings.d.ts +107 -0
- package/types/resources/userPreferences.d.ts +13 -0
- package/types/shell/index.d.ts +971 -745
- package/types/store/dashboard-store.types.ts +57 -4
- package/types/store/pagination.types.ts +41 -9
- package/types/store/subscribe.types.ts +50 -0
- package/utils/__mocks__/tabbable.js +13 -0
- package/utils/__tests__/back-off.test.ts +354 -0
- package/utils/__tests__/create-yaml.test.ts +235 -0
- package/utils/__tests__/fleet.test.ts +148 -0
- package/utils/__tests__/kontainer.test.ts +19 -0
- package/utils/__tests__/object.test.ts +54 -1
- package/utils/__tests__/string.test.ts +273 -1
- package/utils/__tests__/time.test.ts +31 -0
- package/utils/auth.js +41 -6
- package/utils/back-off.ts +176 -0
- package/utils/cluster.js +24 -20
- package/utils/create-yaml.js +103 -9
- package/utils/crypto/encryption.ts +103 -0
- package/utils/cspAdaptor.ts +51 -0
- package/utils/error.js +0 -5
- package/utils/fleet-types.ts +0 -0
- package/utils/fleet.ts +204 -74
- package/utils/grafana.js +1 -0
- package/utils/kontainer.ts +3 -5
- package/utils/object.js +36 -12
- package/utils/pagination-utils.ts +50 -3
- package/utils/pagination-wrapper.ts +132 -50
- package/utils/perf-setting.utils.ts +28 -0
- package/utils/release-notes.ts +48 -0
- package/utils/selector-typed.ts +210 -0
- package/utils/selector.js +29 -6
- package/utils/settings.ts +4 -1
- package/utils/string.js +24 -0
- package/utils/style.ts +39 -0
- package/utils/{time.js → time.ts} +25 -6
- package/utils/uiplugins.ts +41 -8
- package/utils/v-sphere.ts +5 -1
- package/utils/validators/formRules/__tests__/index.test.ts +76 -6
- package/utils/validators/formRules/index.ts +99 -4
- package/utils/window.js +11 -7
- package/.DS_Store +0 -0
- package/components/AssignTo.vue +0 -199
- package/components/DisableAuthProviderModal.vue +0 -115
- package/components/MoveModal.vue +0 -167
- package/components/PromptChangePassword.vue +0 -123
- package/components/ResourceList/Masthead-btn.vue +0 -225
- package/components/__tests__/ApplicationCard.test.ts +0 -27
- package/components/cards/ApplicationCard.vue +0 -145
- package/components/fleet/FleetBundleResources.vue +0 -86
- package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
- package/components/formatter/RKETemplateName.vue +0 -37
- package/config/product/legacy.js +0 -62
- package/config/secret.js +0 -14
- package/dialog/SaveAsRKETemplateDialog.vue +0 -139
- package/models/etcdbackup.js +0 -45
- package/pages/auth copy/login.vue +0 -595
- package/pages/auth copy/logout.vue +0 -47
- package/pages/auth copy/setup.vue +0 -523
- package/pages/auth copy/verify.vue +0 -203
- package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
- package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
- package/pages/c/_cluster/legacy/project/_page.vue +0 -57
- package/pages/c/_cluster/legacy/project/index.vue +0 -32
- package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
package/utils/kontainer.ts
CHANGED
|
@@ -17,11 +17,9 @@ export function syncUpstreamConfig(configPrefix: string, normanCluster: {[key: s
|
|
|
17
17
|
|
|
18
18
|
if (!isEmpty(upstreamConfig)) {
|
|
19
19
|
Object.keys(upstreamConfig).forEach((key) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
} else if ((rancherConfig[key] === null || rancherConfig[key] === undefined) && upstreamConfig[key] !== null && upstreamConfig[key] !== undefined) {
|
|
20
|
+
const empty = typeof upstreamConfig[key] === 'object' && isEmpty(upstreamConfig[key]);
|
|
21
|
+
|
|
22
|
+
if ((rancherConfig[key] === null || rancherConfig[key] === undefined) && upstreamConfig[key] !== null && upstreamConfig[key] !== undefined && !empty) {
|
|
25
23
|
set(rancherConfig, key, upstreamConfig[key]);
|
|
26
24
|
}
|
|
27
25
|
});
|
package/utils/object.js
CHANGED
|
@@ -510,10 +510,6 @@ export function deepToRaw(obj, cache = new WeakSet()) {
|
|
|
510
510
|
* with arrays in obj2 when both properties are arrays
|
|
511
511
|
* false: default lodash merge behavior - recursively merges
|
|
512
512
|
* array members
|
|
513
|
-
* @param {boolean} [options.replaceObjectProps=false] - true: merges objects in
|
|
514
|
-
* obj1 with objects in obj2, overwriting duplicate props
|
|
515
|
-
* false: default lodash merge behavior - recursively merges
|
|
516
|
-
* object props
|
|
517
513
|
*/
|
|
518
514
|
export function mergeWithReplace(
|
|
519
515
|
obj1 = {},
|
|
@@ -521,7 +517,6 @@ export function mergeWithReplace(
|
|
|
521
517
|
{
|
|
522
518
|
mutateOriginal = false,
|
|
523
519
|
replaceArray = true,
|
|
524
|
-
replaceObjectProps = false,
|
|
525
520
|
} = {}
|
|
526
521
|
) {
|
|
527
522
|
const destination = mutateOriginal ? obj1 : {};
|
|
@@ -530,12 +525,41 @@ export function mergeWithReplace(
|
|
|
530
525
|
if (replaceArray && Array.isArray(obj1Value) && Array.isArray(obj2Value)) {
|
|
531
526
|
return obj2Value;
|
|
532
527
|
}
|
|
533
|
-
|
|
534
|
-
if (replaceObjectProps && isObject(obj1Value) && isObject(obj2Value)) {
|
|
535
|
-
return {
|
|
536
|
-
...obj1Value,
|
|
537
|
-
...obj2Value,
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
528
|
});
|
|
541
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Converts Object into a string of a format "key1, val1, key2, val2"
|
|
532
|
+
* @param {Object} input - KV object to convert
|
|
533
|
+
* @returns string
|
|
534
|
+
*/
|
|
535
|
+
export const convertKVToString = (input) => {
|
|
536
|
+
if (!input || typeof input !== 'object') return '';
|
|
537
|
+
|
|
538
|
+
return Object.entries(input)
|
|
539
|
+
.flatMap(([key, value]) => [key, String(value)])
|
|
540
|
+
.join(',');
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Converts kv string into object
|
|
545
|
+
* @param {string} input - a string of a format "key1, val1, key2, val2"
|
|
546
|
+
* @returns
|
|
547
|
+
*/
|
|
548
|
+
export const convertStringToKV = ( input ) => {
|
|
549
|
+
if (!input?.trim()) return {};
|
|
550
|
+
|
|
551
|
+
const parts = input.split(',').map((part) => part.trim());
|
|
552
|
+
const result = {};
|
|
553
|
+
|
|
554
|
+
for (let i = 0; i < parts.length - 1; i += 2) {
|
|
555
|
+
const key = parts[i];
|
|
556
|
+
const value = parts[i + 1];
|
|
557
|
+
|
|
558
|
+
// Accept empty keys but ignore undefined values
|
|
559
|
+
if (typeof key === 'string') {
|
|
560
|
+
result[key] = value ?? '';
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return result;
|
|
565
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PaginationSettings, PaginationSettingsStore } from '@shell/types/resources/settings';
|
|
1
|
+
import { PaginationFeature, PaginationSettings, PaginationSettingsStore } from '@shell/types/resources/settings';
|
|
2
2
|
import {
|
|
3
3
|
NAMESPACE_FILTER_ALL_USER as ALL_USER,
|
|
4
4
|
NAMESPACE_FILTER_ALL as ALL,
|
|
@@ -15,17 +15,22 @@ import { isEqual } from '@shell/utils/object';
|
|
|
15
15
|
import { STEVE_CACHE } from '@shell/store/features';
|
|
16
16
|
import { getPerformanceSetting } from '@shell/utils/settings';
|
|
17
17
|
import { PAGINATION_SETTINGS_STORE_DEFAULTS } from '@shell/plugins/steve/steve-pagination-utils';
|
|
18
|
+
import { MANAGEMENT } from '@shell/config/types';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Helper functions for server side pagination
|
|
21
22
|
*/
|
|
22
23
|
class PaginationUtils {
|
|
24
|
+
/**
|
|
25
|
+
* In places where we're using paginated features but not in a page... this is what the max results should be
|
|
26
|
+
*/
|
|
27
|
+
readonly defaultPageSize = 100000;
|
|
23
28
|
/**
|
|
24
29
|
* When a ns filter isn't one or more projects/namespaces... what are the valid values?
|
|
25
30
|
*
|
|
26
31
|
* This basically blocks 'Not in a Project'.. which would involve a projectsornamespaces param with every ns not in a project.
|
|
27
32
|
*/
|
|
28
|
-
validNsProjectFilters = [ALL, ALL_SYSTEM, ALL_USER, ALL_SYSTEM, NAMESPACE_FILTER_KINDS.NAMESPACE, NAMESPACE_FILTER_KINDS.PROJECT, NAMESPACED_YES, NAMESPACED_NO];
|
|
33
|
+
readonly validNsProjectFilters = [ALL, ALL_SYSTEM, ALL_USER, ALL_SYSTEM, NAMESPACE_FILTER_KINDS.NAMESPACE, NAMESPACE_FILTER_KINDS.PROJECT, NAMESPACED_YES, NAMESPACED_NO];
|
|
29
34
|
|
|
30
35
|
private getSettings({ rootGetters }: any): PaginationSettings {
|
|
31
36
|
const perf = getPerformanceSetting(rootGetters);
|
|
@@ -50,6 +55,23 @@ class PaginationUtils {
|
|
|
50
55
|
return rootGetters['features/get']?.(STEVE_CACHE);
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Determine if the downstream cluster has vai enabled
|
|
60
|
+
*
|
|
61
|
+
* Almost all the time the downstream cluster vai state will align with upstream (it manages it)
|
|
62
|
+
* ... unless it's harvester then weird things happen
|
|
63
|
+
*/
|
|
64
|
+
async isDownstreamSteveCacheEnabled({ dispatch }: any, clusterId: string): Promise<boolean> {
|
|
65
|
+
const url = `/k8s/clusters/${ clusterId }/v1/${ MANAGEMENT.FEATURE }s/${ STEVE_CACHE }`;
|
|
66
|
+
const entry = await dispatch('cluster/request', { url });
|
|
67
|
+
|
|
68
|
+
if (entry.status.lockedValue !== null) {
|
|
69
|
+
return entry.status.lockedValue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (entry.spec.value !== null) ? entry.spec.value : entry.status.default;
|
|
73
|
+
}
|
|
74
|
+
|
|
53
75
|
/**
|
|
54
76
|
* Is pagination enabled at a global level or for a specific resource
|
|
55
77
|
*/
|
|
@@ -62,7 +84,7 @@ class PaginationUtils {
|
|
|
62
84
|
const settings = this.getSettings({ rootGetters });
|
|
63
85
|
|
|
64
86
|
// No setting, not enabled
|
|
65
|
-
if (!settings
|
|
87
|
+
if (!settings) {
|
|
66
88
|
return false;
|
|
67
89
|
}
|
|
68
90
|
|
|
@@ -124,6 +146,31 @@ class PaginationUtils {
|
|
|
124
146
|
return false;
|
|
125
147
|
}
|
|
126
148
|
|
|
149
|
+
listAutoRefreshToggleEnabled({ rootGetters }: any): boolean {
|
|
150
|
+
return this.isFeatureEnabled({ rootGetters }, 'listAutoRefreshToggle');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
isListManualRefreshEnabled({ rootGetters }: any): boolean {
|
|
154
|
+
return this.isFeatureEnabled({ rootGetters }, 'listManualRefresh');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private isFeatureEnabled({ rootGetters }: any, featureName: PaginationFeature): boolean {
|
|
158
|
+
// Cache must be enabled to support pagination api
|
|
159
|
+
if (!this.isSteveCacheEnabled({ rootGetters })) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const settings = this.getSettings({ rootGetters });
|
|
164
|
+
|
|
165
|
+
return !!settings.features?.[featureName]?.enabled;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
resourceChangesDebounceMs({ rootGetters }: any): number | undefined {
|
|
169
|
+
const settings = this.getSettings({ rootGetters });
|
|
170
|
+
|
|
171
|
+
return settings.resourceChangesDebounceMs;
|
|
172
|
+
}
|
|
173
|
+
|
|
127
174
|
validateNsProjectFilters(nsProjectFilters: string[]) {
|
|
128
175
|
return nsProjectFilters?.every((f) => this.validateNsProjectFilter(f));
|
|
129
176
|
}
|
|
@@ -1,70 +1,152 @@
|
|
|
1
1
|
import paginationUtils from '@shell/utils/pagination-utils';
|
|
2
|
-
import { PaginationArgs, PaginationResourceContext
|
|
2
|
+
import { PaginationArgs, PaginationResourceContext } from '@shell/types/store/pagination.types';
|
|
3
3
|
import { VuexStore } from '@shell/types/store/vuex';
|
|
4
|
-
import { ActionFindPageArgs } from '@shell/types/store/dashboard-store.types';
|
|
4
|
+
import { ActionFindPageArgs, ActionFindPageTransientResult } from '@shell/types/store/dashboard-store.types';
|
|
5
|
+
import {
|
|
6
|
+
STEVE_WATCH_EVENT_LISTENER_CALLBACK, STEVE_UNWATCH_EVENT_PARAMS, STEVE_WATCH_EVENT, STEVE_WATCH_EVENT_PARAMS, STEVE_WATCH_EVENT_PARAMS_COMMON, STEVE_WATCH_MODE
|
|
7
|
+
} from '@shell/types/store/subscribe.types';
|
|
8
|
+
import { Reactive, reactive } from 'vue';
|
|
5
9
|
|
|
6
|
-
interface
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
interface Args {
|
|
11
|
+
$store: VuexStore,
|
|
12
|
+
/**
|
|
13
|
+
* Unique ID for this request. Used for watch purposes
|
|
14
|
+
*/
|
|
15
|
+
id: string,
|
|
16
|
+
/**
|
|
17
|
+
* Args used when determining if this resource type supports SSP
|
|
18
|
+
*/
|
|
19
|
+
enabledFor: PaginationResourceContext,
|
|
20
|
+
/**
|
|
21
|
+
* Callback called when the resource is changed (notified by socket)
|
|
22
|
+
*/
|
|
23
|
+
onChange?: () => void,
|
|
24
|
+
|
|
25
|
+
formatResponse?: {
|
|
26
|
+
/**
|
|
27
|
+
* Convert the response into a model class instance
|
|
28
|
+
*/
|
|
29
|
+
classify?: boolean,
|
|
30
|
+
reactive?: boolean,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface Result<T> extends Omit<ActionFindPageTransientResult<T>, 'data'> {
|
|
35
|
+
data: Reactive<T[]>
|
|
9
36
|
}
|
|
10
37
|
|
|
11
38
|
/**
|
|
12
|
-
* This is a helper class that will assist in fetching a resource
|
|
13
|
-
* - Handle if the resource can be fetched by the new pagination api
|
|
14
|
-
* - Make a request to get a page (including classify)
|
|
15
|
-
* - Provide updates when the resource changes
|
|
39
|
+
* This is a helper class that will assist in fetching a resource via the new Server-Side Pagination API
|
|
16
40
|
*
|
|
17
41
|
* This is designed to work in places where we don't/can't store the resource in the store
|
|
18
42
|
* - There already exists a resource we don't want to overwrite
|
|
19
|
-
* - We're transient and want something nicer than just cluster/request
|
|
43
|
+
* - We're transient and want something nicer than just `cluster/request` + all the trimmings
|
|
44
|
+
*
|
|
45
|
+
* It ...
|
|
46
|
+
* - Handles if the resource can be fetched by the new pagination api
|
|
47
|
+
* - Makes a request to get a page (including optional classify & reactive)
|
|
48
|
+
* - Provide updates when the resource changes
|
|
20
49
|
*/
|
|
21
|
-
class PaginationWrapper<T
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
class PaginationWrapper<T extends object> {
|
|
51
|
+
private $store: VuexStore;
|
|
52
|
+
private enabledFor: PaginationResourceContext;
|
|
53
|
+
private onChange?: STEVE_WATCH_EVENT_LISTENER_CALLBACK;
|
|
54
|
+
private id: string;
|
|
55
|
+
private classify: boolean;
|
|
56
|
+
private reactive: boolean;
|
|
57
|
+
|
|
58
|
+
public isEnabled: boolean;
|
|
59
|
+
private steveWatchParams: STEVE_WATCH_EVENT_PARAMS_COMMON | undefined;
|
|
60
|
+
|
|
61
|
+
constructor(args: Args) {
|
|
62
|
+
const {
|
|
63
|
+
$store, id, enabledFor, onChange, formatResponse
|
|
64
|
+
} = args;
|
|
65
|
+
|
|
66
|
+
this.$store = $store;
|
|
67
|
+
this.id = id;
|
|
68
|
+
this.enabledFor = enabledFor;
|
|
69
|
+
this.onChange = onChange;
|
|
70
|
+
this.classify = formatResponse?.classify || false;
|
|
71
|
+
this.reactive = formatResponse?.reactive || false;
|
|
72
|
+
|
|
73
|
+
this.isEnabled = paginationUtils.isEnabled({ rootGetters: $store.getters }, enabledFor);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async request(args: {
|
|
77
|
+
pagination: PaginationArgs,
|
|
78
|
+
}): Promise<Result<T>> {
|
|
79
|
+
if (!this.isEnabled) {
|
|
80
|
+
throw new Error(`Wrapper for type '${ this.enabledFor.store }/${ this.enabledFor.resource?.id }' in context '${ this.enabledFor.resource?.context }' not supported`);
|
|
81
|
+
}
|
|
82
|
+
const { pagination } = args;
|
|
83
|
+
const opt: ActionFindPageArgs = {
|
|
84
|
+
watch: false,
|
|
85
|
+
pagination,
|
|
86
|
+
transient: true,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Fetch
|
|
90
|
+
const out: ActionFindPageTransientResult<T> = await this.$store.dispatch(`${ this.enabledFor.store }/findPage`, { opt, type: this.enabledFor.resource?.id });
|
|
91
|
+
|
|
92
|
+
// Watch
|
|
93
|
+
if (this.onChange && !this.steveWatchParams) {
|
|
94
|
+
this.steveWatchParams = {
|
|
95
|
+
event: STEVE_WATCH_EVENT.CHANGES,
|
|
96
|
+
id: this.id,
|
|
97
|
+
params: {
|
|
98
|
+
type: this.enabledFor.resource?.id as string,
|
|
99
|
+
mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
this.watch();
|
|
43
104
|
}
|
|
44
105
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
transient: true,
|
|
55
|
-
pagination
|
|
106
|
+
// Convert Response
|
|
107
|
+
if (this.classify) {
|
|
108
|
+
out.data = await this.$store.dispatch(`${ this.enabledFor.store }/createMany`, out.data);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (this.reactive) {
|
|
112
|
+
return {
|
|
113
|
+
...out,
|
|
114
|
+
data: reactive(out.data)
|
|
56
115
|
};
|
|
116
|
+
}
|
|
57
117
|
|
|
58
|
-
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
59
120
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}
|
|
121
|
+
private async watch() {
|
|
122
|
+
if (!this.steveWatchParams) {
|
|
123
|
+
console.error('Calling watch but no watch params created'); // eslint-disable-line no-console
|
|
65
124
|
|
|
66
|
-
return
|
|
125
|
+
return;
|
|
67
126
|
}
|
|
127
|
+
const watchParams: STEVE_WATCH_EVENT_PARAMS = {
|
|
128
|
+
...this.steveWatchParams,
|
|
129
|
+
callback: this.onChange as STEVE_WATCH_EVENT_LISTENER_CALLBACK, // we must have it by now
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
await this.$store.dispatch(`${ this.enabledFor.store }/watchEvent`, watchParams);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private async unWatch() {
|
|
136
|
+
if (!this.steveWatchParams) {
|
|
137
|
+
console.error('Calling unWatch but no watch params created'); // eslint-disable-line no-console
|
|
138
|
+
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const unWatchParams: STEVE_UNWATCH_EVENT_PARAMS = { ...this.steveWatchParams };
|
|
143
|
+
|
|
144
|
+
await this.$store.dispatch(`${ this.enabledFor.store }/unwatchEvent`, unWatchParams);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async onDestroy() {
|
|
148
|
+
await this.unWatch();
|
|
149
|
+
}
|
|
68
150
|
}
|
|
69
151
|
|
|
70
152
|
export default PaginationWrapper;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PerfSettings } from '@shell/config/settings';
|
|
2
|
+
|
|
3
|
+
type PaginationSupersedesSettings = 'incrementalLoading' | 'manualRefresh'
|
|
4
|
+
|
|
5
|
+
class _Utils {
|
|
6
|
+
private setting: PaginationSupersedesSettings;
|
|
7
|
+
constructor(setting: PaginationSupersedesSettings) {
|
|
8
|
+
this.setting = setting;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This is a centralised point to ensure SSP takes precedence over the performance setting
|
|
13
|
+
*/
|
|
14
|
+
isEnabled(paginationEnabled: boolean, perfSettings: PerfSettings): boolean {
|
|
15
|
+
return !paginationEnabled && perfSettings[this.setting].enabled;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
/**
|
|
21
|
+
* Helper functions for the 'incremental loading indicator' performance settings
|
|
22
|
+
*/
|
|
23
|
+
incrementalLoadingUtils: new _Utils('incrementalLoading'),
|
|
24
|
+
/**
|
|
25
|
+
* Helper functions for the 'manual refresh' performance settings
|
|
26
|
+
*/
|
|
27
|
+
manualRefreshUtils: new _Utils('manualRefresh'),
|
|
28
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getVersionData } from '@shell/config/version';
|
|
2
|
+
import { READ_WHATS_NEW } from '@shell/store/prefs';
|
|
3
|
+
import { NotificationLevel } from '@shell/types/notifications';
|
|
4
|
+
|
|
5
|
+
export async function addReleaseNotesNotification(dispatch: any, getters: any) {
|
|
6
|
+
const rancherVersion = getVersionData().Version.split('-')[0];
|
|
7
|
+
const prefix = 'release-notes-';
|
|
8
|
+
const id = `${ prefix }${ rancherVersion }`;
|
|
9
|
+
let found = false;
|
|
10
|
+
const all = getters['notifications/all'];
|
|
11
|
+
const lastReadVersion = getters['prefs/get'](READ_WHATS_NEW) || '';
|
|
12
|
+
const t = getters['i18n/t'];
|
|
13
|
+
const releaseNotesUrl = getters['releaseNotesUrl'];
|
|
14
|
+
|
|
15
|
+
// Delete notification(s) for old release notes
|
|
16
|
+
for (let i = 0; i < all.length; i++) {
|
|
17
|
+
const notification = all[i];
|
|
18
|
+
|
|
19
|
+
if (notification.id.startsWith(prefix)) {
|
|
20
|
+
if (notification.id === id) {
|
|
21
|
+
found = true;
|
|
22
|
+
} else {
|
|
23
|
+
await dispatch('notifications/delete', notification.id);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Also use pref, so if we expired it, we don't add it back
|
|
29
|
+
if (!found && lastReadVersion !== rancherVersion) {
|
|
30
|
+
// Register notification
|
|
31
|
+
const notification = {
|
|
32
|
+
id,
|
|
33
|
+
level: NotificationLevel.Info,
|
|
34
|
+
title: t('landing.whatsNew.title', { version: rancherVersion }),
|
|
35
|
+
message: t('landing.whatsNew.message'),
|
|
36
|
+
preference: {
|
|
37
|
+
key: READ_WHATS_NEW,
|
|
38
|
+
value: rancherVersion
|
|
39
|
+
},
|
|
40
|
+
primaryAction: {
|
|
41
|
+
label: t('landing.whatsNew.link'),
|
|
42
|
+
target: releaseNotesUrl
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
await dispatch('notifications/add', notification);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { COUNT } from '@shell/config/types';
|
|
2
|
+
import { KubeLabelSelector, KubeLabelSelectorExpression } from '@shell/types/kube/kube-api';
|
|
3
|
+
import { ActionFindPageArgs } from '@shell/types/store/dashboard-store.types';
|
|
4
|
+
import { FilterArgs, PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
|
|
5
|
+
import { isEmpty } from '@shell/utils/object';
|
|
6
|
+
import { convert, matching as rootMatching } from '@shell/utils/selector';
|
|
7
|
+
|
|
8
|
+
type MatchingResponse = {
|
|
9
|
+
matched: number,
|
|
10
|
+
matches: any[],
|
|
11
|
+
none: boolean,
|
|
12
|
+
sample: any,
|
|
13
|
+
total: number,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Find resources that match a labelSelector. This behaves differently if vai based pagination is on
|
|
18
|
+
* a) Pagination Enabled - fetch matching resources filtered on backend - findPage
|
|
19
|
+
* b) Pagination Disabled - fetch all resources and then filter locally - findAll --> root `matching` fn
|
|
20
|
+
*
|
|
21
|
+
* This is a much smarter version of root matching fn `matching` from shell/utils/selector.js (which just does local filtering)
|
|
22
|
+
*
|
|
23
|
+
* If fetching all of a resource should be avoided or we don't want to mess around with the cache the action `findLabelSelector` should be used
|
|
24
|
+
* - sometimes some legacy code expects all resources are fetched
|
|
25
|
+
* - sometimes we want to fetch a resource but not override the cache
|
|
26
|
+
* - already have a pods list cached, don't want to overwrite that when finding pods associated with a service
|
|
27
|
+
*
|
|
28
|
+
* Resources are returned in a common format which includes metadata
|
|
29
|
+
*/
|
|
30
|
+
export async function matching({
|
|
31
|
+
labelSelector,
|
|
32
|
+
type,
|
|
33
|
+
inStore,
|
|
34
|
+
$store,
|
|
35
|
+
inScopeCount = undefined,
|
|
36
|
+
namespace = undefined,
|
|
37
|
+
transient = true,
|
|
38
|
+
}: {
|
|
39
|
+
/**
|
|
40
|
+
* Standard kube label selector object.
|
|
41
|
+
*
|
|
42
|
+
* If this is 'empty' (no matchLabels or matchExpressions) it will return all results
|
|
43
|
+
*
|
|
44
|
+
* If this is 'null' it will return no results
|
|
45
|
+
*/
|
|
46
|
+
labelSelector: KubeLabelSelector,
|
|
47
|
+
/**
|
|
48
|
+
* Resource type
|
|
49
|
+
*/
|
|
50
|
+
type: string,
|
|
51
|
+
/**
|
|
52
|
+
* Store in which resources will be cached
|
|
53
|
+
*/
|
|
54
|
+
inStore: string,
|
|
55
|
+
/**
|
|
56
|
+
* Standard vuex store object
|
|
57
|
+
*/
|
|
58
|
+
$store: any,
|
|
59
|
+
/**
|
|
60
|
+
* Number of resources that are applicable when filtering.
|
|
61
|
+
*
|
|
62
|
+
* Used to skip any potential http request if we know the result will be zero
|
|
63
|
+
*
|
|
64
|
+
* If this property is not supplied we'll try and discover it from the COUNTS resource.
|
|
65
|
+
*/
|
|
66
|
+
inScopeCount?: number
|
|
67
|
+
/**
|
|
68
|
+
* Optional namespace or namespaces to apply selector to
|
|
69
|
+
*
|
|
70
|
+
* If this is undefined then namespaces will totally be ignored
|
|
71
|
+
*
|
|
72
|
+
* If this is provided all resources must be within them. If an empty array is provided then no resources will be matched
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
namespace?: string | string[],
|
|
76
|
+
/**
|
|
77
|
+
* Should the result bypass the store?
|
|
78
|
+
*/
|
|
79
|
+
transient?: boolean,
|
|
80
|
+
}): Promise<MatchingResponse> {
|
|
81
|
+
const isNamespaced = $store.getters[`${ inStore }/schemaFor`](type)?.attributes.namespaced;
|
|
82
|
+
const safeNamespaces = Array.isArray(namespace) ? namespace : !!namespace ? [namespace] : [];
|
|
83
|
+
const filterByNamespaces = isNamespaced && !!namespace ; // Result set must come from a resource in a namespace
|
|
84
|
+
|
|
85
|
+
// Determine if there's actually anything to filter on
|
|
86
|
+
if (typeof inScopeCount === 'undefined') {
|
|
87
|
+
const counts = $store.getters[`${ inStore }/all`](COUNT)?.[0]?.counts || {};
|
|
88
|
+
|
|
89
|
+
if (filterByNamespaces) {
|
|
90
|
+
inScopeCount = 0;
|
|
91
|
+
safeNamespaces.forEach((n) => {
|
|
92
|
+
inScopeCount += counts?.[type]?.namespaces[n]?.count || 0;
|
|
93
|
+
});
|
|
94
|
+
} else {
|
|
95
|
+
inScopeCount = counts?.[type]?.summary?.count || 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Exit early if there are any situations that always return nothing
|
|
100
|
+
const noCandidates = (inScopeCount || 0) === 0;
|
|
101
|
+
const filterByNamespaceButNoNamespace = isNamespaced && !!namespace && (!safeNamespaces || safeNamespaces.length === 0);
|
|
102
|
+
const explicityNullLabelSelector = labelSelector === null || (labelSelector?.matchLabels === null && !labelSelector.matchExpressions === null);
|
|
103
|
+
|
|
104
|
+
// If we have matchLabels or matchExpression entries they must have a key
|
|
105
|
+
const matchLabelKeys = Object.keys(labelSelector.matchLabels || {});
|
|
106
|
+
const invalidMatchLabelKeys = matchLabelKeys.length && matchLabelKeys.filter((k) => !k).length;
|
|
107
|
+
const invalidMatchExpressionKeys = labelSelector?.matchExpressions?.length && labelSelector.matchExpressions.filter((me) => !me.key).length;
|
|
108
|
+
|
|
109
|
+
if (noCandidates || filterByNamespaceButNoNamespace || explicityNullLabelSelector || invalidMatchLabelKeys || invalidMatchExpressionKeys) {
|
|
110
|
+
return generateMatchingResponse([], inScopeCount || 0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if ($store.getters[`${ inStore }/paginationEnabled`]?.({ id: type })) {
|
|
114
|
+
if (isLabelSelectorEmpty(labelSelector) && (!!namespace && !safeNamespaces?.length)) {
|
|
115
|
+
// no namespaces - ALL resources are candidates
|
|
116
|
+
// no labels - return all candidates
|
|
117
|
+
// too many to fetch...
|
|
118
|
+
throw new Error('Either populated labelSelector or namespace/s must be supplied in order to call findPage');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const findPageArgs: ActionFindPageArgs = {
|
|
122
|
+
pagination: new FilterArgs({
|
|
123
|
+
labelSelector,
|
|
124
|
+
filters: PaginationParamFilter.createMultipleFields(
|
|
125
|
+
safeNamespaces.map(
|
|
126
|
+
(n) => new PaginationFilterField({
|
|
127
|
+
field: 'metadata.namespace', // API only compatible with steve atm...
|
|
128
|
+
value: n,
|
|
129
|
+
})
|
|
130
|
+
)
|
|
131
|
+
),
|
|
132
|
+
}),
|
|
133
|
+
transient,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
let match = await $store.dispatch(`${ inStore }/findPage`, { type, opt: findPageArgs });
|
|
137
|
+
|
|
138
|
+
if (transient) {
|
|
139
|
+
match = match.data;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return generateMatchingResponse(match, inScopeCount || 0);
|
|
143
|
+
} else {
|
|
144
|
+
// Start off with everything as a candidate
|
|
145
|
+
let candidates = await $store.dispatch(`${ inStore }/findAll`, { type });
|
|
146
|
+
|
|
147
|
+
inScopeCount = candidates.length;
|
|
148
|
+
|
|
149
|
+
// Filter out namespace specific stuff
|
|
150
|
+
if (isNamespaced && safeNamespaces?.length > 0) {
|
|
151
|
+
candidates = candidates.filter((e: any) => safeNamespaces.includes(e.metadata?.namespace));
|
|
152
|
+
inScopeCount = candidates.length;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Apply labelSelector
|
|
156
|
+
if (labelSelector.matchLabels || labelSelector.matchExpressions) {
|
|
157
|
+
candidates = matches(candidates, labelSelector, 'metadata.labels');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return generateMatchingResponse(candidates, inScopeCount || 0);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const generateMatchingResponse = <T extends { [key: string]: any, nameDisplay: string}>(match: T[], inScopeCount: number): MatchingResponse => {
|
|
165
|
+
const matched = match.length || 0;
|
|
166
|
+
const sample = match[0]?.nameDisplay;
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
matched,
|
|
170
|
+
matches: match,
|
|
171
|
+
none: matched === 0,
|
|
172
|
+
sample,
|
|
173
|
+
total: inScopeCount || 0,
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* This is similar to shell/utils/selector.js `matches`, but accepts a kube labelSelector
|
|
179
|
+
*/
|
|
180
|
+
function matches<T = any>(candidates: T[], labelSelector: KubeLabelSelector, labelKey: string): T[] {
|
|
181
|
+
const convertedObject = convert(labelSelector.matchLabels, labelSelector.matchExpressions);
|
|
182
|
+
|
|
183
|
+
return rootMatching(candidates, convertedObject, labelKey);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function isLabelSelectorEmpty(labelSelector?: KubeLabelSelector): boolean {
|
|
187
|
+
return !labelSelector?.matchExpressions?.length && isEmpty(labelSelector?.matchLabels);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function labelSelectorToSelector(labelSelector?: KubeLabelSelector): string {
|
|
191
|
+
if (isLabelSelectorEmpty(labelSelector)) {
|
|
192
|
+
return '';
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const res: string[] = [];
|
|
196
|
+
|
|
197
|
+
Object.entries(labelSelector?.matchLabels || {}).forEach(([key, value]) => {
|
|
198
|
+
res.push(`${ key }=${ value }`);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
(labelSelector?.matchExpressions || []).forEach((value: KubeLabelSelectorExpression) => {
|
|
202
|
+
if (value.operator === 'In' && value.values?.length === 1) {
|
|
203
|
+
res.push(`${ value.key }=${ value.values[0] }`);
|
|
204
|
+
} else {
|
|
205
|
+
throw new Error(`Unsupported matchExpression found when converting to selector string. ${ value }`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return res.join(',');
|
|
210
|
+
}
|