@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.4
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/apis/impl/apis.ts +6 -0
- package/apis/index.ts +26 -0
- package/apis/intf/resources-api/cluster-api.ts +18 -0
- package/apis/intf/resources-api/mgmt-api.ts +15 -0
- package/apis/intf/resources-api/resource-base.ts +107 -0
- package/apis/intf/resources-api/resource-constants.ts +147 -0
- package/apis/intf/resources-api/resources-api.ts +143 -0
- package/apis/intf/resources.ts +49 -0
- package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
- package/apis/intf/shell-api/proxy.ts +216 -0
- package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
- package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
- package/apis/intf/shell.ts +12 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
- package/apis/resources/index.ts +22 -0
- package/apis/resources/resources-api-class.ts +187 -0
- package/apis/shell/__tests__/proxy.test.ts +369 -0
- package/apis/shell/index.ts +8 -1
- package/apis/shell/modal.ts +4 -1
- package/apis/shell/notifications.ts +9 -6
- package/apis/shell/proxy.ts +256 -0
- package/apis/shell/slide-in.ts +4 -1
- package/apis/vue-shim.d.ts +2 -1
- package/assets/data/aws-regions.json +4 -0
- package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/fonts/_fontstack.scss +132 -8
- package/assets/styles/global/_layout.scss +4 -0
- package/assets/translations/en-us.yaml +165 -45
- package/assets/translations/zh-hans.yaml +1 -7
- package/chart/monitoring/ClusterSelector.vue +0 -21
- package/chart/monitoring/index.vue +10 -1
- package/chart/monitoring/prometheus/index.vue +6 -3
- package/components/ActionDropdownShell.vue +2 -1
- package/components/CruResource.vue +161 -14
- package/components/CruResourceFooter.vue +9 -5
- package/components/ExplorerMembers.vue +8 -4
- package/components/ExplorerProjectsNamespaces.vue +11 -7
- package/components/GrowlManager.vue +4 -0
- package/components/InstallHelmCharts.vue +2 -2
- package/components/LandingPagePreference.vue +14 -5
- package/components/MgmtNodeList.vue +184 -0
- package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
- package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
- package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
- package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +17 -1
- package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
- package/components/Resource/Detail/Metadata/index.vue +6 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
- package/components/Resource/Detail/SpacedRow.vue +3 -1
- package/components/Resource/Detail/TitleBar/index.vue +10 -11
- package/components/ResourceDetail/index.vue +1 -1
- package/components/ResourceList/Masthead.vue +19 -9
- package/components/ResourceList/index.vue +82 -1
- package/components/RichTranslation.vue +5 -2
- package/components/SelectIconGrid.vue +0 -10
- package/components/Setting.vue +1 -0
- package/components/SingleClusterInfo.vue +1 -0
- package/components/SortableTable/__tests__/sorting.test.ts +126 -0
- package/components/SortableTable/index.vue +6 -9
- package/components/SortableTable/selection.js +23 -5
- package/components/SortableTable/sorting.js +6 -3
- package/components/SubtleLink.vue +31 -6
- package/components/Tabbed/Tab.vue +29 -3
- package/components/Tabbed/index.vue +25 -3
- package/components/TableOfContents/TableOfContents.vue +109 -0
- package/components/TableOfContents/composables.ts +258 -0
- package/components/Window/ContainerShell.vue +21 -11
- package/components/Window/__tests__/ContainerShell.test.ts +107 -37
- package/components/Wizard.vue +23 -17
- package/components/fleet/AppCoChartGrid.vue +401 -0
- package/components/fleet/AppCoEmptyState.vue +127 -0
- package/components/fleet/AppCoPageHeader.vue +119 -0
- package/components/fleet/AppCoVersionSelect.vue +70 -0
- package/components/fleet/FleetBundles.vue +100 -12
- package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
- package/components/fleet/FleetClusterTargets/index.vue +226 -161
- package/components/fleet/FleetIntro.vue +7 -3
- package/components/fleet/FleetNoWorkspaces.vue +7 -3
- package/components/fleet/FleetSecretSelector.vue +5 -3
- package/components/fleet/FleetValuesFrom.vue +8 -2
- package/components/fleet/GitRepoTargetTab.vue +0 -2
- package/components/fleet/HelmOpAdvancedTab.vue +19 -53
- package/components/fleet/HelmOpAppCoConfigTab.vue +593 -0
- package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
- package/components/fleet/HelmOpResourcesSection.vue +82 -0
- package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
- package/components/fleet/HelmOpTargetTab.vue +64 -60
- package/components/fleet/HelmOpValuesTab.vue +129 -105
- package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
- package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
- package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +402 -115
- package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
- package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
- package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
- package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
- package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
- package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
- package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
- package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
- package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
- package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
- package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
- package/components/fleet/dashboard/Empty.vue +8 -4
- package/components/fleet/dashboard/ResourceCard.vue +28 -0
- package/components/fleet/dashboard/ResourceDetails.vue +28 -0
- package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
- package/components/form/ArrayList.vue +61 -4
- package/components/form/KeyValue.vue +23 -2
- package/components/form/LabeledSelect.vue +59 -4
- package/components/form/Labels.vue +22 -3
- package/components/form/NameNsDescription.vue +24 -5
- package/components/form/ResourceTabs/index.vue +1 -0
- package/components/form/Security.vue +6 -2
- package/components/form/WorkloadPorts.vue +2 -7
- package/components/form/__tests__/NameNsDescription.test.ts +75 -0
- package/components/form/__tests__/Security.test.ts +76 -0
- package/components/formatter/Autoscaler.vue +4 -4
- package/components/formatter/ClusterKubeVersion.vue +27 -0
- package/components/formatter/ClusterLink.vue +1 -7
- package/components/formatter/ClusterProvider.vue +6 -10
- package/components/formatter/FleetSummaryGraph.vue +0 -3
- package/components/formatter/InternalExternalIP.vue +10 -4
- package/components/formatter/MachineSummaryGraph.vue +1 -1
- package/components/formatter/PodsUsage.vue +2 -2
- package/components/formatter/ServiceTargets.vue +26 -7
- package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
- package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
- package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
- package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
- package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
- package/components/nav/Header.vue +4 -0
- package/components/nav/NamespaceFilter.vue +2 -2
- package/components/nav/TopLevelMenu.helper.ts +15 -3
- package/components/nav/TopLevelMenu.vue +22 -6
- package/components/nav/__tests__/Header.test.ts +15 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +263 -21
- package/components/templates/default.vue +9 -4
- package/components/templates/home.vue +23 -0
- package/components/templates/plain.vue +23 -0
- package/components/templates/standalone.vue +17 -0
- package/composables/useFormValidation.ts +93 -0
- package/composables/useHelmOpResources.test.ts +56 -0
- package/composables/useHelmOpResources.ts +32 -0
- package/composables/useStateColor.test.ts +325 -0
- package/composables/useStateColor.ts +128 -0
- package/composables/useVeeValidateField.test.ts +159 -0
- package/composables/useVeeValidateField.ts +67 -0
- package/config/home-links.js +1 -1
- package/config/labels-annotations.js +1 -0
- package/config/pagination-table-headers.js +18 -1
- package/config/product/explorer.js +17 -4
- package/config/product/manager.js +84 -21
- package/config/router/index.js +16 -0
- package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
- package/config/router/navigation-guards/authentication.js +10 -4
- package/config/router/routes.js +26 -6
- package/config/settings.ts +0 -2
- package/config/table-headers.js +23 -5
- package/config/types.js +11 -1
- package/core/__tests__/plugin-products.test.ts +904 -20
- package/core/plugin-products-base.ts +110 -10
- package/core/plugin-products.ts +4 -0
- package/core/plugin-types.ts +194 -31
- package/core/plugin.ts +18 -7
- package/core/productDebugger.js +9 -4
- package/core/types-provisioning.ts +77 -31
- package/core/types.ts +72 -22
- package/detail/__tests__/pod.test.ts +41 -0
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
- package/detail/__tests__/workload.test.ts +3 -152
- package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
- package/detail/harvesterhci.io.management.cluster.vue +6 -2
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +34 -14
- package/detail/workload/index.vue +12 -55
- package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +105 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
- package/edit/auth/__tests__/azuread.test.ts +247 -39
- package/edit/auth/__tests__/github.test.ts +234 -0
- package/edit/auth/__tests__/oidc.test.ts +26 -6
- package/edit/auth/__tests__/saml.test.ts +196 -0
- package/edit/auth/azuread.vue +197 -56
- package/edit/auth/github.vue +72 -13
- package/edit/auth/ldap/__tests__/index.test.ts +206 -0
- package/edit/auth/ldap/config.vue +8 -0
- package/edit/auth/ldap/index.vue +75 -1
- package/edit/auth/oidc.vue +119 -73
- package/edit/auth/saml.vue +76 -12
- package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
- package/edit/fleet.cattle.io.helmop.vue +491 -136
- package/edit/management.cattle.io.user.vue +5 -2
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
- package/edit/networking.k8s.io.ingress/index.vue +75 -20
- package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +11 -7
- package/edit/provisioning.cattle.io.cluster/rke2.vue +92 -14
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +22 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
- package/edit/secret/__tests__/ssh.test.ts +5 -6
- package/edit/secret/basic.vue +31 -0
- package/edit/secret/index.vue +68 -17
- package/edit/secret/registry.vue +38 -0
- package/edit/secret/ssh.vue +29 -0
- package/edit/secret/tls.vue +30 -0
- package/edit/service.vue +4 -4
- package/edit/workload/Upgrading.vue +3 -3
- package/edit/workload/__tests__/Upgrading.test.ts +6 -9
- package/edit/workload/mixins/workload.js +2 -1
- package/list/fleet.cattle.io.bundle.vue +7 -104
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
- package/list/group.principal.vue +5 -4
- package/list/harvesterhci.io.management.cluster.vue +8 -9
- package/list/management.cattle.io.user.vue +12 -9
- package/list/provisioning.cattle.io.cluster.vue +268 -180
- package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
- package/mixins/__tests__/auth-config.test.ts +90 -0
- package/mixins/__tests__/chart.test.ts +206 -0
- package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
- package/mixins/auth-config.js +7 -0
- package/mixins/brand.js +2 -1
- package/mixins/chart.js +22 -9
- package/mixins/child-hook.js +12 -6
- package/mixins/create-edit-view/impl.js +5 -3
- package/mixins/resource-fetch-api-pagination.js +62 -6
- package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
- package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
- package/models/__tests__/fleet-application.test.ts +175 -0
- package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
- package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
- package/models/__tests__/management.cattle.io.node.ts +28 -5
- package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
- package/models/__tests__/namespace.test.ts +36 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +81 -11
- package/models/__tests__/workload.test.ts +401 -26
- package/models/base-cluster.x-k8s.io.js +26 -0
- package/models/catalog.cattle.io.clusterrepo.js +28 -4
- package/models/cluster.js +1 -1
- package/models/cluster.x-k8s.io.machine.js +4 -22
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
- package/models/cluster.x-k8s.io.machineset.js +2 -20
- package/models/compliance.cattle.io.clusterscan.js +165 -2
- package/models/ext.cattle.io.kubeconfig.ts +4 -7
- package/models/fleet-application.js +7 -1
- package/models/fleet.cattle.io.helmop.js +20 -1
- package/models/management.cattle.io.cluster.js +434 -41
- package/models/management.cattle.io.node.js +50 -7
- package/models/management.cattle.io.nodepool.js +1 -1
- package/models/namespace.js +1 -1
- package/models/networking.k8s.io.ingress.js +12 -4
- package/models/pod.js +33 -1
- package/models/provisioning.cattle.io.cluster.js +51 -334
- package/models/rke.cattle.io.etcdsnapshot.js +1 -2
- package/models/workload.js +108 -13
- package/models/workload.service.js +5 -0
- package/package.json +22 -39
- package/pages/__tests__/readme.test.ts +49 -0
- package/pages/about.vue +5 -6
- package/pages/auth/login.vue +0 -35
- package/pages/auth/setup.vue +13 -3
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
- package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
- package/pages/c/_cluster/apps/charts/chart.vue +62 -9
- package/pages/c/_cluster/apps/charts/index.vue +48 -10
- package/pages/c/_cluster/apps/charts/install.vue +122 -113
- package/pages/c/_cluster/auth/roles/index.vue +5 -4
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
- package/pages/c/_cluster/explorer/index.vue +5 -49
- package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
- package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
- package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
- package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
- package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
- package/pages/c/_cluster/fleet/application/create.vue +187 -136
- package/pages/c/_cluster/fleet/application/index.vue +5 -3
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
- package/pages/c/_cluster/fleet/index.vue +2 -2
- package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
- package/pages/c/_cluster/istio/index.vue +21 -6
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -0
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +815 -2
- package/pages/c/_cluster/uiplugins/index.vue +218 -197
- package/pages/diagnostic.vue +13 -17
- package/pages/fail-whale.vue +30 -7
- package/pages/home.vue +93 -306
- package/pages/readme.vue +88 -0
- package/plugins/clean-html.d.ts +9 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +181 -0
- package/plugins/dashboard-store/actions.js +40 -18
- package/plugins/dashboard-store/resource-class.js +67 -9
- package/plugins/steve/__tests__/actions.test.ts +212 -0
- package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
- package/plugins/steve/actions.js +96 -0
- package/plugins/steve/steve-pagination-utils.ts +12 -4
- package/plugins/steve/subscribe.js +35 -5
- package/rancher-components/Accordion/Accordion.vue +53 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
- package/rancher-components/Form/Radio/RadioButton.vue +17 -1
- package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
- package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
- package/rancher-components/RcButton/RcButton.test.ts +140 -1
- package/rancher-components/RcButton/RcButton.vue +126 -17
- package/rancher-components/RcButton/types.ts +3 -0
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
- package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
- package/rancher-components/RcSection/RcSection.vue +28 -3
- package/scripts/extension/helm/package/Dockerfile +1 -1
- package/scripts/test-plugins-build.sh +2 -1
- package/store/__tests__/catalog.test.ts +115 -1
- package/store/__tests__/notifications.test.ts +434 -0
- package/store/__tests__/type-map.test.ts +556 -1
- package/store/action-menu.js +8 -3
- package/store/auth.js +1 -1
- package/store/aws.js +27 -16
- package/store/catalog.js +84 -3
- package/store/digitalocean.js +20 -38
- package/store/index.js +2 -0
- package/store/linode.js +25 -40
- package/store/plugins.js +7 -4
- package/store/pnap.js +1 -0
- package/store/type-map.js +111 -29
- package/tsconfig.paths.json +8 -8
- package/types/components/buttonGroup.ts +5 -0
- package/types/kube/kube-api.ts +14 -1
- package/types/rancher/steve.api.ts +12 -12
- package/types/resources/settings.d.ts +2 -1
- package/types/shell/index.d.ts +206 -72
- package/types/store/dashboard-store.types.ts +108 -11
- package/types/store/pagination.types.ts +6 -3
- package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
- package/utils/__tests__/async.test.ts +87 -0
- package/utils/__tests__/auth.test.ts +273 -0
- package/utils/__tests__/aws.test.ts +140 -0
- package/utils/__tests__/banners.test.ts +176 -0
- package/utils/__tests__/chart.test.ts +64 -1
- package/utils/__tests__/color.test.ts +226 -0
- package/utils/__tests__/computed.test.ts +193 -0
- package/utils/__tests__/cspAdaptor.test.ts +163 -0
- package/utils/__tests__/dom.test.ts +81 -0
- package/utils/__tests__/duration.test.ts +176 -0
- package/utils/__tests__/dynamic-importer.test.ts +102 -0
- package/utils/__tests__/fleet-appco.test.ts +312 -0
- package/utils/__tests__/fleet.test.ts +340 -0
- package/utils/__tests__/ingress.test.ts +553 -0
- package/utils/__tests__/kube.test.ts +68 -0
- package/utils/__tests__/monitoring.test.ts +130 -0
- package/utils/__tests__/namespace-filter.test.ts +109 -0
- package/utils/__tests__/object.test.ts +22 -0
- package/utils/__tests__/pagination-utils.test.ts +361 -0
- package/utils/__tests__/parse-externalid.test.ts +137 -0
- package/utils/__tests__/perf-setting.utils.test.ts +98 -0
- package/utils/__tests__/platform.test.ts +91 -0
- package/utils/__tests__/poller-sequential.test.ts +177 -0
- package/utils/__tests__/poller.test.ts +170 -0
- package/utils/__tests__/position.test.ts +237 -0
- package/utils/__tests__/promise.test.ts +346 -0
- package/utils/__tests__/provider.test.ts +51 -1
- package/utils/__tests__/queue.test.ts +232 -0
- package/utils/__tests__/release-notes.test.ts +221 -0
- package/utils/__tests__/router.test.js +254 -1
- package/utils/__tests__/select.test.ts +208 -0
- package/utils/__tests__/settings.test.ts +140 -0
- package/utils/__tests__/sort-utils.test.ts +301 -0
- package/utils/__tests__/string-utils.test.ts +798 -0
- package/utils/__tests__/string.test.ts +23 -1
- package/utils/__tests__/style.test.ts +154 -0
- package/utils/__tests__/svg-filter.test.ts +184 -0
- package/utils/__tests__/time.test.ts +265 -1
- package/utils/__tests__/title.test.ts +47 -0
- package/utils/__tests__/units.test.ts +417 -0
- package/utils/__tests__/versions.test.ts +128 -0
- package/utils/__tests__/width.test.ts +53 -0
- package/utils/__tests__/window.test.ts +158 -0
- package/utils/__tests__/xccdf.test.ts +511 -0
- package/utils/chart.js +36 -0
- package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
- package/utils/crypto/__tests__/index.test.ts +144 -0
- package/utils/duration.ts +104 -0
- package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
- package/utils/dynamic-content/info.ts +2 -1
- package/utils/error.js +13 -0
- package/utils/fleet-appco.ts +323 -0
- package/utils/fleet.ts +13 -3
- package/utils/gatekeeper/__tests__/util.test.ts +174 -0
- package/utils/gc/__tests__/gc-interval.test.ts +119 -0
- package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
- package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
- package/utils/gc/__tests__/gc.test.ts +487 -0
- package/utils/ingress.ts +9 -1
- package/utils/object.js +22 -2
- package/utils/pagination-utils.ts +2 -1
- package/utils/provider.ts +12 -0
- package/utils/string.js +25 -2
- package/utils/uiplugins.ts +5 -5
- package/utils/validators/__tests__/cluster-name.test.ts +110 -0
- package/utils/validators/__tests__/container-images.test.ts +104 -0
- package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
- package/utils/validators/__tests__/flow-output.test.ts +91 -0
- package/utils/validators/__tests__/index.test.ts +481 -0
- package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
- package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
- package/utils/validators/__tests__/misc-validators.test.ts +246 -0
- package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
- package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
- package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
- package/utils/validators/__tests__/role-template.test.ts +149 -0
- package/utils/validators/__tests__/service.test.ts +283 -0
- package/utils/validators/__tests__/setting.test.js +32 -0
- package/utils/validators/formRules/__tests__/index.test.ts +50 -0
- package/utils/validators/formRules/index.ts +5 -5
- package/utils/validators/machine-pool.ts +1 -1
- package/utils/validators/setting.js +18 -3
- package/utils/xccdf.ts +415 -0
- package/vue.config.js +1 -1
- package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
- package/pages/support/index.vue +0 -264
- package/utils/duration.js +0 -43
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { defineComponent, inject, computed,
|
|
3
|
-
import { useField } from 'vee-validate';
|
|
2
|
+
import { defineComponent, inject, computed, toRef } from 'vue';
|
|
4
3
|
import TextAreaAutoGrow from '@components/Form/TextArea/TextAreaAutoGrow.vue';
|
|
5
4
|
import LabeledTooltip from '@components/LabeledTooltip/LabeledTooltip.vue';
|
|
6
5
|
import { escapeHtml, generateRandomAlphaString } from '@shell/utils/string';
|
|
@@ -9,6 +8,7 @@ import { isValidCron } from 'cron-validator';
|
|
|
9
8
|
import { debounce } from 'lodash';
|
|
10
9
|
import { useLabeledFormElement, labeledFormElementProps } from '@shell/composables/useLabeledFormElement';
|
|
11
10
|
import { useCompactInput } from '@shell/composables/useCompactInput';
|
|
11
|
+
import { useVeeValidateField } from '@shell/composables/useVeeValidateField';
|
|
12
12
|
|
|
13
13
|
interface NonReactiveProps {
|
|
14
14
|
onInput: (event: Event) => void | ((event: Event) => void);
|
|
@@ -142,56 +142,11 @@ export default defineComponent({
|
|
|
142
142
|
|
|
143
143
|
const onInput = inject('onInput', provideProps.onInput);
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// Pass existing rules to vee-validate so field-level validation still runs
|
|
151
|
-
const veeValidator = (value: unknown): boolean | string => {
|
|
152
|
-
// Return true when name is absent to avoid duplicating
|
|
153
|
-
// useLabeledFormElement validation
|
|
154
|
-
if (!props.name) {
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
for (const rule of props.rules as Array<(v: unknown) => string | undefined>) {
|
|
158
|
-
const msg = rule(value);
|
|
159
|
-
|
|
160
|
-
if (msg) {
|
|
161
|
-
return msg;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return true;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const {
|
|
169
|
-
errorMessage: veeError,
|
|
170
|
-
handleBlur: veeHandleBlur,
|
|
171
|
-
validate: veeValidate,
|
|
172
|
-
value: veeValue,
|
|
173
|
-
} = useField<string | number | Record<string, unknown>>(
|
|
174
|
-
veeFieldName,
|
|
175
|
-
veeValidator,
|
|
176
|
-
{
|
|
177
|
-
initialValue: props.value as string | number,
|
|
178
|
-
validateOnValueUpdate: true,
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
// Keep vee-validate's internal value in sync with the controlled prop value.
|
|
183
|
-
watch(() => props.value, (v) => {
|
|
184
|
-
if (veeValue.value !== v) {
|
|
185
|
-
veeValue.value = v as string | number;
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
const effectiveValidationMessage = computed(() => {
|
|
190
|
-
if (props.name && veeError.value) {
|
|
191
|
-
return veeError.value;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return validationMessage.value;
|
|
145
|
+
const { effectiveValidationMessage, veeHandleBlur, veeValidate } = useVeeValidateField({
|
|
146
|
+
name: toRef(props, 'name'),
|
|
147
|
+
rules: toRef(props, 'rules'),
|
|
148
|
+
value: toRef(props, 'value'),
|
|
149
|
+
validationMessage,
|
|
195
150
|
});
|
|
196
151
|
|
|
197
152
|
const effectiveStatus = computed(() => props.status);
|
|
@@ -80,6 +80,14 @@ export default defineComponent({
|
|
|
80
80
|
default: false
|
|
81
81
|
},
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Use body text color for the label instead of the default input-label color.
|
|
85
|
+
*/
|
|
86
|
+
useBodyTextColor: {
|
|
87
|
+
type: Boolean,
|
|
88
|
+
default: false
|
|
89
|
+
},
|
|
90
|
+
|
|
83
91
|
/**
|
|
84
92
|
* Radio option Id - used to link to aria-activedescendant
|
|
85
93
|
* when using inside of the context of a Radio Group
|
|
@@ -189,7 +197,11 @@ export default defineComponent({
|
|
|
189
197
|
/>
|
|
190
198
|
<div class="labeling">
|
|
191
199
|
<label
|
|
192
|
-
|
|
200
|
+
class="radio-label m-0"
|
|
201
|
+
:class="{
|
|
202
|
+
'text-muted': muteLabel,
|
|
203
|
+
'body-text-color': useBodyTextColor
|
|
204
|
+
}"
|
|
193
205
|
:for="name"
|
|
194
206
|
>
|
|
195
207
|
<slot
|
|
@@ -314,6 +326,10 @@ $fontColor: var(--input-label);
|
|
|
314
326
|
flex-direction: column;
|
|
315
327
|
|
|
316
328
|
margin: 3px 10px 0px 5px;
|
|
329
|
+
|
|
330
|
+
.body-text-color {
|
|
331
|
+
color: var(--body-text);
|
|
332
|
+
}
|
|
317
333
|
}
|
|
318
334
|
}
|
|
319
335
|
|
|
@@ -12,6 +12,7 @@ interface Option {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default defineComponent({
|
|
15
|
+
name: 'RadioGroup',
|
|
15
16
|
components: { RadioButton },
|
|
16
17
|
props: {
|
|
17
18
|
/**
|
|
@@ -102,6 +103,14 @@ export default defineComponent({
|
|
|
102
103
|
row: {
|
|
103
104
|
type: Boolean,
|
|
104
105
|
default: false
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Use body text color for the label instead of the default input-label color.
|
|
110
|
+
*/
|
|
111
|
+
useBodyTextColor: {
|
|
112
|
+
type: Boolean,
|
|
113
|
+
default: false
|
|
105
114
|
}
|
|
106
115
|
},
|
|
107
116
|
|
|
@@ -302,6 +311,7 @@ export default defineComponent({
|
|
|
302
311
|
:disabled="isDisabled"
|
|
303
312
|
:data-testid="`radio-button-${i}`"
|
|
304
313
|
:mode="mode"
|
|
314
|
+
:use-body-text-color="useBodyTextColor"
|
|
305
315
|
:prevent-focus-on-radio-groups="true"
|
|
306
316
|
@update:value="$emit('update:value', $event)"
|
|
307
317
|
/>
|
|
@@ -28,7 +28,8 @@ const emit = defineEmits(['close']);
|
|
|
28
28
|
<style lang="scss" scoped>
|
|
29
29
|
.rc-tag {
|
|
30
30
|
display: inline-flex;
|
|
31
|
-
|
|
31
|
+
min-height: 24px;
|
|
32
|
+
padding: 2px 8px;
|
|
32
33
|
align-items: center;
|
|
33
34
|
gap: 8px;
|
|
34
35
|
|
|
@@ -41,7 +42,7 @@ const emit = defineEmits(['close']);
|
|
|
41
42
|
font-size: 13px;
|
|
42
43
|
font-style: normal;
|
|
43
44
|
font-weight: 400;
|
|
44
|
-
line-height:
|
|
45
|
+
line-height: 20px;
|
|
45
46
|
color: var(--body-text);
|
|
46
47
|
|
|
47
48
|
button {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils';
|
|
1
|
+
import { mount, RouterLinkStub } from '@vue/test-utils';
|
|
2
2
|
import RcButton from './RcButton.vue';
|
|
3
3
|
|
|
4
4
|
describe('rcButton.vue', () => {
|
|
@@ -138,4 +138,143 @@ describe('rcButton.vue', () => {
|
|
|
138
138
|
expect(button.classes()).toContain('variant-ghost');
|
|
139
139
|
});
|
|
140
140
|
});
|
|
141
|
+
|
|
142
|
+
describe('space key navigation', () => {
|
|
143
|
+
it('triggers click when Space is pressed on a link button', async() => {
|
|
144
|
+
const to = { name: 'some-route' };
|
|
145
|
+
const wrapper = mount(RcButton, {
|
|
146
|
+
props: { to },
|
|
147
|
+
global: { stubs: { RouterLink: RouterLinkStub } },
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const link = wrapper.findComponent(RouterLinkStub);
|
|
151
|
+
const clickSpy = jest.spyOn(link.element, 'click');
|
|
152
|
+
|
|
153
|
+
await link.trigger('keyup', { key: ' ' });
|
|
154
|
+
|
|
155
|
+
expect(clickSpy).toHaveBeenCalledWith();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('does not manually trigger click when Space is pressed on a regular button', async() => {
|
|
159
|
+
const wrapper = mount(RcButton);
|
|
160
|
+
const button = wrapper.find('button');
|
|
161
|
+
const clickSpy = jest.spyOn(button.element, 'click');
|
|
162
|
+
|
|
163
|
+
await button.trigger('keyup', { key: ' ' });
|
|
164
|
+
|
|
165
|
+
expect(clickSpy).not.toHaveBeenCalled();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('to and href mutual exclusion', () => {
|
|
170
|
+
it('warns when both "to" and "href" props are provided', () => {
|
|
171
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
172
|
+
|
|
173
|
+
mount(RcButton, {
|
|
174
|
+
props: { to: '/foo', href: 'https://example.com' },
|
|
175
|
+
global: { stubs: { RouterLink: RouterLinkStub } },
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
expect(warnSpy).toHaveBeenCalledWith('[RcButton] "to" and "href" are mutually exclusive. Provide only one.');
|
|
179
|
+
warnSpy.mockRestore();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('does not warn when only "to" is provided', () => {
|
|
183
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
184
|
+
|
|
185
|
+
mount(RcButton, {
|
|
186
|
+
props: { to: '/foo' },
|
|
187
|
+
global: { stubs: { RouterLink: RouterLinkStub } },
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(warnSpy).not.toHaveBeenCalledWith('[RcButton] "to" and "href" are mutually exclusive. Provide only one.');
|
|
191
|
+
warnSpy.mockRestore();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('does not warn when only "href" is provided', () => {
|
|
195
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
196
|
+
|
|
197
|
+
mount(RcButton, { props: { href: 'https://example.com' } });
|
|
198
|
+
|
|
199
|
+
expect(warnSpy).not.toHaveBeenCalledWith('[RcButton] "to" and "href" are mutually exclusive. Provide only one.');
|
|
200
|
+
warnSpy.mockRestore();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('href prop', () => {
|
|
205
|
+
it('renders as an <a> element when "href" prop is provided', () => {
|
|
206
|
+
const wrapper = mount(RcButton, { props: { href: 'https://example.com' } });
|
|
207
|
+
|
|
208
|
+
expect(wrapper.find('a').exists()).toBe(true);
|
|
209
|
+
expect(wrapper.find('button').exists()).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('sets the href attribute on the rendered anchor', () => {
|
|
213
|
+
const href = 'https://example.com';
|
|
214
|
+
const wrapper = mount(RcButton, { props: { href } });
|
|
215
|
+
|
|
216
|
+
expect(wrapper.find('a').attributes('href')).toStrictEqual(href);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('sets role="link" when rendered as an anchor', () => {
|
|
220
|
+
const wrapper = mount(RcButton, { props: { href: 'https://example.com' } });
|
|
221
|
+
|
|
222
|
+
expect(wrapper.find('a').attributes('role')).toStrictEqual('link');
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('applies button classes when rendered as an anchor', () => {
|
|
226
|
+
const wrapper = mount(RcButton, { props: { href: 'https://example.com', variant: 'secondary' } });
|
|
227
|
+
const anchor = wrapper.find('a');
|
|
228
|
+
|
|
229
|
+
expect(anchor.classes()).toContain('rc-button');
|
|
230
|
+
expect(anchor.classes()).toContain('btn');
|
|
231
|
+
expect(anchor.classes()).toContain('variant-secondary');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('triggers click when Space is pressed on an anchor', async() => {
|
|
235
|
+
const wrapper = mount(RcButton, { props: { href: 'https://example.com' } });
|
|
236
|
+
const anchor = wrapper.find('a');
|
|
237
|
+
const clickSpy = jest.spyOn(anchor.element, 'click');
|
|
238
|
+
|
|
239
|
+
await anchor.trigger('keyup', { key: ' ' });
|
|
240
|
+
|
|
241
|
+
expect(clickSpy).toHaveBeenCalledWith();
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('to prop', () => {
|
|
246
|
+
it('renders as a <button> when no "to" prop is provided', () => {
|
|
247
|
+
const wrapper = mount(RcButton);
|
|
248
|
+
|
|
249
|
+
expect(wrapper.find('button').exists()).toBe(true);
|
|
250
|
+
expect(wrapper.findComponent(RouterLinkStub).exists()).toBe(false);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('renders as a RouterLink when "to" prop is provided', () => {
|
|
254
|
+
const to = { name: 'some-route' };
|
|
255
|
+
const wrapper = mount(RcButton, {
|
|
256
|
+
props: { to },
|
|
257
|
+
global: { stubs: { RouterLink: RouterLinkStub } },
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const link = wrapper.findComponent(RouterLinkStub);
|
|
261
|
+
|
|
262
|
+
expect(link.exists()).toBe(true);
|
|
263
|
+
expect(wrapper.find('button').exists()).toBe(false);
|
|
264
|
+
expect(link.props('to')).toStrictEqual(to);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('applies button classes when rendered as a RouterLink', () => {
|
|
268
|
+
const wrapper = mount(RcButton, {
|
|
269
|
+
props: { to: '/foo', variant: 'secondary' },
|
|
270
|
+
global: { stubs: { RouterLink: RouterLinkStub } },
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const link = wrapper.findComponent(RouterLinkStub);
|
|
274
|
+
|
|
275
|
+
expect(link.classes()).toContain('rc-button');
|
|
276
|
+
expect(link.classes()).toContain('btn');
|
|
277
|
+
expect(link.classes()).toContain('variant-secondary');
|
|
278
|
+
});
|
|
279
|
+
});
|
|
141
280
|
});
|
|
@@ -7,10 +7,15 @@
|
|
|
7
7
|
*
|
|
8
8
|
* <rc-button variant="primary" @click="doAction">Perform an Action</rc-button>
|
|
9
9
|
*/
|
|
10
|
-
import { computed, ref } from 'vue';
|
|
10
|
+
import { computed, ref, resolveComponent, watchEffect } from 'vue';
|
|
11
11
|
import {
|
|
12
|
-
ButtonVariantProps,
|
|
13
|
-
|
|
12
|
+
ButtonVariantProps,
|
|
13
|
+
ButtonSizeProps,
|
|
14
|
+
ButtonVariantNewProps,
|
|
15
|
+
ButtonSizeNewProps,
|
|
16
|
+
ButtonSize,
|
|
17
|
+
IconProps,
|
|
18
|
+
NavigationProps,
|
|
14
19
|
} from './types';
|
|
15
20
|
import RcIcon from '@components/RcIcon/RcIcon.vue';
|
|
16
21
|
|
|
@@ -33,7 +38,54 @@ const buttonSizesNew: { size: ButtonSize, className: string }[] = [
|
|
|
33
38
|
{ size: 'large', className: 'btn-large' },
|
|
34
39
|
];
|
|
35
40
|
|
|
36
|
-
const props = withDefaults(
|
|
41
|
+
const props = withDefaults(
|
|
42
|
+
defineProps<
|
|
43
|
+
ButtonVariantProps &
|
|
44
|
+
ButtonSizeProps &
|
|
45
|
+
ButtonVariantNewProps &
|
|
46
|
+
ButtonSizeNewProps &
|
|
47
|
+
IconProps &
|
|
48
|
+
NavigationProps
|
|
49
|
+
>(),
|
|
50
|
+
{
|
|
51
|
+
size: 'medium',
|
|
52
|
+
to: undefined,
|
|
53
|
+
href: undefined,
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
58
|
+
watchEffect(() => {
|
|
59
|
+
if (props.to && props.href) {
|
|
60
|
+
console.warn('[RcButton] "to" and "href" are mutually exclusive. Provide only one.'); // eslint-disable-line no-console
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const tag = computed(() => {
|
|
66
|
+
if (props.to) {
|
|
67
|
+
return resolveComponent('RouterLink');
|
|
68
|
+
}
|
|
69
|
+
if (props.href) {
|
|
70
|
+
return 'a';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return 'button';
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const role = computed(() => (props.to || props.href ? 'link' : 'button'));
|
|
77
|
+
|
|
78
|
+
const linkProps = computed(() => {
|
|
79
|
+
if (props.to) {
|
|
80
|
+
return { to: props.to };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (props.href) {
|
|
84
|
+
return { href: props.href };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {};
|
|
88
|
+
});
|
|
37
89
|
|
|
38
90
|
const activeVariantClassName = computed(() => {
|
|
39
91
|
if (props.variant === 'multiAction' || props.multiAction) {
|
|
@@ -90,14 +142,34 @@ const focus = () => {
|
|
|
90
142
|
RcFocusTarget?.value?.focus();
|
|
91
143
|
};
|
|
92
144
|
|
|
145
|
+
const preventScroll = (event: KeyboardEvent) => {
|
|
146
|
+
if (tag.value === 'button') {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const handleSpace = (event: KeyboardEvent) => {
|
|
154
|
+
if (tag.value === 'button') {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
(event.target as HTMLElement).click();
|
|
159
|
+
};
|
|
160
|
+
|
|
93
161
|
defineExpose({ focus });
|
|
94
162
|
</script>
|
|
95
163
|
|
|
96
164
|
<template>
|
|
97
|
-
<
|
|
165
|
+
<component
|
|
166
|
+
:is="tag"
|
|
98
167
|
ref="RcFocusTarget"
|
|
99
|
-
role="
|
|
168
|
+
:role="role"
|
|
169
|
+
v-bind="linkProps"
|
|
100
170
|
:class="{ ...buttonClass }"
|
|
171
|
+
@keydown.space="preventScroll"
|
|
172
|
+
@keyup.space="handleSpace"
|
|
101
173
|
>
|
|
102
174
|
<slot
|
|
103
175
|
v-if="$slots.before || props.leftIcon"
|
|
@@ -124,15 +196,23 @@ defineExpose({ focus });
|
|
|
124
196
|
size="inherit"
|
|
125
197
|
/>
|
|
126
198
|
</slot>
|
|
127
|
-
</
|
|
199
|
+
</component>
|
|
128
200
|
</template>
|
|
129
201
|
|
|
130
202
|
<style lang="scss" scoped>
|
|
131
|
-
button {
|
|
203
|
+
.rc-button {
|
|
132
204
|
display: inline-flex;
|
|
133
205
|
align-items: center;
|
|
134
206
|
justify-content: center;
|
|
135
207
|
|
|
208
|
+
// Override global .btn > .icon:not(:only-child) { margin-right: 6px } from _button.scss.
|
|
209
|
+
// RcButton uses flex gap for spacing instead. The :not(:only-child) clause matches the global
|
|
210
|
+
// selector so we win on specificity regardless of stylesheet load order; :deep() is needed to
|
|
211
|
+
// target slotted content.
|
|
212
|
+
& > :deep(.icon:not(:only-child)) {
|
|
213
|
+
margin-right: 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
136
216
|
// Much of the styling in here came from _button.scss. Because we're making changes from role to variant and we don't want to impact existing use cases we're pulling in some of these styles. We should in the long run deprecate that file.
|
|
137
217
|
// Variant styles
|
|
138
218
|
&.variant-primary {
|
|
@@ -155,9 +235,12 @@ button {
|
|
|
155
235
|
}
|
|
156
236
|
|
|
157
237
|
&:disabled {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
238
|
+
&, &:hover, &:focus {
|
|
239
|
+
color: var(--disabled-text);
|
|
240
|
+
background: var(--disabled-bg);
|
|
241
|
+
border-color: var(--disabled-bg);
|
|
242
|
+
cursor: not-allowed;
|
|
243
|
+
}
|
|
161
244
|
}
|
|
162
245
|
}
|
|
163
246
|
|
|
@@ -180,6 +263,15 @@ button {
|
|
|
180
263
|
@include focus-outline;
|
|
181
264
|
outline-offset: 2px;
|
|
182
265
|
}
|
|
266
|
+
|
|
267
|
+
&:disabled {
|
|
268
|
+
&, &:hover, &:focus {
|
|
269
|
+
color: var(--disabled-text);
|
|
270
|
+
background: var(--disabled-bg);
|
|
271
|
+
border-color: var(--disabled-bg);
|
|
272
|
+
cursor: not-allowed;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
183
275
|
}
|
|
184
276
|
|
|
185
277
|
&.variant-tertiary {
|
|
@@ -201,6 +293,15 @@ button {
|
|
|
201
293
|
@include focus-outline;
|
|
202
294
|
outline-offset: 2px;
|
|
203
295
|
}
|
|
296
|
+
|
|
297
|
+
&:disabled {
|
|
298
|
+
&, &:hover, &:focus {
|
|
299
|
+
color: var(--disabled-text);
|
|
300
|
+
background: var(--disabled-bg);
|
|
301
|
+
border-color: var(--disabled-bg);
|
|
302
|
+
cursor: not-allowed;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
204
305
|
}
|
|
205
306
|
|
|
206
307
|
&.variant-link {
|
|
@@ -253,11 +354,15 @@ button {
|
|
|
253
354
|
&.btn-small {
|
|
254
355
|
//:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
|
|
255
356
|
&, &:not(.btn-sm) {
|
|
256
|
-
line-height
|
|
357
|
+
// Unitless ratio chosen so font-size * line-height (12px * 4/3 = 16px)
|
|
358
|
+
// is a whole pixel value. A fractional computed line-height (e.g. the
|
|
359
|
+
// previous 140% = 16.8px) shifts text ~1px off-center within the
|
|
360
|
+
// flex-centered button in Chrome, but not in Firefox.
|
|
361
|
+
line-height: calc(4 / 3);
|
|
257
362
|
font-size: 12px;
|
|
258
363
|
min-height: 24px;
|
|
259
364
|
|
|
260
|
-
padding: 0 8px;
|
|
365
|
+
padding: var(--rc-button-padding, 0 8px);
|
|
261
366
|
gap: 8px;
|
|
262
367
|
}
|
|
263
368
|
}
|
|
@@ -265,11 +370,13 @@ button {
|
|
|
265
370
|
&.btn-medium {
|
|
266
371
|
//:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
|
|
267
372
|
&, &:not(.btn-sm) {
|
|
268
|
-
line-height
|
|
373
|
+
// Unitless ratio chosen so font-size * line-height (14px * 10/7 = 20px)
|
|
374
|
+
// is a whole pixel value. See note in .btn-small for why this matters.
|
|
375
|
+
line-height: calc(10 / 7);
|
|
269
376
|
font-size: 14px;
|
|
270
377
|
min-height: 32px;
|
|
271
378
|
|
|
272
|
-
padding: 0 12px;
|
|
379
|
+
padding: var(--rc-button-padding, 0 12px);
|
|
273
380
|
gap: 8px;
|
|
274
381
|
}
|
|
275
382
|
}
|
|
@@ -277,11 +384,13 @@ button {
|
|
|
277
384
|
&.btn-large {
|
|
278
385
|
// This is the default size brought by the global button styling
|
|
279
386
|
&, &:not(.btn-sm) {
|
|
280
|
-
line-height
|
|
387
|
+
// Unitless ratio chosen so font-size * line-height (16px * 1.5 = 24px)
|
|
388
|
+
// is a whole pixel value. See note in .btn-small for why this matters.
|
|
389
|
+
line-height: 1.5;
|
|
281
390
|
font-size: 16px;
|
|
282
391
|
min-height: 40px;
|
|
283
392
|
|
|
284
|
-
padding: 0 16px;
|
|
393
|
+
padding: var(--rc-button-padding, 0 16px);
|
|
285
394
|
gap: 12px;
|
|
286
395
|
}
|
|
287
396
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { RouteLocationRaw } from 'vue-router';
|
|
1
2
|
import { RcIconType } from '@components/RcIcon/types';
|
|
2
3
|
|
|
4
|
+
export type NavigationProps = { to?: RouteLocationRaw; href?: string }
|
|
5
|
+
|
|
3
6
|
// TODO: 13211 Investigate why `InstanceType<typeof RcButton>` fails prod builds
|
|
4
7
|
// export type RcButtonType = InstanceType<typeof RcButton>
|
|
5
8
|
export type RcButtonType = {
|
|
@@ -35,18 +35,20 @@ defineExpose({ focus });
|
|
|
35
35
|
@keydown.enter.space="handleKeydown"
|
|
36
36
|
@click="showMenu(true)"
|
|
37
37
|
>
|
|
38
|
-
<template
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
<template
|
|
39
|
+
v-if="$slots.before"
|
|
40
|
+
#before
|
|
41
|
+
>
|
|
42
|
+
<slot name="before" />
|
|
42
43
|
</template>
|
|
43
44
|
<slot name="default">
|
|
44
45
|
<!--Empty slot content-->
|
|
45
46
|
</slot>
|
|
46
|
-
<template
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
<template
|
|
48
|
+
v-if="$slots.after"
|
|
49
|
+
#after
|
|
50
|
+
>
|
|
51
|
+
<slot name="after" />
|
|
50
52
|
</template>
|
|
51
53
|
</RcButton>
|
|
52
54
|
</template>
|
|
@@ -36,6 +36,24 @@ describe('rcItemCard', () => {
|
|
|
36
36
|
expect(wrapper.findAll(`[data-testid="item-card-header-statuses-status"]`)).toHaveLength(2);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
+
// Regression: when image.src is falsy, LazyImage must still render so its own
|
|
40
|
+
// empty-src fallback (generic catalog icon) is shown. Previously the template
|
|
41
|
+
// was gated by `v-else-if="image.src"` and showed an empty box for missing icons.
|
|
42
|
+
it.each(['medium', 'small'] as const)('renders LazyImage with an empty src when image.src is falsy (%s variant)', (variant) => {
|
|
43
|
+
const wrapper = mount(RcItemCard, {
|
|
44
|
+
props: {
|
|
45
|
+
...baseProps,
|
|
46
|
+
variant,
|
|
47
|
+
image: { src: '', alt: { text: 'Logo' } },
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const lazy = wrapper.findComponent({ name: 'LazyImage' });
|
|
52
|
+
|
|
53
|
+
expect(lazy.exists()).toBe(true);
|
|
54
|
+
expect(lazy.props('src')).toBe('');
|
|
55
|
+
});
|
|
56
|
+
|
|
39
57
|
it('renders pill only in medium variant', () => {
|
|
40
58
|
const wrapper = mount(RcItemCard, {
|
|
41
59
|
props: {
|
|
@@ -208,7 +208,7 @@ const cursorValue = computed(() => props.clickable ? 'pointer' : 'auto');
|
|
|
208
208
|
size="xxlarge"
|
|
209
209
|
/>
|
|
210
210
|
</template>
|
|
211
|
-
<template v-else
|
|
211
|
+
<template v-else>
|
|
212
212
|
<LazyImage
|
|
213
213
|
:src="image.src"
|
|
214
214
|
:alt="imageAlt"
|
|
@@ -255,7 +255,7 @@ const cursorValue = computed(() => props.clickable ? 'pointer' : 'auto');
|
|
|
255
255
|
size="xlarge"
|
|
256
256
|
/>
|
|
257
257
|
</template>
|
|
258
|
-
<template v-else
|
|
258
|
+
<template v-else>
|
|
259
259
|
<LazyImage
|
|
260
260
|
:src="image.src"
|
|
261
261
|
:alt="imageAlt"
|