@rancher/shell 3.0.5-rc.5 → 3.0.5-rc.6
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 +1 -0
- package/assets/images/key.svg +17 -0
- package/assets/styles/base/_spacing.scss +2 -2
- package/assets/styles/global/_form.scss +1 -1
- package/assets/styles/global/_labeled-input.scss +1 -1
- package/assets/styles/themes/_dark.scss +3 -0
- package/assets/styles/themes/_light.scss +3 -0
- package/assets/styles/vendor/vue-select.scss +1 -1
- package/assets/translations/en-us.yaml +404 -64
- package/assets/translations/zh-hans.yaml +3 -4
- package/cloud-credential/gcp.vue +9 -1
- package/components/AppModal.vue +2 -0
- package/components/CodeMirror.vue +1 -1
- package/components/ConfigMapSettings/Settings.vue +377 -0
- package/components/ConfigMapSettings/index.vue +354 -0
- package/components/CruResource.vue +1 -2
- package/components/DetailText.vue +61 -11
- package/components/Drawer/Chrome.vue +116 -0
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
- package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +82 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
- package/components/Drawer/ResourceDetailDrawer/composables.ts +50 -0
- package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
- package/components/Drawer/ResourceDetailDrawer/index.vue +110 -0
- package/components/GrowlManager.vue +16 -15
- package/components/IconOrSvg.vue +5 -0
- package/components/KeyValueView.vue +1 -1
- package/components/LocaleSelector.vue +9 -1
- package/components/ProgressBarMulti.vue +1 -0
- package/components/PromptModal.vue +6 -1
- package/components/RelatedResources.vue +4 -12
- package/components/Resource/Detail/Additional.vue +46 -0
- package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
- package/components/Resource/Detail/Metadata/Annotations/index.vue +5 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +37 -254
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +298 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +27 -5
- package/components/Resource/Detail/Metadata/KeyValue.vue +25 -17
- package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -1
- package/components/Resource/Detail/Metadata/Labels/index.vue +4 -0
- package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +1 -1
- package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +1 -1
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
- package/components/Resource/Detail/Metadata/composables.ts +60 -11
- package/components/Resource/Detail/Metadata/index.vue +12 -5
- package/components/Resource/Detail/Page.vue +15 -0
- package/components/Resource/Detail/ResourceRow.vue +37 -18
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
- package/components/Resource/Detail/TitleBar/Title.vue +2 -1
- package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +1 -1
- package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +1 -1
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
- package/components/Resource/Detail/TitleBar/composables.ts +44 -0
- package/components/Resource/Detail/TitleBar/index.vue +83 -11
- package/components/Resource/Detail/composables.ts +45 -0
- package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
- package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
- package/components/ResourceDetail/Masthead/index.vue +65 -0
- package/components/ResourceDetail/Masthead/latest.vue +44 -0
- package/components/ResourceDetail/__tests__/index.test.ts +26 -5
- package/components/ResourceDetail/index.vue +30 -16
- package/components/ResourceDetail/legacy.vue +18 -1
- package/components/ResourceList/Masthead.vue +6 -0
- package/components/ResourceYaml.vue +14 -1
- package/components/SlideInPanelManager.vue +46 -7
- package/components/StateDot/index.vue +28 -0
- package/components/Tabbed/index.vue +11 -15
- package/components/Wizard.vue +4 -2
- package/components/__tests__/ConfigMapSettings.test.ts +376 -0
- package/components/__tests__/GrowlManager.test.ts +0 -25
- package/components/auth/login/ldap.vue +1 -1
- package/components/fleet/FleetApplications.vue +0 -7
- package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
- package/components/fleet/FleetClusterTargets/index.vue +455 -0
- package/components/fleet/FleetClusters.vue +25 -6
- package/components/fleet/FleetGitRepoPaths.vue +476 -0
- package/components/fleet/FleetHelmOps.vue +8 -0
- package/components/fleet/FleetRepos.vue +1 -6
- package/components/fleet/FleetResources.vue +4 -5
- package/components/fleet/FleetValuesFrom.vue +295 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
- package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
- package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +13 -13
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
- package/components/fleet/dashboard/ResourceCard.vue +1 -0
- package/components/fleet/dashboard/ResourceCardSummary.vue +1 -5
- package/components/fleet/dashboard/ResourceDetails.vue +8 -10
- package/components/fleet/dashboard/ResourcePanel.vue +15 -8
- package/components/form/ArrayList.vue +13 -2
- package/components/form/ChangePassword.vue +3 -1
- package/components/form/Footer.vue +10 -4
- package/components/form/KeyValue.vue +81 -43
- package/components/form/LabeledSelect.vue +56 -16
- package/components/form/Labels.vue +90 -17
- package/components/form/MatchExpressions.vue +46 -5
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/ResourceSelector.vue +1 -0
- package/components/form/ResourceTabs/index.vue +5 -0
- package/components/form/SecretSelector.vue +9 -2
- package/components/form/Select.vue +57 -19
- package/components/form/SimpleSecretSelector.vue +9 -2
- package/components/form/Taints.vue +21 -2
- package/components/form/UnitInput.vue +8 -0
- package/components/form/ValueFromResource.vue +1 -1
- package/components/form/__tests__/LabeledSelect.test.ts +8 -4
- package/components/form/__tests__/Labels.test.ts +360 -0
- package/components/form/__tests__/MatchExpressions.test.ts +16 -13
- package/components/form/__tests__/Select.test.ts +5 -2
- package/components/formatter/FleetApplicationSource.vue +1 -1
- package/components/formatter/WorkloadHealthScale.vue +1 -1
- package/components/google/AccountAccess.vue +211 -0
- package/components/google/types/gcp.d.ts +136 -0
- package/components/google/types/index.d.ts +101 -0
- package/components/google/util/__mocks__/gcp.ts +465 -0
- package/components/google/util/formatter.ts +82 -0
- package/components/google/util/gcp.ts +134 -0
- package/components/google/util/index.d.ts +11 -0
- package/components/nav/Favorite.vue +1 -1
- package/components/nav/Group.vue +70 -47
- package/components/nav/Header.vue +5 -1
- package/components/nav/NamespaceFilter.vue +13 -1
- package/components/nav/NotificationCenter/Notification.vue +510 -0
- package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
- package/components/nav/NotificationCenter/index.vue +148 -0
- package/composables/drawer.ts +26 -0
- package/composables/resources.test.ts +63 -0
- package/composables/resources.ts +38 -0
- package/composables/useIsNewDetailPageEnabled.ts +17 -0
- package/config/labels-annotations.js +6 -0
- package/config/product/auth.js +16 -1
- package/config/product/{cis.js → compliance.js} +23 -26
- package/config/product/explorer.js +5 -1
- package/config/product/fleet.js +7 -0
- package/config/product/settings.js +22 -11
- package/config/query-params.js +3 -0
- package/config/roles.ts +1 -1
- package/config/router/navigation-guards/authentication.js +51 -2
- package/config/router/routes.js +27 -31
- package/config/settings.ts +21 -3
- package/config/store.js +2 -0
- package/config/system-namespaces.js +1 -1
- package/config/table-headers.js +2 -2
- package/config/types.js +15 -6
- package/core/plugin.ts +32 -7
- package/core/types.ts +18 -1
- package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
- package/detail/management.cattle.io.fleetworkspace.vue +18 -27
- package/detail/management.cattle.io.oidcclient.vue +369 -0
- package/detail/node.vue +2 -2
- package/detail/pod.vue +2 -2
- package/detail/service.vue +10 -1
- package/detail/workload/index.vue +8 -2
- package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
- package/dialog/GenericPrompt.vue +1 -1
- package/dialog/ImportDialog.vue +8 -8
- package/dialog/OidcClientSecretDialog.vue +117 -0
- package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +5 -2
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
- package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
- package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
- package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
- package/edit/configmap.vue +4 -1
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.gitrepo.vue +44 -222
- package/edit/fleet.cattle.io.helmop.vue +44 -269
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
- package/edit/logging-flow/index.vue +1 -0
- package/edit/logging.banzaicloud.io.output/index.vue +1 -0
- package/edit/management.cattle.io.fleetworkspace.vue +1 -0
- package/edit/management.cattle.io.oidcclient.vue +162 -0
- package/edit/management.cattle.io.project.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
- package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
- package/edit/monitoring.coreos.com.route.vue +1 -0
- package/edit/namespace.vue +1 -0
- package/edit/networking.istio.io.destinationrule/index.vue +4 -1
- package/edit/networking.k8s.io.ingress/index.vue +4 -1
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
- package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +418 -382
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +27 -27
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
- package/edit/resources.cattle.io.restore.vue +1 -1
- package/edit/secret/index.vue +1 -0
- package/edit/service.vue +4 -1
- package/edit/serviceaccount.vue +4 -1
- package/edit/storage.k8s.io.storageclass/index.vue +4 -1
- package/edit/workload/index.vue +5 -0
- package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
- package/list/management.cattle.io.oidcclient.vue +108 -0
- package/list/node.vue +2 -0
- package/machine-config/amazonec2.vue +3 -24
- package/machine-config/components/GCEImage.vue +374 -0
- package/machine-config/google.vue +617 -0
- package/mixins/__tests__/brand.spec.ts +170 -0
- package/mixins/brand.js +16 -17
- package/mixins/create-edit-view/index.js +5 -0
- package/mixins/resource-fetch-api-pagination.js +16 -0
- package/mixins/vue-select-overrides.js +1 -0
- package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
- package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
- package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
- package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
- package/models/fleet-application.js +8 -79
- package/models/fleet.cattle.io.cluster.js +11 -0
- package/models/fleet.cattle.io.gitrepo.js +2 -2
- package/models/fleet.cattle.io.helmop.js +9 -39
- package/models/management.cattle.io.fleetworkspace.js +2 -1
- package/models/management.cattle.io.oidcclient.js +18 -0
- package/models/management.cattle.io.registration.js +3 -0
- package/models/provisioning.cattle.io.cluster.js +5 -5
- package/models/service.js +4 -0
- package/models/workload.js +5 -0
- package/package.json +1 -1
- package/pages/about.vue +4 -58
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/AddRepoLink.vue +0 -1
- package/pages/c/_cluster/apps/charts/index.vue +285 -81
- package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
- package/pages/c/_cluster/explorer/index.vue +3 -3
- package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
- package/pages/c/_cluster/fleet/application/create.vue +3 -2
- package/pages/c/_cluster/fleet/index.vue +94 -56
- package/pages/c/_cluster/fleet/settings/index.vue +229 -0
- package/pages/c/_cluster/longhorn/index.vue +5 -2
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
- package/pages/explorer/resource/detail/configmap.vue +30 -7
- package/pages/explorer/resource/detail/secret.vue +50 -0
- package/pages/home.vue +9 -55
- package/pages/support/index.vue +4 -6
- package/plugins/dashboard-store/actions.js +19 -5
- package/plugins/dashboard-store/getters.js +4 -0
- package/plugins/dashboard-store/resource-class.js +16 -2
- package/plugins/steve/steve-pagination-utils.ts +26 -18
- package/plugins/steve/subscribe.js +6 -1
- package/rancher-components/Banner/Banner.vue +13 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +9 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +8 -3
- package/store/auth.js +2 -0
- package/store/catalog.js +23 -1
- package/store/growl.js +97 -8
- package/store/index.js +6 -0
- package/store/notifications.ts +426 -0
- package/store/prefs.js +0 -1
- package/store/type-map.js +19 -16
- package/store/uiplugins.ts +15 -1
- package/types/fleet.d.ts +24 -0
- package/types/notifications/index.ts +74 -0
- package/types/shell/index.d.ts +46 -32
- package/types/store/dashboard-store.types.ts +16 -0
- package/utils/__tests__/fleet.test.ts +148 -0
- package/utils/__tests__/object.test.ts +54 -1
- package/utils/__tests__/string.test.ts +273 -1
- package/utils/__tests__/time.test.ts +31 -0
- package/utils/auth.js +9 -2
- package/utils/crypto/encryption.ts +103 -0
- package/utils/cspAdaptor.ts +51 -0
- package/utils/fleet.ts +54 -65
- package/utils/object.js +36 -0
- package/utils/pagination-utils.ts +1 -1
- package/utils/release-notes.ts +48 -0
- package/utils/selector-typed.ts +7 -2
- package/utils/string.js +24 -0
- package/utils/{time.js → time.ts} +25 -6
- package/utils/uiplugins.ts +22 -0
- package/utils/validators/formRules/index.ts +3 -0
- package/components/Resource/Detail/TitleBar/composable.ts +0 -31
- package/config/product/legacy.js +0 -62
- package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
- package/pages/c/_cluster/legacy/project/_page.vue +0 -57
- package/pages/c/_cluster/legacy/project/index.vue +0 -32
- package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
- /package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Banner } from '@components/Banner';
|
|
3
|
+
import TitleBar from '@shell/components/Resource/Detail/TitleBar/index.vue';
|
|
4
|
+
import { useDefaultTitleBarProps } from '@shell/components/Resource/Detail/TitleBar/composables';
|
|
5
|
+
import Metadata from '@shell/components/Resource/Detail/Metadata/index.vue';
|
|
6
|
+
import { useDefaultMetadataForLegacyPagesProps } from '@shell/components/Resource/Detail/Metadata/composables';
|
|
7
|
+
import { useResourceDetailBannerProps } from '@shell/components/Resource/Detail/composables';
|
|
8
|
+
import { computed } from 'vue';
|
|
9
|
+
|
|
10
|
+
export interface Props {
|
|
11
|
+
value?: Object;
|
|
12
|
+
resourceSubtype?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script lang="ts" setup>
|
|
18
|
+
const props = withDefaults(defineProps<Props>(), { value: () => ({}), resourceSubtype: undefined });
|
|
19
|
+
|
|
20
|
+
const resourceSubtype = computed(() => props.resourceSubtype);
|
|
21
|
+
const titleBarProps = useDefaultTitleBarProps(props.value, resourceSubtype);
|
|
22
|
+
const metadataProps = useDefaultMetadataForLegacyPagesProps(props.value);
|
|
23
|
+
const bannerProps = useResourceDetailBannerProps(props.value);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<TitleBar v-bind="titleBarProps" />
|
|
28
|
+
<Banner
|
|
29
|
+
v-if="bannerProps"
|
|
30
|
+
class="new state-banner"
|
|
31
|
+
v-bind="bannerProps"
|
|
32
|
+
/>
|
|
33
|
+
<Metadata
|
|
34
|
+
v-bind="metadataProps"
|
|
35
|
+
class="mmt-4"
|
|
36
|
+
/>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<style lang="scss" scoped>
|
|
40
|
+
.new.state-banner {
|
|
41
|
+
margin: 0;
|
|
42
|
+
margin-top: 16px;
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
|
-
|
|
3
2
|
import ResourceDetail from '@shell/components/ResourceDetail/index.vue';
|
|
4
3
|
import { _EDIT, _VIEW, LEGACY, MODE } from '@shell/config/query-params';
|
|
4
|
+
import * as pageEnabled from '@shell/composables/useIsNewDetailPageEnabled';
|
|
5
5
|
import flushPromises from 'flush-promises';
|
|
6
|
+
import { computed } from 'vue';
|
|
6
7
|
|
|
7
8
|
const mockQuery: any = {};
|
|
8
9
|
const mockParams: any = {};
|
|
@@ -30,13 +31,22 @@ jest.mock('vue-router', () => ({
|
|
|
30
31
|
})
|
|
31
32
|
}));
|
|
32
33
|
|
|
34
|
+
jest.mock('@shell/composables/useIsNewDetailPageEnabled');
|
|
35
|
+
|
|
33
36
|
describe('component: ResourceDetail/index', () => {
|
|
34
37
|
const resourceName = 'configmap';
|
|
38
|
+
const useIsNewDetailPageEnabledSpy = jest.spyOn(pageEnabled, 'useIsNewDetailPageEnabled');
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
jest.clearAllMocks();
|
|
42
|
+
});
|
|
35
43
|
|
|
36
|
-
it('should render legacy component with default props if
|
|
44
|
+
it('should render legacy component with default props if useIsNewDetailPageEnabledSpy is false', async() => {
|
|
37
45
|
mockParams.resource = resourceName;
|
|
38
46
|
mockQuery[MODE] = _VIEW;
|
|
39
47
|
|
|
48
|
+
useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => false));
|
|
49
|
+
|
|
40
50
|
const wrapper = mount(ResourceDetail, { });
|
|
41
51
|
const legacyComponent = wrapper.findComponent<any>({ name: 'Legacy' });
|
|
42
52
|
|
|
@@ -46,26 +56,33 @@ describe('component: ResourceDetail/index', () => {
|
|
|
46
56
|
expect(legacyComponent.props('resourceOverride')).toBeUndefined();
|
|
47
57
|
expect(legacyComponent.props('parentRouteOverride')).toBeUndefined();
|
|
48
58
|
expect(legacyComponent.props('errorsMap')).toBeUndefined();
|
|
59
|
+
expect(useIsNewDetailPageEnabledSpy).toHaveBeenCalledTimes(1);
|
|
49
60
|
});
|
|
50
61
|
|
|
51
|
-
it('should render legacy component with default props if
|
|
62
|
+
it('should render legacy component with default props if useIsNewDetailPageEnabledSpy is false but resourceName has not been added to our mapping', async() => {
|
|
52
63
|
mockParams.resource = 'notMapped';
|
|
53
64
|
mockQuery[MODE] = _VIEW;
|
|
54
65
|
|
|
66
|
+
useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => false));
|
|
67
|
+
|
|
55
68
|
const wrapper = mount(ResourceDetail, {});
|
|
56
69
|
const legacyComponent = wrapper.findComponent<any>({ name: 'Legacy' });
|
|
57
70
|
|
|
58
71
|
expect(legacyComponent.exists()).toBeTruthy();
|
|
72
|
+
expect(useIsNewDetailPageEnabledSpy).toHaveBeenCalledTimes(1);
|
|
59
73
|
});
|
|
60
74
|
|
|
61
|
-
it('should render legacy component with default props if
|
|
75
|
+
it('should render legacy component with default props if useIsNewDetailPageEnabledSpy is false but mode is not VIEW', async() => {
|
|
62
76
|
mockParams.resource = resourceName;
|
|
63
77
|
mockQuery[MODE] = _EDIT;
|
|
64
78
|
|
|
79
|
+
useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => false));
|
|
80
|
+
|
|
65
81
|
const wrapper = mount(ResourceDetail, {});
|
|
66
82
|
const legacyComponent = wrapper.findComponent<any>({ name: 'Legacy' });
|
|
67
83
|
|
|
68
84
|
expect(legacyComponent.exists()).toBeTruthy();
|
|
85
|
+
expect(useIsNewDetailPageEnabledSpy).toHaveBeenCalledTimes(1);
|
|
69
86
|
});
|
|
70
87
|
|
|
71
88
|
it('should render legacy component while forwarding props', async() => {
|
|
@@ -99,16 +116,20 @@ describe('component: ResourceDetail/index', () => {
|
|
|
99
116
|
expect(legacyComponent.props('errorsMap')).toStrictEqual(errorsMap);
|
|
100
117
|
});
|
|
101
118
|
|
|
102
|
-
it('should render new component if
|
|
119
|
+
it('should render new component if useIsNewDetailPageEnabledSpy is true', async() => {
|
|
103
120
|
mockParams.resource = resourceName;
|
|
121
|
+
mockParams.id = 'ID';
|
|
104
122
|
mockQuery[MODE] = _VIEW;
|
|
105
123
|
mockQuery[LEGACY] = 'false';
|
|
106
124
|
|
|
125
|
+
useIsNewDetailPageEnabledSpy.mockReturnValue(computed(() => true));
|
|
126
|
+
|
|
107
127
|
const wrapper = mount(ResourceDetail);
|
|
108
128
|
|
|
109
129
|
await flushPromises();
|
|
110
130
|
const configmapComponent = wrapper.findComponent<any>({ name: 'configmap' });
|
|
111
131
|
|
|
112
132
|
expect(configmapComponent.exists()).toBeTruthy();
|
|
133
|
+
expect(useIsNewDetailPageEnabledSpy).toHaveBeenCalledTimes(1);
|
|
113
134
|
});
|
|
114
135
|
});
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { useRoute } from 'vue-router';
|
|
3
3
|
import { computed, defineAsyncComponent } from 'vue';
|
|
4
4
|
|
|
5
|
-
import { MODE, _VIEW
|
|
5
|
+
import { MODE, _VIEW } from '@shell/config/query-params';
|
|
6
6
|
import Legacy from '@shell/components/ResourceDetail/legacy.vue';
|
|
7
7
|
import Loading from '@shell/components/Loading.vue';
|
|
8
|
+
import { useIsNewDetailPageEnabled } from '@shell/composables/useIsNewDetailPageEnabled';
|
|
8
9
|
|
|
9
10
|
export interface Props {
|
|
10
11
|
flexContent?: boolean;
|
|
@@ -22,19 +23,20 @@ export interface Props {
|
|
|
22
23
|
// I could also dynamically check for and import these pages but I wanted this to be easier
|
|
23
24
|
// to be explicit and easier to search for.
|
|
24
25
|
const resourceToPage: any = {
|
|
25
|
-
// 'apps.daemonset':
|
|
26
|
-
// 'apps.deployment':
|
|
27
|
-
// 'apps.statefulset':
|
|
28
|
-
// 'batch.cronjob':
|
|
29
|
-
// 'batch.job':
|
|
30
|
-
// 'cluster-dashboard': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/cluster-dashboard.vue')),
|
|
26
|
+
// 'apps.daemonset': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/apps.daemonset.vue')),
|
|
27
|
+
// 'apps.deployment': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/apps.deployment.vue')),
|
|
28
|
+
// 'apps.statefulset': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/apps.statefulset.vue')),
|
|
29
|
+
// 'batch.cronjob': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/batch.cronjob.vue')),
|
|
30
|
+
// 'batch.job': defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/batch.job.vue')),
|
|
31
31
|
configmap: defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/configmap.vue')),
|
|
32
32
|
// namespace: defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/namespace.vue')),
|
|
33
33
|
// node: defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/node.vue')),
|
|
34
34
|
// pod: defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/pod.vue')),
|
|
35
|
-
|
|
35
|
+
secret: defineAsyncComponent(() => import('@shell/pages/explorer/resource/detail/secret.vue')),
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
defineOptions({ inheritAttrs: false });
|
|
39
|
+
|
|
38
40
|
const route = useRoute();
|
|
39
41
|
const props = withDefaults(defineProps<Props>(), {
|
|
40
42
|
flexContent: false,
|
|
@@ -45,14 +47,26 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
45
47
|
errorsMap: undefined
|
|
46
48
|
});
|
|
47
49
|
|
|
48
|
-
const currentResourceName = computed
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const currentResourceName = computed(() => {
|
|
51
|
+
const resource = route?.params?.resource;
|
|
52
|
+
|
|
53
|
+
if (!resource) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
if (typeof resource === 'string') {
|
|
58
|
+
return resource;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// This should never occur, just satisfying the types
|
|
62
|
+
return resource[0];
|
|
63
|
+
});
|
|
64
|
+
const mode = computed(() => route?.query?.[MODE]);
|
|
65
|
+
const isView = computed(() => route?.params?.id && (!mode.value || mode.value === _VIEW));
|
|
66
|
+
// We're defaulting to legacy being on, we'll switch this once we want to enable the new detail page by default
|
|
67
|
+
const iseNewDetailPageEnabled = useIsNewDetailPageEnabled();
|
|
68
|
+
const page = computed(() => currentResourceName.value ? resourceToPage[currentResourceName.value] : undefined);
|
|
69
|
+
const useLatest = computed(() => !!(iseNewDetailPageEnabled.value && isView.value && page.value));
|
|
56
70
|
</script>
|
|
57
71
|
|
|
58
72
|
<template>
|
|
@@ -66,6 +80,6 @@ const useLatest = computed(() => !!(!isLegacy.value && isView.value && page.valu
|
|
|
66
80
|
</Suspense>
|
|
67
81
|
<Legacy
|
|
68
82
|
v-else
|
|
69
|
-
v-bind="props"
|
|
83
|
+
v-bind="{...$attrs, ...props}"
|
|
70
84
|
/>
|
|
71
85
|
</template>
|
|
@@ -379,6 +379,16 @@ export default {
|
|
|
379
379
|
closeError(index) {
|
|
380
380
|
this.errors = this.errors.filter((_, i) => i !== index);
|
|
381
381
|
},
|
|
382
|
+
onYamlError(err) {
|
|
383
|
+
this.errors = [];
|
|
384
|
+
const errors = Array.isArray(err) ? err : [err];
|
|
385
|
+
|
|
386
|
+
errors.forEach((e) => {
|
|
387
|
+
if (this.errors.indexOf(e) === -1) {
|
|
388
|
+
this.errors.push(e);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
},
|
|
382
392
|
/**
|
|
383
393
|
* Initializes the resource components based on the provided user and
|
|
384
394
|
* resource override.
|
|
@@ -483,8 +493,9 @@ export default {
|
|
|
483
493
|
:offer-preview="offerPreview"
|
|
484
494
|
:done-route="doneRoute"
|
|
485
495
|
:done-override="value ? value.doneOverride : null"
|
|
496
|
+
:show-errors="false"
|
|
486
497
|
@update:value="$emit('input', $event)"
|
|
487
|
-
@error="
|
|
498
|
+
@error="onYamlError"
|
|
488
499
|
/>
|
|
489
500
|
|
|
490
501
|
<component
|
|
@@ -542,4 +553,10 @@ export default {
|
|
|
542
553
|
flex-direction: column;
|
|
543
554
|
flex-grow: 1;
|
|
544
555
|
}
|
|
556
|
+
.cru__errors {
|
|
557
|
+
position: sticky;
|
|
558
|
+
top: 0;
|
|
559
|
+
z-index: 1;
|
|
560
|
+
background-color: var(--header-bg);
|
|
561
|
+
}
|
|
545
562
|
</style>
|
|
@@ -157,6 +157,12 @@ export default {
|
|
|
157
157
|
},
|
|
158
158
|
|
|
159
159
|
_createButtonlabel() {
|
|
160
|
+
const overrideLabel = this.$store.getters['type-map/optionsFor'](this.resource).listCreateButtonLabelKey;
|
|
161
|
+
|
|
162
|
+
if (overrideLabel) {
|
|
163
|
+
return this.t(overrideLabel);
|
|
164
|
+
}
|
|
165
|
+
|
|
160
166
|
return this.createButtonLabel || this.t('resourceList.head.create');
|
|
161
167
|
},
|
|
162
168
|
}
|
|
@@ -73,6 +73,11 @@ export default {
|
|
|
73
73
|
default: true
|
|
74
74
|
},
|
|
75
75
|
|
|
76
|
+
showErrors: {
|
|
77
|
+
type: Boolean,
|
|
78
|
+
default: true
|
|
79
|
+
},
|
|
80
|
+
|
|
76
81
|
applyHooks: {
|
|
77
82
|
type: Function,
|
|
78
83
|
default: null,
|
|
@@ -289,6 +294,13 @@ export default {
|
|
|
289
294
|
}
|
|
290
295
|
},
|
|
291
296
|
|
|
297
|
+
refresh() {
|
|
298
|
+
this.$refs.yamleditor.refresh();
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
closeError(index) {
|
|
302
|
+
this.errors = (this.errors || []).filter((_, i) => i !== index);
|
|
303
|
+
},
|
|
292
304
|
}
|
|
293
305
|
};
|
|
294
306
|
</script>
|
|
@@ -318,7 +330,8 @@ export default {
|
|
|
318
330
|
class="footer"
|
|
319
331
|
:class="{ 'edit': !isView }"
|
|
320
332
|
:mode="mode"
|
|
321
|
-
:errors="errors"
|
|
333
|
+
:errors="showErrors ? errors : []"
|
|
334
|
+
@close-error="closeError"
|
|
322
335
|
@save="save"
|
|
323
336
|
@done="done"
|
|
324
337
|
>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { computed, watch } from 'vue';
|
|
2
|
+
import { computed, onBeforeUnmount, watch } from 'vue';
|
|
3
3
|
import { useStore } from 'vuex';
|
|
4
4
|
import {
|
|
5
5
|
DEFAULT_FOCUS_TRAP_OPTS,
|
|
6
6
|
useWatcherBasedSetupFocusTrapWithDestroyIncluded
|
|
7
7
|
} from '@shell/composables/focusTrap';
|
|
8
|
+
import { isEqual } from 'lodash';
|
|
9
|
+
import { useRouter } from 'vue-router';
|
|
8
10
|
|
|
9
11
|
const HEADER_HEIGHT = 55;
|
|
10
12
|
|
|
@@ -15,6 +17,11 @@ const currentComponent = computed(() => store.getters['slideInPanel/component'])
|
|
|
15
17
|
const currentProps = computed(() => store.getters['slideInPanel/componentProps']);
|
|
16
18
|
|
|
17
19
|
const panelTop = computed(() => {
|
|
20
|
+
// Some components like the ResourceDetailDrawer are designed to take up the full height of the viewport so we want to be able to specify the top.
|
|
21
|
+
if (currentProps?.value?.top) {
|
|
22
|
+
return currentProps?.value?.top;
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
const banner = document.getElementById('banner-header');
|
|
19
26
|
let height = HEADER_HEIGHT;
|
|
20
27
|
|
|
@@ -25,13 +32,24 @@ const panelTop = computed(() => {
|
|
|
25
32
|
return `${ height }px`;
|
|
26
33
|
});
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
// Some components like the ResourceDetailDrawer are designed to take up the full height of the viewport so we want to be able to specify the height.
|
|
36
|
+
const panelHeight = computed(() => (currentProps?.value?.height) ? (currentProps?.value?.height) : `calc(100vh - ${ panelTop?.value })`);
|
|
29
37
|
const panelWidth = computed(() => currentProps?.value?.width || '33%');
|
|
30
38
|
const panelRight = computed(() => (isOpen?.value ? '0' : `-${ panelWidth?.value }`));
|
|
31
39
|
const panelZIndex = computed(() => `${ (isOpen?.value ? 1 : 2) * (currentProps?.value?.zIndex ?? 1000) }`);
|
|
32
40
|
|
|
33
41
|
const showHeader = computed(() => currentProps?.value?.showHeader ?? true);
|
|
34
42
|
const panelTitle = showHeader.value ? computed(() => currentProps?.value?.title || 'Details') : null;
|
|
43
|
+
const closeOnRouteChange = computed(() => {
|
|
44
|
+
const propsCloseOnRouteChange = currentProps?.value.closeOnRouteChange;
|
|
45
|
+
|
|
46
|
+
if (!propsCloseOnRouteChange) {
|
|
47
|
+
return ['name', 'params', 'hash', 'query'];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return propsCloseOnRouteChange;
|
|
51
|
+
});
|
|
52
|
+
const router = useRouter();
|
|
35
53
|
|
|
36
54
|
watch(
|
|
37
55
|
/**
|
|
@@ -75,15 +93,33 @@ watch(
|
|
|
75
93
|
);
|
|
76
94
|
|
|
77
95
|
watch(
|
|
78
|
-
() =>
|
|
79
|
-
() => {
|
|
80
|
-
if (isOpen?.value
|
|
96
|
+
() => router?.currentRoute?.value,
|
|
97
|
+
(newValue, oldValue) => {
|
|
98
|
+
if (!isOpen?.value) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (closeOnRouteChange.value.includes('name') && !isEqual(newValue?.name, oldValue?.name)) {
|
|
103
|
+
closePanel();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (closeOnRouteChange.value.includes('params') && !isEqual(newValue?.params, oldValue?.params)) {
|
|
107
|
+
closePanel();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (closeOnRouteChange.value.includes('hash') && !isEqual(newValue?.hash, oldValue?.hash)) {
|
|
111
|
+
closePanel();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (closeOnRouteChange.value.includes('query') && !isEqual(newValue?.query, oldValue?.query)) {
|
|
81
115
|
closePanel();
|
|
82
116
|
}
|
|
83
117
|
},
|
|
84
118
|
{ deep: true }
|
|
85
119
|
);
|
|
86
120
|
|
|
121
|
+
onBeforeUnmount(closePanel);
|
|
122
|
+
|
|
87
123
|
function closePanel() {
|
|
88
124
|
store.commit('slideInPanel/close');
|
|
89
125
|
}
|
|
@@ -100,9 +136,12 @@ function closePanel() {
|
|
|
100
136
|
data-testid="slide-in-glass"
|
|
101
137
|
class="slide-in-glass"
|
|
102
138
|
:class="{ 'slide-in-glass-open': isOpen }"
|
|
139
|
+
:style="{
|
|
140
|
+
['z-index']: panelZIndex
|
|
141
|
+
}"
|
|
103
142
|
@click="closePanel"
|
|
104
143
|
/>
|
|
105
|
-
<
|
|
144
|
+
<aside
|
|
106
145
|
class="slide-in"
|
|
107
146
|
:class="{ 'slide-in-open': isOpen }"
|
|
108
147
|
:style="{
|
|
@@ -136,7 +175,7 @@ function closePanel() {
|
|
|
136
175
|
class="dynamic-panel-content"
|
|
137
176
|
/>
|
|
138
177
|
</div>
|
|
139
|
-
</
|
|
178
|
+
</aside>
|
|
140
179
|
</div>
|
|
141
180
|
</Teleport>
|
|
142
181
|
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { StateColor, stateColorCssVar } from '@shell/utils/style';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
color: StateColor;
|
|
7
|
+
size?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<Props>(), { size: '8px' });
|
|
11
|
+
const backgroundColor = computed(() => stateColorCssVar(props.color));
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<span class="state-dot" />
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<style lang="scss" scoped>
|
|
19
|
+
.state-dot {
|
|
20
|
+
display: inline-block;
|
|
21
|
+
|
|
22
|
+
width: v-bind('props.size');
|
|
23
|
+
height: v-bind('props.size');
|
|
24
|
+
|
|
25
|
+
border-radius: 50%;
|
|
26
|
+
background-color: v-bind('backgroundColor');
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
@@ -145,17 +145,10 @@ export default {
|
|
|
145
145
|
this.select(activeTab.name);
|
|
146
146
|
}
|
|
147
147
|
},
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
window.addEventListener('hashchange', this.hashChange);
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
unmounted() {
|
|
157
|
-
if ( this.useHash ) {
|
|
158
|
-
window.removeEventListener('hashchange', this.hashChange);
|
|
148
|
+
'$route.hash'() {
|
|
149
|
+
if ( this.useHash ) {
|
|
150
|
+
this.hashChange();
|
|
151
|
+
}
|
|
159
152
|
}
|
|
160
153
|
},
|
|
161
154
|
|
|
@@ -164,7 +157,7 @@ export default {
|
|
|
164
157
|
return tab.displayAlertIcon || (tab.error && !tab.active);
|
|
165
158
|
},
|
|
166
159
|
hashChange() {
|
|
167
|
-
if (
|
|
160
|
+
if (this.scrollOnChange) {
|
|
168
161
|
const scrollable = document.getElementsByTagName('main')[0];
|
|
169
162
|
|
|
170
163
|
if (scrollable) {
|
|
@@ -182,8 +175,9 @@ export default {
|
|
|
182
175
|
select(name/* , event */) {
|
|
183
176
|
const { sortedTabs } = this;
|
|
184
177
|
|
|
185
|
-
const
|
|
186
|
-
const
|
|
178
|
+
const cleanName = name.replace('#', '');
|
|
179
|
+
const selected = this.find(cleanName);
|
|
180
|
+
const hashName = `#${ cleanName }`;
|
|
187
181
|
|
|
188
182
|
if ( !selected || selected.disabled) {
|
|
189
183
|
return;
|
|
@@ -281,7 +275,7 @@ export default {
|
|
|
281
275
|
>
|
|
282
276
|
<a
|
|
283
277
|
:data-testid="`btn-${tab.name}`"
|
|
284
|
-
:aria-controls="
|
|
278
|
+
:aria-controls="tab.name"
|
|
285
279
|
:aria-selected="tab.active"
|
|
286
280
|
:aria-label="tab.labelDisplay || ''"
|
|
287
281
|
role="tab"
|
|
@@ -318,6 +312,7 @@ export default {
|
|
|
318
312
|
type="button"
|
|
319
313
|
class="btn bg-transparent"
|
|
320
314
|
data-testid="tab-list-add"
|
|
315
|
+
:aria-label="t('tabs.addItem')"
|
|
321
316
|
@click="tabAddClicked"
|
|
322
317
|
>
|
|
323
318
|
<i class="icon icon-plus" />
|
|
@@ -327,6 +322,7 @@ export default {
|
|
|
327
322
|
class="btn bg-transparent"
|
|
328
323
|
:disabled="!sortedTabs.length"
|
|
329
324
|
data-testid="tab-list-remove"
|
|
325
|
+
:aria-label="t('tabs.removeItem')"
|
|
330
326
|
@click="tabRemoveClicked"
|
|
331
327
|
>
|
|
332
328
|
<i class="icon icon-minus" />
|
package/components/Wizard.vue
CHANGED
|
@@ -361,7 +361,7 @@ export default {
|
|
|
361
361
|
role="presentation"
|
|
362
362
|
>
|
|
363
363
|
<span
|
|
364
|
-
:aria-controls="'step' +
|
|
364
|
+
:aria-controls="'step-container-' + step.name"
|
|
365
365
|
:aria-selected="step.name === activeStep.name"
|
|
366
366
|
role="tab"
|
|
367
367
|
class="controls"
|
|
@@ -376,7 +376,7 @@ export default {
|
|
|
376
376
|
</span>
|
|
377
377
|
</span>
|
|
378
378
|
</li>
|
|
379
|
-
<
|
|
379
|
+
<li
|
|
380
380
|
v-if="idx!==visibleSteps.length-1"
|
|
381
381
|
:key="step.name"
|
|
382
382
|
class="divider"
|
|
@@ -397,7 +397,9 @@ export default {
|
|
|
397
397
|
>
|
|
398
398
|
<div
|
|
399
399
|
v-if="step.name === activeStep.name || step.hidden"
|
|
400
|
+
:id="'step-container-' + step.name"
|
|
400
401
|
:key="step.name"
|
|
402
|
+
role="tabpanel"
|
|
401
403
|
class="step-container__step"
|
|
402
404
|
:class="{'hide': step.name !== activeStep.name && step.hidden}"
|
|
403
405
|
>
|