@rancher/shell 1.2.3 → 2.0.1
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 +9 -0
- package/assets/images/vendor/openid.svg +18 -0
- package/assets/styles/app.scss +1 -2
- package/assets/styles/fonts/_icons.scss +3 -3
- package/assets/styles/global/_columns.scss +1 -1
- package/assets/styles/global/_labeled-input.scss +1 -0
- package/assets/styles/global/_layout.scss +99 -0
- package/assets/styles/themes/_csp.scss +2 -2
- package/assets/styles/themes/_dark.scss +8 -2
- package/assets/styles/themes/_light.scss +2 -1
- package/assets/styles/themes/_suse.scss +1 -1
- package/assets/styles/vendor/vue-select.scss +5 -0
- package/assets/translations/en-us.yaml +315 -64
- package/assets/translations/zh-hans.yaml +7 -31
- package/babel.config.js +8 -2
- package/chart/__tests__/S3.test.ts +9 -2
- package/chart/gatekeeper.vue +2 -11
- package/chart/istio.vue +1 -10
- package/chart/logging/index.vue +2 -11
- package/chart/monitoring/alerting/index.vue +7 -21
- package/chart/monitoring/grafana/index.vue +61 -2
- package/chart/monitoring/index.vue +52 -26
- package/chart/monitoring/prometheus/index.vue +39 -45
- package/chart/rancher-backup/S3.vue +11 -9
- package/chart/rancher-backup/index.vue +18 -15
- package/cloud-credential/__tests__/harvester.test.ts +18 -0
- package/cloud-credential/azure.vue +4 -17
- package/cloud-credential/generic.vue +18 -9
- package/cloud-credential/harvester.vue +11 -3
- package/components/AlertTable.vue +17 -7
- package/components/AppModal.vue +167 -0
- package/components/AssignTo.vue +7 -4
- package/components/AsyncButton.vue +27 -5
- package/components/BackLink.vue +4 -4
- package/components/BannerGraphic.vue +1 -0
- package/components/BrandImage.vue +47 -1
- package/components/Carousel.vue +15 -8
- package/components/Certificates.vue +161 -0
- package/components/ClusterBadge.vue +12 -3
- package/components/ClusterIconMenu.vue +55 -12
- package/components/ClusterProviderIcon.vue +14 -3
- package/components/CodeMirror.vue +111 -17
- package/components/CommunityLinks.vue +12 -8
- package/components/CopyCode.vue +6 -2
- package/components/CopyToClipboard.vue +2 -1
- package/components/CopyToClipboardText.vue +14 -9
- package/components/CreateDriver.vue +81 -0
- package/components/CruResource.vue +52 -27
- package/components/DetailTop.vue +2 -2
- package/components/Dialog.vue +6 -5
- package/components/DisableAuthProviderModal.vue +14 -8
- package/components/DraggableZone.vue +2 -2
- package/components/EtcdInfoBanner.vue +5 -5
- package/components/ExplorerMembers.vue +3 -3
- package/components/ExplorerProjectsNamespaces.vue +31 -7
- package/components/FixedBanner.vue +48 -36
- package/components/GlobalRoleBindings.vue +26 -0
- package/components/GrafanaDashboard.vue +6 -4
- package/components/IconOrSvg.vue +1 -1
- package/components/Import.vue +10 -6
- package/components/Inactivity.vue +1 -5
- package/components/KeyValueView.vue +14 -10
- package/components/Markdown.vue +16 -12
- package/components/MessageLink.vue +2 -2
- package/components/ModalWithCard.vue +5 -8
- package/components/MoveModal.vue +35 -33
- package/components/PodSecurityAdmission.vue +3 -3
- package/components/PromptChangePassword.vue +33 -33
- package/components/PromptModal.vue +11 -21
- package/components/PromptRemove.vue +12 -17
- package/components/PromptRestore.vue +18 -16
- package/components/Questions/__tests__/Boolean.test.ts +9 -19
- package/components/Questions/__tests__/Float.test.ts +9 -19
- package/components/Questions/__tests__/Int.test.ts +9 -19
- package/components/Questions/__tests__/String.test.ts +9 -19
- package/components/Questions/__tests__/Yaml.test.ts +9 -20
- package/components/Questions/__tests__/utils/questions-defaults.ts +20 -0
- package/components/Questions/index.vue +19 -3
- package/components/ResourceCancelModal.vue +34 -29
- package/components/ResourceDetail/Masthead.vue +48 -16
- package/components/ResourceDetail/index.vue +6 -4
- package/components/ResourceList/Masthead.vue +10 -9
- package/components/ResourceList/index.vue +65 -14
- package/components/ResourceTable.vue +87 -21
- package/components/ResourceYaml.vue +35 -5
- package/components/SelectIconGrid.vue +3 -3
- package/components/SideNav.vue +50 -94
- package/components/SingleClusterInfo.vue +4 -4
- package/components/SortableTable/THead.vue +33 -21
- package/components/SortableTable/filtering.js +9 -1
- package/components/SortableTable/grouping.js +8 -1
- package/components/SortableTable/index.vue +143 -44
- package/components/SortableTable/paging.js +36 -7
- package/components/SortableTable/selection.js +2 -1
- package/components/SortableTable/sorting.js +24 -7
- package/components/StatusTable.vue +5 -1
- package/components/Tabbed/index.vue +18 -1
- package/components/TableDataUserIcon.vue +47 -0
- package/components/TypeDescription.vue +1 -0
- package/components/Wizard.vue +1 -0
- package/components/YamlEditor.vue +1 -0
- package/components/__tests__/AppModal.test.ts +98 -0
- package/components/__tests__/AsyncButton.test.ts +1 -3
- package/components/__tests__/BackLink.test.ts +1 -1
- package/components/__tests__/ButtonGroup.test.ts +3 -6
- package/components/__tests__/Carousel.test.ts +43 -0
- package/components/__tests__/Certificates.test.ts +29 -0
- package/components/__tests__/CodeMirror.test.ts +87 -0
- package/components/__tests__/CopyCode.test.ts +5 -4
- package/components/__tests__/CruResource.test.ts +10 -9
- package/components/__tests__/EtcdInfoBanner.test.ts +37 -0
- package/components/__tests__/FixedBanner.test.ts +5 -20
- package/components/__tests__/NamespaceFilter.test.ts +9 -18
- package/components/__tests__/TabTitle.test.ts +129 -0
- package/components/auth/AzureWarning.vue +2 -2
- package/components/auth/RoleDetailEdit.vue +10 -0
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/auth/login/oidc.vue +7 -1
- package/components/fleet/FleetBundles.vue +5 -11
- package/components/fleet/FleetClusters.vue +9 -9
- package/components/fleet/FleetIntro.vue +11 -17
- package/components/fleet/FleetNoWorkspaces.vue +2 -2
- package/components/fleet/FleetRepos.vue +63 -27
- package/components/fleet/FleetResources.vue +6 -1
- package/components/fleet/FleetStatus.vue +3 -3
- package/components/fleet/FleetSummary.vue +35 -30
- package/components/fleet/ForceDirectedTreeChart/index.vue +9 -3
- package/components/fleet/__tests__/FleetSummary.test.ts +316 -0
- package/components/form/ArrayList.vue +22 -18
- package/components/form/ArrayListSelect.vue +5 -0
- package/components/form/BannerSettings.vue +3 -0
- package/components/form/ClusterAppearance.vue +132 -0
- package/components/form/ColorInput.vue +1 -0
- package/components/form/Error.vue +3 -3
- package/components/form/FileSelector.vue +1 -0
- package/components/form/Footer.vue +2 -2
- package/components/form/GitPicker.vue +83 -38
- package/components/form/KeyValue.vue +70 -48
- package/components/form/LabeledSelect.vue +145 -41
- package/components/form/Labels.vue +3 -1
- package/components/form/NameNsDescription.vue +26 -9
- package/components/form/Password.vue +3 -1
- package/components/form/ResourceLabeledSelect.vue +187 -0
- package/components/form/ResourceTabs/index.vue +31 -15
- package/components/form/SecretSelector.vue +93 -18
- package/components/form/SelectOrCreateAuthSecret.vue +132 -59
- package/components/form/SimpleSecretSelector.vue +88 -28
- package/components/form/Taints.vue +13 -7
- package/components/form/__tests__/BannerSettings.test.ts +53 -0
- package/components/form/__tests__/KeyValue.test.ts +120 -11
- package/components/form/__tests__/LabeledSelect.test.ts +0 -18
- package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +25 -15
- package/components/form/__tests__/Taints.test.ts +70 -0
- package/components/form/labeled-select-utils/labeled-select-pagination.ts +151 -0
- package/components/form/labeled-select-utils/labeled-select.utils.ts +122 -0
- package/components/formatter/AppSummaryGraph.vue +2 -2
- package/components/formatter/Checked.vue +11 -3
- package/components/formatter/CloudCredPublicData.vue +30 -0
- package/components/formatter/ClusterLink.vue +2 -2
- package/components/formatter/ClusterProvider.vue +1 -18
- package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
- package/components/formatter/FleetSummaryGraph.vue +25 -12
- package/components/formatter/ImagePercentageBar.vue +0 -4
- package/components/formatter/IngressTarget.vue +18 -7
- package/components/formatter/Link.vue +2 -2
- package/components/formatter/LinkDetail.vue +2 -2
- package/components/formatter/LinkDetailImage.vue +2 -2
- package/components/formatter/LinkName.vue +2 -2
- package/components/formatter/LiveDuration.vue +1 -1
- package/components/formatter/PercentageBar.vue +1 -1
- package/components/formatter/PrincipalGroupBindings.vue +2 -2
- package/components/formatter/SecretType.vue +2 -2
- package/components/formatter/VirtualServiceGateways.vue +2 -2
- package/components/formatter/WorkloadDetailEndpoints.vue +12 -22
- package/components/formatter/__tests__/Checked.test.ts +19 -0
- package/components/formatter/__tests__/LinkDetail.test.ts +5 -5
- package/components/formatter/__tests__/WorkloadDetailEndpoints.test.ts +81 -0
- package/components/nav/Group.vue +9 -7
- package/components/nav/Header.vue +85 -46
- package/components/nav/Jump.vue +19 -9
- package/components/nav/NamespaceFilter.vue +8 -1
- package/components/nav/TopLevelMenu.vue +392 -136
- package/components/nav/Type.vue +71 -106
- package/components/nav/WindowManager/ContainerLogs.vue +120 -19
- package/components/nav/WindowManager/ContainerShell.vue +6 -1
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
- package/components/nav/WindowManager/index.vue +11 -10
- package/components/nav/__tests__/TopLevelMenu.test.ts +400 -6
- package/components/nav/__tests__/Type.test.ts +322 -97
- package/components/nuxt/nuxt-child.js +9 -78
- package/components/nuxt/nuxt-error.vue +1 -1
- package/components/nuxt/nuxt-link.client.js +13 -95
- package/{layouts → components/templates}/blank.vue +1 -1
- package/{layouts → components/templates}/default.vue +11 -101
- package/{layouts → components/templates}/error.vue +13 -26
- package/{layouts → components/templates}/home.vue +4 -1
- package/{layouts → components/templates}/plain.vue +4 -1
- package/{layouts → components/templates}/standalone.vue +1 -5
- package/{layouts → components/templates}/unauthenticated.vue +2 -3
- package/composables/useCompactInput.test.ts +36 -0
- package/composables/useCompactInput.ts +20 -0
- package/composables/useLabeledFormElement.test.ts +135 -0
- package/composables/useLabeledFormElement.ts +138 -0
- package/config/harvester-manager-types.js +2 -0
- package/config/home-links.js +2 -1
- package/config/labels-annotations.js +2 -1
- package/config/middleware.js +0 -6
- package/config/pagination-table-headers.js +57 -0
- package/config/pod-security-admission.ts +1 -1
- package/config/private-label.js +21 -1
- package/config/product/auth.js +1 -0
- package/config/product/explorer.js +166 -45
- package/config/product/fleet.js +6 -1
- package/config/product/legacy.js +2 -11
- package/config/product/manager.js +51 -25
- package/config/query-params.js +2 -0
- package/config/roles.ts +23 -0
- package/config/router/index.js +23 -0
- package/config/router/navigation-guards/attempt-first-login.js +73 -0
- package/config/router/navigation-guards/authentication.js +63 -0
- package/config/router/navigation-guards/i18n.js +13 -0
- package/config/router/navigation-guards/index.js +16 -0
- package/config/router/navigation-guards/load-initial-settings.js +15 -0
- package/config/router/routes.js +487 -0
- package/config/settings.ts +31 -2
- package/config/store.js +8 -4
- package/config/system-namespaces.js +3 -0
- package/config/table-headers.js +66 -1
- package/config/types.js +35 -20
- package/config/uiplugins.js +10 -5
- package/core/plugin-helpers.js +4 -6
- package/core/plugin-routes.ts +56 -114
- package/core/plugin.ts +18 -11
- package/core/plugins-loader.js +7 -9
- package/core/plugins.js +289 -285
- package/core/types-provisioning.ts +7 -0
- package/creators/app/app.package.json +2 -1
- package/creators/app/files/.eslintignore +0 -2
- package/creators/app/files/.gitlab-ci.yml +14 -0
- package/creators/app/files/.vscode/settings.json +0 -1
- package/creators/app/init +19 -0
- package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +2 -6
- package/creators/pkg/files/.github/workflows/build-extension-charts.yml +2 -6
- package/creators/pkg/init +32 -0
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +119 -0
- package/detail/__tests__/service.test.ts +62 -0
- package/detail/catalog.cattle.io.app.vue +1 -1
- package/detail/cis.cattle.io.clusterscan.vue +14 -3
- package/detail/fleet.cattle.io.bundle.vue +1 -1
- package/detail/fleet.cattle.io.cluster.vue +11 -1
- package/detail/fleet.cattle.io.gitrepo.vue +15 -9
- package/detail/namespace.vue +2 -2
- package/detail/networking.k8s.io.ingress.vue +52 -19
- package/detail/node.vue +22 -3
- package/detail/provisioning.cattle.io.cluster.vue +31 -13
- package/detail/service.vue +1 -1
- package/detail/workload/index.vue +1 -0
- package/dialog/AddCustomBadgeDialog.vue +318 -161
- package/dialog/DeactivateDriverDialog.vue +137 -0
- package/dialog/RollbackWorkloadDialog.vue +2 -2
- package/dialog/RotateCertificatesDialog.vue +0 -21
- package/dialog/ScaleMachineDownDialog.vue +34 -17
- package/directives/clean-html.js +15 -0
- package/directives/clean-tooltip.js +32 -0
- package/directives/focus.js +41 -0
- package/directives/int-number.js +21 -0
- package/directives/positive-int-number.js +19 -0
- package/directives/trim-whitespace.js +19 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +3 -2
- package/edit/__tests__/kontainerDriver.test.ts +107 -0
- package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +12 -1
- package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +2 -3
- package/edit/__tests__/nodeDriver.test.ts +107 -0
- package/edit/__tests__/service.test.ts +85 -0
- package/edit/__tests__/ui.cattle.io.navlink.test.ts +3 -1
- package/edit/auth/AuthProviderWarningBanners.vue +34 -0
- package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +19 -0
- package/edit/auth/__tests__/azuread.test.ts +241 -0
- package/edit/auth/__tests__/oidc.test.ts +137 -0
- package/edit/auth/azuread.vue +133 -31
- package/edit/auth/github.vue +5 -17
- package/edit/auth/googleoauth.vue +6 -23
- package/edit/auth/ldap/index.vue +5 -17
- package/edit/auth/oidc.vue +143 -42
- package/edit/auth/saml.vue +5 -14
- package/edit/catalog.cattle.io.clusterrepo.vue +177 -9
- package/edit/cis.cattle.io.clusterscan.vue +5 -2
- package/edit/cis.cattle.io.clusterscanbenchmark.vue +41 -9
- package/edit/cloudcredential.vue +28 -4
- package/edit/configmap.vue +10 -4
- package/edit/fleet.cattle.io.gitrepo.vue +3 -1
- package/edit/helm.cattle.io.projecthelmchart.vue +29 -19
- package/edit/kontainerDriver.vue +65 -0
- package/edit/logging-flow/Match.vue +10 -9
- package/edit/logging-flow/index.vue +4 -19
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +232 -2
- package/edit/logging.banzaicloud.io.output/index.vue +43 -26
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -3
- package/edit/management.cattle.io.project.vue +3 -53
- package/edit/management.cattle.io.setting.vue +52 -2
- package/edit/management.cattle.io.user.vue +2 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +10 -7
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +21 -16
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +2 -2
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -1
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +15 -3
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +4 -1
- package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +2 -0
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +2 -0
- package/edit/networking.k8s.io.ingress/Rules.vue +8 -3
- package/edit/networking.k8s.io.ingress/index.vue +64 -8
- package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +6 -2
- package/edit/networking.k8s.io.networkpolicy/__tests__/{PolicyRuleTarget.spec.ts → PolicyRuleTarget.test.ts} +46 -7
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +1 -1
- package/edit/networking.k8s.io.networkpolicy/index.vue +2 -0
- package/edit/nodeDriver.vue +65 -0
- package/edit/persistentvolume/index.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +33 -16
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +276 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +3 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +228 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +77 -13
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +391 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +4 -4
- package/edit/provisioning.cattle.io.cluster/index.vue +126 -51
- package/edit/provisioning.cattle.io.cluster/rke2.vue +325 -791
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +217 -0
- package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +123 -129
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +132 -0
- package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
- package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +190 -0
- package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +3 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +148 -0
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
- package/edit/resources.cattle.io.backup.vue +139 -124
- package/edit/resources.cattle.io.restore.vue +146 -126
- package/edit/service.vue +13 -0
- package/edit/serviceaccount.vue +46 -4
- package/edit/token.vue +3 -1
- package/edit/workload/Upgrading.vue +3 -2
- package/edit/workload/__tests__/Job.test.ts +1 -3
- package/edit/workload/__tests__/Upgrading.test.ts +2 -2
- package/edit/workload/index.vue +2 -1
- package/edit/workload/mixins/workload.js +35 -2
- package/edit/workload/storage/emptyDir.vue +2 -2
- package/initialize/App.vue +75 -0
- package/initialize/app-extended.js +128 -0
- package/initialize/entry-helpers.js +546 -0
- package/initialize/entry.js +32 -0
- package/initialize/install-components.js +23 -0
- package/initialize/install-directives.js +59 -0
- package/initialize/install-plugins.js +123 -0
- package/list/__tests__/workload.test.ts +1 -1
- package/list/catalog.cattle.io.app.vue +1 -0
- package/list/cis.cattle.io.clusterscan.vue +16 -10
- package/list/group.principal.vue +2 -2
- package/list/management.cattle.io.feature.vue +16 -16
- package/list/management.cattle.io.setting.vue +1 -0
- package/list/management.cattle.io.user.vue +13 -4
- package/list/networking.k8s.io.ingress.vue +36 -0
- package/list/node.vue +212 -73
- package/list/provisioning.cattle.io.cluster.vue +17 -4
- package/list/ui.cattle.io.navlink.vue +2 -2
- package/list/workload.vue +22 -0
- package/machine-config/__tests__/vmwarevsphere-pool-config-merge.test.ts +30 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +1 -3
- package/machine-config/amazonec2.vue +1 -1
- package/machine-config/azure.vue +2 -1
- package/machine-config/generic.vue +11 -15
- package/machine-config/vmwarevsphere-pool-config-merge.ts +25 -0
- package/machine-config/vmwarevsphere.vue +31 -27
- package/middleware/authenticated.js +23 -399
- package/mixins/__tests__/chart.test.ts +48 -6
- package/mixins/__tests__/create-edit-view.test.ts +2 -3
- package/mixins/auth-config.js +5 -9
- package/mixins/brand.js +102 -96
- package/mixins/chart.js +27 -13
- package/mixins/create-edit-view/index.js +2 -2
- package/mixins/fetch.client.js +42 -48
- package/mixins/labeled-form-element.ts +27 -2
- package/mixins/page-actions.js +7 -5
- package/mixins/resource-fetch-api-pagination.js +304 -0
- package/mixins/resource-fetch-namespaced.js +1 -1
- package/mixins/resource-fetch.js +46 -5
- package/models/__tests__/cluster.test.ts +44 -0
- package/models/__tests__/fleet.cattle.io.cluster.test.ts +36 -0
- package/models/__tests__/management.cattle.io.cluster.test.ts +23 -0
- package/models/__tests__/management.cattle.io.node.ts +85 -0
- package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
- package/models/__tests__/namespace.test.ts +49 -9
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +241 -0
- package/models/__tests__/schema.tests.ts +24 -0
- package/models/__tests__/secret.test.ts +37 -0
- package/models/__tests__/steve-schema.test.ts +73 -0
- package/models/__tests__/storage.k8s.io.storageclass.test.ts +22 -0
- package/models/__tests__/workload.test.ts +91 -0
- package/models/catalog.cattle.io.app.js +8 -0
- package/models/catalog.cattle.io.clusterrepo.js +9 -1
- package/models/catalog.cattle.io.uiplugin.js +7 -8
- package/models/cis.cattle.io.clusterscan.js +29 -8
- package/models/cloudcredential.js +9 -1
- package/models/cluster/node.js +8 -4
- package/models/cluster/schema.js +6 -0
- package/models/cluster.js +33 -0
- package/models/cluster.x-k8s.io.machine.js +1 -1
- package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
- package/models/driver.js +63 -0
- package/models/fleet.cattle.io.cluster.js +27 -11
- package/models/fleet.cattle.io.gitrepo.js +66 -13
- package/models/helm.cattle.io.projecthelmchart.js +1 -1
- package/models/kontainerdriver.js +85 -0
- package/models/management/schema.js +6 -0
- package/models/management.cattle.io.authconfig.js +3 -2
- package/models/management.cattle.io.cluster.js +16 -7
- package/models/management.cattle.io.globalrole.js +2 -0
- package/models/management.cattle.io.kontainerdriver.js +1 -0
- package/models/management.cattle.io.node.js +18 -14
- package/models/management.cattle.io.nodepool.js +17 -0
- package/models/management.cattle.io.project.js +0 -36
- package/models/management.cattle.io.setting.js +11 -7
- package/models/management.cattle.io.user.js +2 -2
- package/models/monitoring.coreos.com.receiver.js +3 -1
- package/models/monitoring.coreos.com.route.js +1 -1
- package/models/namespace.js +1 -1
- package/models/networking.k8s.io.ingress.js +2 -1
- package/models/nodedriver.js +85 -0
- package/models/pod.js +20 -0
- package/models/provisioning.cattle.io.cluster.js +125 -10
- package/models/schema.js +28 -7
- package/models/secret.js +126 -18
- package/models/service.js +2 -0
- package/models/steve-schema.ts +254 -0
- package/models/storage.k8s.io.storageclass.js +1 -1
- package/models/workload.js +17 -0
- package/models/workload.service.js +18 -0
- package/package.json +18 -14
- package/pages/about.vue +12 -6
- package/pages/account/create-key.vue +0 -1
- package/pages/account/index.vue +7 -3
- package/pages/auth/login.vue +106 -103
- package/pages/auth/logout.vue +2 -4
- package/pages/auth/setup.vue +92 -66
- package/pages/auth/verify.vue +30 -24
- package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +2 -17
- package/pages/c/_cluster/apps/charts/chart.vue +54 -9
- package/pages/c/_cluster/apps/charts/index.vue +99 -69
- package/pages/c/_cluster/apps/charts/install.helpers.js +2 -13
- package/pages/c/_cluster/apps/charts/install.vue +12 -11
- package/pages/c/_cluster/auth/config/_id.vue +0 -6
- package/pages/c/_cluster/auth/config/index.vue +15 -9
- package/pages/c/_cluster/auth/roles/index.vue +8 -10
- package/pages/c/_cluster/ecm/index.vue +0 -2
- package/pages/c/_cluster/explorer/ConfigBadge.vue +13 -8
- package/pages/c/_cluster/explorer/EventsTable.vue +18 -0
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +181 -0
- package/pages/c/_cluster/explorer/index.vue +253 -91
- package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +69 -0
- package/pages/c/_cluster/explorer/tools/index.vue +10 -6
- package/pages/c/_cluster/fleet/index.vue +89 -94
- package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +89 -0
- package/pages/c/_cluster/longhorn/index.vue +52 -17
- package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -25
- package/pages/c/_cluster/manager/drivers/kontainerDriver/_id.vue +12 -0
- package/pages/c/_cluster/manager/drivers/kontainerDriver/create.vue +15 -0
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +91 -0
- package/pages/c/_cluster/manager/drivers/nodeDriver/_id.vue +12 -0
- package/pages/c/_cluster/manager/drivers/nodeDriver/create.vue +15 -0
- package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +60 -0
- package/pages/c/_cluster/manager/jwt.authentication/index.vue +235 -0
- package/pages/c/_cluster/manager/pages/_page.vue +4 -5
- package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +4 -0
- package/pages/c/_cluster/monitoring/route-receiver/index.vue +2 -2
- package/pages/c/_cluster/neuvector/index.vue +1 -0
- package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
- package/pages/c/_cluster/settings/banners.vue +86 -10
- package/pages/c/_cluster/settings/brand.vue +261 -38
- package/pages/c/_cluster/settings/index.vue +4 -6
- package/pages/c/_cluster/settings/links.vue +3 -2
- package/pages/c/_cluster/settings/performance.vue +71 -3
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +5 -2
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +12 -8
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +9 -6
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
- package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +11 -5
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +55 -19
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +36 -301
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +14 -6
- package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +52 -106
- package/pages/c/_cluster/uiplugins/index.vue +38 -54
- package/pages/diagnostic.vue +2 -2
- package/pages/fail-whale.vue +103 -42
- package/pages/home.vue +81 -24
- package/pages/prefs.vue +8 -4
- package/pages/support/index.vue +14 -10
- package/pkg/auto-import.js +1 -1
- package/plugins/axios.js +0 -36
- package/plugins/back-button.js +3 -5
- package/plugins/clean-html-directive.js +5 -30
- package/plugins/clean-html.js +53 -0
- package/plugins/clean-tooltip-directive.js +6 -31
- package/plugins/codemirror-loader.js +1 -1
- package/plugins/codemirror.js +41 -9
- package/plugins/dashboard-store/__tests__/mutations.test.ts +389 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
- package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
- package/plugins/dashboard-store/actions.js +132 -25
- package/plugins/dashboard-store/classify.js +1 -18
- package/plugins/dashboard-store/getters.js +154 -44
- package/plugins/dashboard-store/index.js +0 -111
- package/plugins/dashboard-store/mutations.js +150 -52
- package/plugins/dashboard-store/resource-class.js +77 -127
- package/plugins/directives.js +6 -39
- package/plugins/ember-cookie.js +13 -0
- package/plugins/global-formatters.js +26 -5
- package/plugins/i18n.js +89 -55
- package/plugins/int-number.js +6 -20
- package/plugins/plugin.js +3 -3
- package/plugins/positive-int-number.js +6 -17
- package/plugins/steve/__tests__/{getters.spec.ts → getters.test.ts} +81 -10
- package/plugins/steve/__tests__/mutations.test.ts +49 -0
- package/plugins/steve/__tests__/resource-utils.test.ts +159 -0
- package/plugins/steve/__tests__/steve-class.test.ts +59 -0
- package/plugins/steve/__tests__/subscribe.spec.ts +4 -1
- package/plugins/steve/__tests__/utils/mutation.test.helpers.ts +105 -0
- package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
- package/plugins/steve/accept-or-reject-socket-message.ts +103 -0
- package/plugins/steve/actions.js +3 -38
- package/plugins/steve/getters.js +164 -61
- package/plugins/steve/hybrid-class.js +5 -1
- package/plugins/steve/mutations.js +24 -3
- package/plugins/steve/norman-class.js +142 -2
- package/{utils → plugins/steve}/projectAndNamespaceFiltering.utils.ts +28 -10
- package/plugins/steve/resource-utils.ts +38 -0
- package/plugins/steve/schema.d.ts +22 -0
- package/plugins/steve/steve-class.js +22 -0
- package/plugins/steve/steve-pagination-utils.ts +368 -0
- package/plugins/steve/subscribe.js +17 -76
- package/plugins/trim-whitespace.js +6 -34
- package/plugins/vue-js-modal.js +1 -1
- package/promptRemove/pod.vue +15 -7
- package/public/index.html +1 -0
- package/rancher-components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/Accordion/Accordion.vue +86 -0
- package/rancher-components/Accordion/index.ts +1 -0
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.test.ts +1 -5
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +4 -4
- package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +57 -24
- package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
- package/rancher-components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/StringList/StringList.test.ts +270 -0
- package/rancher-components/StringList/StringList.vue +65 -26
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +69 -0
- package/scripts/clean +1 -1
- package/scripts/extension/bundle +19 -7
- package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +11 -0
- package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -0
- package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
- package/scripts/extension/helm/package/Dockerfile +1 -1
- package/scripts/extension/helm/scripts/package +11 -3
- package/scripts/extension/helm/scripts/patch +27 -0
- package/scripts/extension/parse-tag-name +4 -4
- package/scripts/extension/publish +25 -14
- package/scripts/publish-shell.sh +11 -1
- package/scripts/serve-pkgs +0 -2
- package/scripts/test-plugins-build.sh +87 -11
- package/scripts/vue-migrate.js +683 -0
- package/server/har-file.js +183 -0
- package/store/__tests__/catalog.test.ts +224 -0
- package/store/__tests__/type-map.test.ts +1122 -0
- package/store/auth.js +23 -4
- package/store/aws.js +53 -6
- package/store/catalog.js +22 -6
- package/store/cru-resource.ts +26 -0
- package/store/customisation.js +35 -0
- package/store/features.js +7 -4
- package/store/i18n.js +11 -0
- package/store/index.js +140 -49
- package/store/plugins.js +8 -4
- package/store/prefs.js +33 -38
- package/store/type-map.js +288 -213
- package/store/type-map.utils.ts +226 -0
- package/tsconfig.json +34 -9
- package/tsconfig.paths.json +21 -0
- package/types/components/labeledSelect.ts +50 -0
- package/types/resources/settings.d.ts +32 -0
- package/types/{userPreferences.d.ts → resources/userPreferences.d.ts} +0 -1
- package/types/shell/index.d.ts +1045 -770
- package/types/store/dashboard-store.types.ts +42 -0
- package/types/store/pagination.types.ts +457 -0
- package/types/store/type-map.ts +30 -0
- package/types/store/vuex.d.ts +9 -0
- package/types/vue-shim.d.ts +51 -0
- package/utils/__tests__/cluster.test.ts +20 -18
- package/utils/__tests__/create-yaml.test.ts +359 -2
- package/utils/__tests__/kontainer.test.ts +180 -0
- package/utils/__tests__/pod-security-admission.test.ts +1 -1
- package/utils/alertmanagerconfig.js +19 -0
- package/utils/array.ts +40 -1
- package/utils/async.ts +2 -0
- package/utils/auth.js +152 -4
- package/utils/axios.js +2 -21
- package/utils/azure.js +24 -0
- package/utils/banners.js +103 -0
- package/utils/clipboard.js +5 -0
- package/utils/cluster.js +1 -1
- package/utils/config.js +4 -0
- package/utils/create-yaml.js +59 -28
- package/utils/custom-validators.js +0 -2
- package/utils/error.js +41 -1
- package/utils/formatter.js +5 -3
- package/utils/git.ts +1 -1
- package/utils/install-redirect.js +1 -1
- package/utils/kontainer.ts +190 -0
- package/utils/object.js +24 -0
- package/utils/pagination-utils.ts +154 -0
- package/utils/pod-security-admission.ts +1 -1
- package/utils/router.js +86 -0
- package/utils/settings.ts +46 -0
- package/utils/time.js +2 -1
- package/utils/unit-tests/ChildRenderingRouterLinkStub.ts +36 -0
- package/utils/url.ts +1 -1
- package/utils/validators/formRules/__tests__/index.test.ts +70 -4
- package/utils/validators/formRules/index.ts +15 -9
- package/utils/validators/index.js +1 -0
- package/utils/validators/setting.js +6 -10
- package/utils/version.js +2 -1
- package/vue.config.js +377 -401
- package/.DS_Store +0 -0
- package/assets/images/providers/aks-black.svg +0 -28
- package/assets/images/providers/aks.svg +0 -31
- package/assets/styles/vendor/vue-js-modal.scss +0 -16
- package/components/ChartPsp.vue +0 -76
- package/components/EventsTable.vue +0 -67
- package/components/TabbedLinks/index.vue +0 -94
- package/components/__tests__/ChartPsp.test.ts +0 -75
- package/components/formatter/__tests__/ClusterProvider.test.ts +0 -28
- package/components/nuxt/nuxt-link.server.js +0 -16
- package/components/nuxt/nuxt.js +0 -101
- package/config/router.js +0 -408
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -237
- package/initialize/App.js +0 -198
- package/initialize/client.js +0 -875
- package/initialize/index.js +0 -364
- package/initialize/layouts.ts +0 -26
- package/middleware/i18n.js +0 -10
- package/middleware/unauthenticated.js +0 -22
- package/mixins/fetch.server.js +0 -73
- package/pages/c/_cluster/apps/index.vue +0 -17
- package/pages/c/_cluster/auth/index.vue +0 -19
- package/pages/c/_cluster/index.vue +0 -17
- package/pages/c/_cluster/legacy/index.vue +0 -22
- package/pages/c/_cluster/manager/index.vue +0 -22
- package/pages/c/_cluster/mcapps/index.vue +0 -21
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +0 -232
- package/pages/c/index.vue +0 -9
- package/pages/rio/mesh.vue +0 -508
- package/plugins/dashboard-store/__tests__/mutations.spec.ts +0 -406
- package/plugins/dashboard-store/rehydrate-all.js +0 -44
- package/plugins/portal-vue.js +0 -4
- package/plugins/portal.js +0 -4
- package/plugins/resize.js +0 -5
- package/plugins/shortkey.js +0 -4
- package/plugins/tooltip.js +0 -4
- package/plugins/transitions.js +0 -4
- package/plugins/v-select.js +0 -4
- package/plugins/vue-clipboard2.js +0 -4
- package/tsconfig.default.json +0 -46
- package/utils/group.js +0 -70
- package/utils/nuxt.js +0 -659
- package/utils/router.scrollBehavior.js +0 -80
- /package/components/__tests__/{Collapse.spec.ts → Collapse.test.ts} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
- /package/models/__tests__/{node.ts → node.test.ts} +0 -0
- /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
- /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
- /package/plugins/steve/__tests__/{header-warnings.spec.ts → header-warnings.test.ts} +0 -0
- /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
- /package/types/{pod-security-admission.ts → resources/pod-security-admission.ts} +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { isArray } from '@shell/utils/array';
|
|
2
|
+
import { set, get, isEmpty } from '@shell/utils/object';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This function accepts a v3 cluster object and mutates its config field to sync values that were set outside Rancher (eg, when an imported cluster is created in its respective cloud provider).
|
|
6
|
+
* Values configured outside of rancher are not automatically propagated to the config field that the UI edits; they are reflected in the aksStatus/eksStatus/gkeStatus.upstreamSpec field.
|
|
7
|
+
* This function works in tandem with diffUpstreamSpec: the former runs when the edit form is initialized and the latter runs when the cluster is saved.
|
|
8
|
+
* @param configPrefix one of aks, eks, gke
|
|
9
|
+
* @param normanCluster v3 cluster object
|
|
10
|
+
*/
|
|
11
|
+
export function syncUpstreamConfig(configPrefix: string, normanCluster: {[key: string]: any}): void {
|
|
12
|
+
const configKey = `${ configPrefix }Config`;
|
|
13
|
+
const statusKey = `${ configPrefix }Status`;
|
|
14
|
+
|
|
15
|
+
const rancherConfig = normanCluster[configKey] || {};
|
|
16
|
+
const upstreamConfig = normanCluster?.[statusKey]?.upstreamSpec || {};
|
|
17
|
+
|
|
18
|
+
if (!isEmpty(upstreamConfig)) {
|
|
19
|
+
Object.keys(upstreamConfig).forEach((key) => {
|
|
20
|
+
if (typeof upstreamConfig[key] === 'object') {
|
|
21
|
+
if (isEmpty(rancherConfig[key]) && !isEmpty(upstreamConfig[key])) {
|
|
22
|
+
set(rancherConfig, key, upstreamConfig[key]);
|
|
23
|
+
}
|
|
24
|
+
} else if ((rancherConfig[key] === null || rancherConfig[key] === undefined) && upstreamConfig[key] !== null && upstreamConfig[key] !== undefined) {
|
|
25
|
+
set(rancherConfig, key, upstreamConfig[key]);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Hosted provider (aks gke eks) edit functionality differs from other k8s resources
|
|
33
|
+
* see ui issue: https://github.com/rancher/rancher/issues/28541
|
|
34
|
+
* backend issue: https://github.com/rancher/rancher/issues/28422
|
|
35
|
+
* The below code is taken from the rancher/ui implementation https://github.com/rancher/ui/blob/master/app/models/cluster.js#L1368
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
function isEmptyObject(object: any) {
|
|
39
|
+
return Object.keys(object).length === 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isObject(val: any) {
|
|
43
|
+
return Object.prototype.toString.call(val) === '[object Object]';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isEmptyStringOrArray(val: any) {
|
|
47
|
+
return val === null || val === undefined || val === '' || (isArray(val) && val.length === 0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* this is NOT a generic object diff.
|
|
52
|
+
* It tries to be as generic as possible but it does make certain assumptions regarding nulls and emtpy arrays/objects
|
|
53
|
+
* if upstream is null and local aks config is empty we do not count this as a change
|
|
54
|
+
* additionally null values on the RHS will be ignored as null cant be sent in this case
|
|
55
|
+
* nodeGroups, nodePools, tags, and labels are not diffed
|
|
56
|
+
* @param upstream aksStatus.upstreamSpec
|
|
57
|
+
* @param local aksConfig
|
|
58
|
+
* @returns aksConfig containing only values which differ from upstream spec, excluding null values
|
|
59
|
+
*/
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
61
|
+
export function diffUpstreamSpec(upstream: any, local: any): any {
|
|
62
|
+
const delta = {};
|
|
63
|
+
const localKeys = Object.keys(local);
|
|
64
|
+
|
|
65
|
+
localKeys.forEach((key) => {
|
|
66
|
+
if (key === 'type') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const upstreamMatch = get(upstream, key);
|
|
71
|
+
const localMatch = get(local, key);
|
|
72
|
+
|
|
73
|
+
if (key !== 'nodeGroups' && key !== 'nodePools') {
|
|
74
|
+
try {
|
|
75
|
+
if (JSON.stringify(upstreamMatch) === JSON.stringify(localMatch)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (key === 'nodeGroups' || key === 'nodePools' || key === 'tags' || key === 'labels') {
|
|
82
|
+
// Node Groups and Node Pools do not require a sync, we can safely send the entire object
|
|
83
|
+
// Tags and Labels (maps) are also included by default because what is present in the config is exactly what should be used on save and any equal maps would have been caught by the JSON isEqual comparison above
|
|
84
|
+
if (!isEmptyStringOrArray(localMatch)) {
|
|
85
|
+
// node groups need ALL data so short circut and send it all
|
|
86
|
+
set(delta, key, localMatch);
|
|
87
|
+
} else {
|
|
88
|
+
// all node groups were deleted
|
|
89
|
+
set(delta, key, []);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isEmptyStringOrArray(upstreamMatch) || isEmptyObject(upstreamMatch)) {
|
|
96
|
+
if (isEmptyStringOrArray(localMatch) || isEmptyObject(localMatch)) {
|
|
97
|
+
if (upstreamMatch !== null && (isArray(localMatch) || isObject(localMatch))) {
|
|
98
|
+
// Empty Arrays and Empty Maps must be sent as such unless the upstream value is null, then the empty array or obj is just an init value
|
|
99
|
+
set(delta, key, localMatch);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
// upstream is empty, local is not, just set
|
|
103
|
+
set(delta, key, localMatch);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
if (localMatch !== null) {
|
|
107
|
+
// entry in og obj
|
|
108
|
+
if (isArray(upstreamMatch)) {
|
|
109
|
+
if (isArray(localMatch)) {
|
|
110
|
+
if (!isEmptyStringOrArray(localMatch) && localMatch.every((m: any) => isObject(m))) {
|
|
111
|
+
// You have more diffing to do
|
|
112
|
+
localMatch.forEach((match: any) => {
|
|
113
|
+
// our most likely candiate for a match is node group name, but lets check the others just incase.
|
|
114
|
+
const matchId = get(match, 'name') || get(match, 'id') || false;
|
|
115
|
+
|
|
116
|
+
if (matchId) {
|
|
117
|
+
let lmatchIdx = 0;
|
|
118
|
+
|
|
119
|
+
// we have soime kind of identifier to find a match in the upstream, so we can diff and insert to new array
|
|
120
|
+
const lMatch = upstreamMatch.find((l: any, idx: number) => {
|
|
121
|
+
const lmatchId = get(l, 'name') || get(l, 'id');
|
|
122
|
+
|
|
123
|
+
if (lmatchId === matchId) {
|
|
124
|
+
lmatchIdx = idx;
|
|
125
|
+
|
|
126
|
+
return l;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (lMatch) {
|
|
131
|
+
// we have a match in the upstream, meaning we've probably made updates to the object itself
|
|
132
|
+
const diffedMatch = diffUpstreamSpec(lMatch, match);
|
|
133
|
+
|
|
134
|
+
if (!isArray(get(delta, key))) {
|
|
135
|
+
set(delta, key, [diffedMatch]);
|
|
136
|
+
} else {
|
|
137
|
+
const target: any[] = delta[key as keyof typeof delta];
|
|
138
|
+
|
|
139
|
+
// diff and push into new array
|
|
140
|
+
target.splice(lmatchIdx, 0, diffedMatch);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// no match in upstream, new entry
|
|
144
|
+
if (!isArray(get(delta, key))) {
|
|
145
|
+
set(delta, key, [match]);
|
|
146
|
+
} else {
|
|
147
|
+
const target: any = delta[key as keyof typeof delta];
|
|
148
|
+
|
|
149
|
+
target.push(match);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
// no match id, all we can do is dumb add
|
|
154
|
+
if (!isArray(get(delta, key))) {
|
|
155
|
+
set(delta, key, [match]);
|
|
156
|
+
} else {
|
|
157
|
+
const target: any = delta[key as keyof typeof delta];
|
|
158
|
+
|
|
159
|
+
target.push(match);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
set(delta, key, localMatch);
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
set(delta, key, localMatch);
|
|
168
|
+
}
|
|
169
|
+
} else if (isObject(upstreamMatch)) {
|
|
170
|
+
if (!isEmptyStringOrArray(localMatch) && !isEmptyObject(localMatch)) {
|
|
171
|
+
if ((Object.keys(upstreamMatch) || []).length > 0) {
|
|
172
|
+
// You have more diffing to do
|
|
173
|
+
set(delta, key, diffUpstreamSpec(upstreamMatch, localMatch));
|
|
174
|
+
} else if (isEmptyObject(upstreamMatch)) {
|
|
175
|
+
// we had a map now we have an empty map
|
|
176
|
+
set(delta, key, {});
|
|
177
|
+
}
|
|
178
|
+
} else if (!isEmptyObject(upstreamMatch) && isEmptyObject(localMatch)) {
|
|
179
|
+
// we had a map now we have an empty map
|
|
180
|
+
set(delta, key, {});
|
|
181
|
+
}
|
|
182
|
+
} else { // upstreamMatch not an array or object
|
|
183
|
+
set(delta, key, localMatch);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return delta;
|
|
190
|
+
}
|
package/utils/object.js
CHANGED
|
@@ -110,6 +110,20 @@ export function remove(obj, path) {
|
|
|
110
110
|
return obj;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* `delete` a property at the given path.
|
|
115
|
+
*
|
|
116
|
+
* This is similar to `remove` but doesn't need any fancy kube obj path splitting
|
|
117
|
+
* and doesn't use `Vue.set` (avoids reactivity)
|
|
118
|
+
*/
|
|
119
|
+
export function deleteProperty(obj, path) {
|
|
120
|
+
const pathAr = path.split('.');
|
|
121
|
+
const propToDelete = pathAr.pop();
|
|
122
|
+
|
|
123
|
+
// Walk down path until final prop, then delete final prop
|
|
124
|
+
delete pathAr.reduce((o, k) => o[k] || {}, obj)[propToDelete];
|
|
125
|
+
}
|
|
126
|
+
|
|
113
127
|
export function getter(path) {
|
|
114
128
|
return function(obj) {
|
|
115
129
|
return get(obj, path);
|
|
@@ -411,3 +425,13 @@ export function pickBy(obj = {}, predicate = (value, key) => false) {
|
|
|
411
425
|
export const toDictionary = (array, callback) => Object.assign(
|
|
412
426
|
{}, ...array.map((item) => ({ [item]: callback(item) }))
|
|
413
427
|
);
|
|
428
|
+
|
|
429
|
+
export function dropKeys(obj, keys) {
|
|
430
|
+
if ( !obj ) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
for ( const k of keys ) {
|
|
435
|
+
delete obj[k];
|
|
436
|
+
}
|
|
437
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { PaginationSettings } from '@shell/types/resources/settings';
|
|
2
|
+
import {
|
|
3
|
+
NAMESPACE_FILTER_ALL_USER as ALL_USER,
|
|
4
|
+
NAMESPACE_FILTER_ALL as ALL,
|
|
5
|
+
NAMESPACE_FILTER_ALL_SYSTEM as ALL_SYSTEM,
|
|
6
|
+
NAMESPACE_FILTER_NAMESPACED_YES as NAMESPACED_YES,
|
|
7
|
+
NAMESPACE_FILTER_NAMESPACED_NO as NAMESPACED_NO,
|
|
8
|
+
NAMESPACE_FILTER_KINDS,
|
|
9
|
+
NAMESPACE_FILTER_NS_FULL_PREFIX,
|
|
10
|
+
NAMESPACE_FILTER_P_FULL_PREFIX,
|
|
11
|
+
} from '@shell/utils/namespace-filter';
|
|
12
|
+
import { PaginationArgs, PaginationParam, PaginationSort } from '@shell/types/store/pagination.types';
|
|
13
|
+
import { sameArrayObjects } from '@shell/utils/array';
|
|
14
|
+
import { isEqual } from '@shell/utils/object';
|
|
15
|
+
import { STEVE_CACHE } from '@shell/store/features';
|
|
16
|
+
import { getPerformanceSetting } from '@shell/utils/settings';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Helper functions for server side pagination
|
|
20
|
+
*/
|
|
21
|
+
class PaginationUtils {
|
|
22
|
+
/**
|
|
23
|
+
* When a ns filter isn't one or more projects/namespaces... what are the valid values?
|
|
24
|
+
*
|
|
25
|
+
* This basically blocks 'Not in a Project'.. which would involve a projectsornamespaces param with every ns not in a project.
|
|
26
|
+
*/
|
|
27
|
+
validNsProjectFilters = [ALL, ALL_SYSTEM, ALL_USER, ALL_SYSTEM, NAMESPACE_FILTER_KINDS.NAMESPACE, NAMESPACE_FILTER_KINDS.PROJECT, NAMESPACED_YES, NAMESPACED_NO];
|
|
28
|
+
|
|
29
|
+
private getSettings({ rootGetters }: any): PaginationSettings {
|
|
30
|
+
const perf = getPerformanceSetting(rootGetters);
|
|
31
|
+
|
|
32
|
+
return perf.serverPagination;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
isSteveCacheEnabled({ rootGetters }: any): boolean {
|
|
36
|
+
// We always get Feature flags as part of start up (see `dispatch('features/loadServer')` in loadManagement)
|
|
37
|
+
return rootGetters['features/get']?.(STEVE_CACHE);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Is pagination enabled at a global level or for a specific resource
|
|
42
|
+
*/
|
|
43
|
+
isEnabled({ rootGetters }: any, enabledFor: {
|
|
44
|
+
store: string,
|
|
45
|
+
resource?: {
|
|
46
|
+
id: string,
|
|
47
|
+
}
|
|
48
|
+
}) {
|
|
49
|
+
// Cache must be enabled to support pagination api
|
|
50
|
+
if (!this.isSteveCacheEnabled({ rootGetters })) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const settings = this.getSettings({ rootGetters });
|
|
55
|
+
|
|
56
|
+
// No setting, not enabled
|
|
57
|
+
if (!settings?.enabled) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Missing required params, not enabled
|
|
62
|
+
if (!enabledFor) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const storeSettings = settings.stores?.[enabledFor.store];
|
|
67
|
+
|
|
68
|
+
// No pagination setting for target store, not enabled
|
|
69
|
+
if (!storeSettings) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Not interested in a resource, so just top level settings are checked
|
|
74
|
+
if (!enabledFor.resource) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Store says all resources are enabled
|
|
79
|
+
if (storeSettings.resources.enableAll) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// given a resource... but no id... invalid
|
|
84
|
+
if (!enabledFor.resource.id) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Store says only some (those that have pagination columns not from schema and no custom list)
|
|
89
|
+
const isGeneric =
|
|
90
|
+
!rootGetters['type-map/configuredHeaders'](enabledFor.resource.id) &&
|
|
91
|
+
!rootGetters['type-map/configuredPaginationHeaders'](enabledFor.resource.id) &&
|
|
92
|
+
!rootGetters['type-map/hasCustomList'](enabledFor.resource.id);
|
|
93
|
+
|
|
94
|
+
if (storeSettings.resources.enableSome.generic && isGeneric) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (storeSettings.resources.enableSome.enabled.includes(enabledFor.resource.id)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
validateNsProjectFilters(nsProjectFilters: string[]) {
|
|
106
|
+
return nsProjectFilters?.every((f) => this.validateNsProjectFilter(f));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
validateNsProjectFilter(nsProjectFilter: string) {
|
|
110
|
+
if (nsProjectFilter.startsWith(NAMESPACE_FILTER_NS_FULL_PREFIX) || nsProjectFilter.startsWith(NAMESPACE_FILTER_P_FULL_PREFIX)) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return this.validNsProjectFilters.includes(nsProjectFilter);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
paginationFilterEqual(a: PaginationParam, b: PaginationParam): boolean {
|
|
118
|
+
if (a.param !== b.param || a.equals !== b.equals) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return sameArrayObjects(a.fields, b.fields, true);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
paginationFiltersEqual(a: PaginationParam[], b: PaginationParam[]): boolean {
|
|
126
|
+
if (!!a && a?.length !== b?.length) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (let i = 0; i < a.length; i++) {
|
|
131
|
+
if (!this.paginationFilterEqual(a[i], b[i])) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
paginationEqual(a?: PaginationArgs, b?: PaginationArgs): boolean {
|
|
140
|
+
const {
|
|
141
|
+
filters: aFilter = [], sort: aSort = [], projectsOrNamespaces: aPN = [], ...aPrimitiveTypes
|
|
142
|
+
} = a || {};
|
|
143
|
+
const {
|
|
144
|
+
filters: bFilter = [], sort: bSort = [], projectsOrNamespaces: bPN = [], ...bPrimitiveTypes
|
|
145
|
+
} = b || {};
|
|
146
|
+
|
|
147
|
+
return isEqual(aPrimitiveTypes, bPrimitiveTypes) &&
|
|
148
|
+
this.paginationFiltersEqual(aFilter, bFilter) &&
|
|
149
|
+
this.paginationFiltersEqual(aPN, bPN) &&
|
|
150
|
+
sameArrayObjects<PaginationSort>(aSort, bSort, true);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export default new PaginationUtils();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { reduce, filter, keys } from 'lodash';
|
|
2
2
|
import { PSALabelPrefix, PSALabelsNamespaces } from '@shell/config/pod-security-admission';
|
|
3
3
|
import { camelToTitle } from '@shell/utils/string';
|
|
4
|
-
import { PSA } from '@shell/types/pod-security-admission';
|
|
4
|
+
import { PSA } from '@shell/types/resources/pod-security-admission';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Return PSA labels present in the resource
|
package/utils/router.js
CHANGED
|
@@ -25,3 +25,89 @@ export function queryParamsFor(current, qp, defaults = {}) {
|
|
|
25
25
|
|
|
26
26
|
return query;
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
export function getClusterFromRoute(to) {
|
|
30
|
+
let cluster = to.params?.cluster;
|
|
31
|
+
|
|
32
|
+
if (!cluster) {
|
|
33
|
+
cluster = findMeta(to, 'cluster');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return cluster;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getProductFromRoute(to) {
|
|
40
|
+
let product = to.params?.product;
|
|
41
|
+
|
|
42
|
+
if ( !product ) {
|
|
43
|
+
const match = to.name?.match(/^c-cluster-([^-]+)/);
|
|
44
|
+
|
|
45
|
+
if ( match ) {
|
|
46
|
+
product = match[1];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// If still no product, see if the route indicates the product via route metadata
|
|
51
|
+
if (!product) {
|
|
52
|
+
product = findMeta(to, 'product');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return product;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const getPackageFromRoute = (route) => {
|
|
59
|
+
if (!route?.meta) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Sometimes meta is an array... sometimes not
|
|
63
|
+
const arraySafe = Array.isArray(route.meta) ? route.meta : [route.meta];
|
|
64
|
+
|
|
65
|
+
return arraySafe.find((m) => !!m.pkg)?.pkg;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getResourceFromRoute = (to) => {
|
|
69
|
+
let resource = to.params?.resource;
|
|
70
|
+
|
|
71
|
+
if (!resource) {
|
|
72
|
+
resource = findMeta(to, 'resource');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return resource;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Given a route it will look through the matching parent routes to see if any match the fn (predicate) criteria
|
|
80
|
+
*
|
|
81
|
+
* @param {*} to a VueRouter Route object
|
|
82
|
+
* @param {*} fn fn is a predicate which is passed a matched route. It will return true to indicate there was a matching route and false otherwise
|
|
83
|
+
* @returns true if a matching route was found, false otherwise
|
|
84
|
+
*/
|
|
85
|
+
export const routeMatched = (to, fn) => {
|
|
86
|
+
const matched = to?.matched || [];
|
|
87
|
+
|
|
88
|
+
return !!matched.find(fn);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks to see if the route requires authentication by taking a look at the route and it's parents 'meta' to see if it
|
|
93
|
+
* contains { requiresAuthentication: true }
|
|
94
|
+
* @param {*} to a VueRouter Route object
|
|
95
|
+
* @returns true if the route requires authentication, false otherwise
|
|
96
|
+
*/
|
|
97
|
+
export const routeRequiresAuthentication = (to) => {
|
|
98
|
+
return routeMatched(to, (matched) => matched.meta?.requiresAuthentication);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function findMeta(route, key) {
|
|
102
|
+
if (route?.meta) {
|
|
103
|
+
const meta = Array.isArray(route.meta) ? route.meta : [route.meta];
|
|
104
|
+
|
|
105
|
+
for (let i = 0; i < meta.length; i++) {
|
|
106
|
+
if (meta[i][key]) {
|
|
107
|
+
return meta[i][key];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
package/utils/settings.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { MANAGEMENT } from '@shell/config/types';
|
|
2
2
|
import { Store } from 'vuex';
|
|
3
3
|
import { DEFAULT_PERF_SETTING, PerfSettings, SETTING } from '@shell/config/settings';
|
|
4
|
+
import { pluralize } from '@shell/utils/string';
|
|
5
|
+
import { _MULTI } from '@shell/plugins/dashboard-store/actions';
|
|
4
6
|
|
|
5
7
|
export const fetchOrCreateSetting = async(store: Store<any>, id: string, val: string, save = true): Promise<any> => {
|
|
6
8
|
let setting;
|
|
@@ -34,6 +36,50 @@ export const fetchSetting = async(store: Store<any>, id: string): Promise<any> =
|
|
|
34
36
|
return setting;
|
|
35
37
|
};
|
|
36
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Carefully fetch mgmt settings
|
|
41
|
+
*
|
|
42
|
+
* Ensures that
|
|
43
|
+
* - Concurrent calls to this function will only result in a single http request
|
|
44
|
+
* - Subsequent calls, when either logged in or logged out, will only result in a single http request
|
|
45
|
+
* - Logged out call will fetch partial settings, after logging in another call will fetch all settings
|
|
46
|
+
*
|
|
47
|
+
* Will be used in many places, particularly multiple times when loading the dashboard
|
|
48
|
+
*
|
|
49
|
+
* Note - We need to specify the url for cases where it can't be determined (i.e. we haven't fetched schemas)
|
|
50
|
+
*/
|
|
51
|
+
export const fetchInitialSettings = async(store: Store<any>): Promise<any> => {
|
|
52
|
+
const generation = store.getters['management/generation'](MANAGEMENT.SETTING);
|
|
53
|
+
// We use this as it copies the previous mechanism this was based on (in findAll)
|
|
54
|
+
// There is the getter `auth/loggedInAs` (which is set given `fromHeader`), but that's initialised after the first call to here (see `authenticated`)
|
|
55
|
+
const header = store.getters['auth/fromHeader'];
|
|
56
|
+
const authed = `${ header }` === 'true' || `${ header }` === 'none';
|
|
57
|
+
|
|
58
|
+
if (authed) {
|
|
59
|
+
// We're authed, we will always get the full list
|
|
60
|
+
return await store.dispatch('management/findAll', {
|
|
61
|
+
type: MANAGEMENT.SETTING,
|
|
62
|
+
opt: { url: `/v1/${ pluralize(MANAGEMENT.SETTING) }` }
|
|
63
|
+
} );
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!generation) {
|
|
67
|
+
// We're not authed, and haven't previously fetched settings (no generation)
|
|
68
|
+
// Fetch settings, put them in the store, but don't say we've got all yet (so subsequent calls will run)
|
|
69
|
+
return await store.dispatch('management/findAll', {
|
|
70
|
+
type: MANAGEMENT.SETTING,
|
|
71
|
+
opt: {
|
|
72
|
+
url: `/v1/${ pluralize(MANAGEMENT.SETTING) }`,
|
|
73
|
+
load: _MULTI,
|
|
74
|
+
redirectUnauthorized: false
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// We're not authed, but have a previous value, no need to make a http request to fetch again
|
|
80
|
+
return store.getters['management/all'](MANAGEMENT.SETTING);
|
|
81
|
+
};
|
|
82
|
+
|
|
37
83
|
export const setSetting = async(store: Store<any>, id: string, val: string): Promise<any> => {
|
|
38
84
|
const setting = await fetchOrCreateSetting(store, id, val, false);
|
|
39
85
|
|
package/utils/time.js
CHANGED
|
@@ -10,7 +10,7 @@ export function diffFrom(value, from, t) {
|
|
|
10
10
|
const now = day();
|
|
11
11
|
|
|
12
12
|
from = from || now;
|
|
13
|
-
const diff = value.diff(
|
|
13
|
+
const diff = value.diff(from, 'seconds');
|
|
14
14
|
|
|
15
15
|
let absDiff = Math.abs(diff);
|
|
16
16
|
|
|
@@ -34,6 +34,7 @@ export function diffFrom(value, from, t) {
|
|
|
34
34
|
diff,
|
|
35
35
|
absDiff,
|
|
36
36
|
label,
|
|
37
|
+
// i18n-uses unit.day, unit.hour, unit.min, unit.sec
|
|
37
38
|
unitsKey: `unit.${ LABELS[i] }`,
|
|
38
39
|
units: LABELS[i],
|
|
39
40
|
next,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { RouterLinkStub } from '@vue/test-utils';
|
|
2
|
+
import { NavigationFailure, Route } from 'vue-router';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* See {@link RouterLinkSlotArgument} in vue-router
|
|
6
|
+
*/
|
|
7
|
+
export interface RouterLinkSlotArgumentOptional {
|
|
8
|
+
href?: string;
|
|
9
|
+
route?: Route;
|
|
10
|
+
navigate?: (e?: MouseEvent) => Promise<undefined | NavigationFailure>;
|
|
11
|
+
isActive?: boolean;
|
|
12
|
+
isExactActive?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* This is a workaround because VueUtils RouterLinkStub doesn't currently support the slot api.
|
|
17
|
+
*
|
|
18
|
+
* See @link https://github.com/vuejs/vue-test-utils/issues/1803#issuecomment-940884170
|
|
19
|
+
*
|
|
20
|
+
* @param slotProps Provide arguments that you want passed to the child rendered by router-link
|
|
21
|
+
* @returns A stub
|
|
22
|
+
*/
|
|
23
|
+
export function createChildRenderingRouterLinkStub(slotProps?: RouterLinkSlotArgumentOptional): typeof RouterLinkStub | any {
|
|
24
|
+
return {
|
|
25
|
+
...RouterLinkStub,
|
|
26
|
+
render() {
|
|
27
|
+
return this.$scopedSlots.default({
|
|
28
|
+
href: slotProps?.href || '',
|
|
29
|
+
route: slotProps?.route || ({} as any),
|
|
30
|
+
navigate: slotProps?.navigate || (() => {}),
|
|
31
|
+
isActive: slotProps?.isActive || false,
|
|
32
|
+
isExactActive: slotProps?.isExactActive || false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
package/utils/url.ts
CHANGED