@rancher/shell 3.0.12-rc.3 → 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/assets/styles/global/_layout.scss +4 -0
- package/assets/translations/en-us.yaml +144 -41
- package/assets/translations/zh-hans.yaml +1 -7
- package/chart/monitoring/ClusterSelector.vue +0 -21
- package/chart/monitoring/prometheus/index.vue +6 -3
- package/components/CruResource.vue +161 -14
- package/components/ExplorerMembers.vue +8 -4
- package/components/ExplorerProjectsNamespaces.vue +10 -6
- package/components/GrowlManager.vue +4 -0
- 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 +2 -0
- package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
- package/components/ResourceDetail/index.vue +1 -1
- package/components/ResourceList/Masthead.vue +7 -1
- package/components/ResourceList/index.vue +82 -1
- package/components/RichTranslation.vue +5 -2
- package/components/Setting.vue +1 -0
- 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 +9 -4
- 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/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
- package/components/fleet/FleetClusterTargets/index.vue +189 -146
- 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 +253 -0
- 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 +39 -1
- package/components/form/Labels.vue +22 -3
- package/components/form/NameNsDescription.vue +13 -5
- package/components/form/ResourceTabs/index.vue +1 -0
- package/components/form/__tests__/NameNsDescription.test.ts +75 -0
- package/components/formatter/InternalExternalIP.vue +10 -4
- package/components/formatter/ServiceTargets.vue +26 -7
- package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
- package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
- package/components/nav/Header.vue +4 -0
- package/components/nav/TopLevelMenu.vue +7 -2
- package/components/nav/__tests__/Header.test.ts +15 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
- package/components/templates/default.vue +9 -4
- package/components/templates/home.vue +9 -4
- package/components/templates/plain.vue +9 -4
- 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/config/home-links.js +1 -1
- package/config/labels-annotations.js +1 -0
- package/config/product/explorer.js +17 -4
- package/config/product/manager.js +2 -0
- 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 +20 -6
- package/config/settings.ts +0 -2
- package/config/table-headers.js +3 -4
- package/config/types.js +9 -0
- package/core/plugin-products-base.ts +3 -3
- package/core/plugin-types.ts +83 -30
- package/core/plugin.ts +3 -0
- package/core/types-provisioning.ts +34 -1
- package/core/types.ts +15 -2
- 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/provisioning.cattle.io.cluster.vue +30 -4
- 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 +34 -9
- 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 +128 -95
- 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/provisioning.cattle.io.cluster/rke2.vue +84 -10
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -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 +16 -10
- package/mixins/__tests__/auth-config.test.ts +90 -0
- package/mixins/__tests__/chart.test.ts +94 -0
- package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
- package/mixins/auth-config.js +7 -0
- package/mixins/chart.js +11 -2
- package/mixins/child-hook.js +12 -6
- package/mixins/create-edit-view/impl.js +5 -3
- package/mixins/resource-fetch-api-pagination.js +21 -1
- 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__/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.node.ts +22 -0
- package/models/__tests__/namespace.test.ts +36 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +49 -0
- package/models/__tests__/workload.test.ts +401 -26
- package/models/catalog.cattle.io.clusterrepo.js +28 -4
- package/models/compliance.cattle.io.clusterscan.js +39 -4
- package/models/fleet-application.js +4 -0
- package/models/fleet.cattle.io.helmop.js +20 -1
- package/models/management.cattle.io.cluster.js +18 -2
- package/models/management.cattle.io.node.js +44 -3
- package/models/namespace.js +1 -1
- package/models/pod.js +33 -1
- package/models/provisioning.cattle.io.cluster.js +5 -5
- package/models/workload.js +108 -13
- package/models/workload.service.js +5 -0
- package/package.json +14 -13
- package/pages/about.vue +5 -6
- package/pages/auth/login.vue +0 -35
- package/pages/auth/setup.vue +11 -0
- 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__/index.test.ts +93 -0
- package/pages/c/_cluster/apps/charts/chart.vue +2 -1
- package/pages/c/_cluster/apps/charts/index.vue +48 -10
- package/pages/c/_cluster/apps/charts/install.vue +122 -116
- package/pages/c/_cluster/auth/roles/index.vue +5 -4
- 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/uiplugins/__tests__/index.test.ts +96 -0
- package/pages/c/_cluster/uiplugins/index.vue +15 -0
- package/pages/fail-whale.vue +16 -11
- package/pages/home.vue +16 -46
- package/plugins/clean-html.d.ts +9 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +93 -0
- package/plugins/dashboard-store/resource-class.js +62 -7
- package/plugins/steve/__tests__/actions.test.ts +212 -0
- package/plugins/steve/actions.js +96 -0
- package/plugins/steve/steve-pagination-utils.ts +1 -1
- package/rancher-components/Accordion/Accordion.vue +53 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
- 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 +103 -0
- package/rancher-components/RcButton/RcButton.vue +94 -15
- package/rancher-components/RcButton/types.ts +3 -0
- 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__/notifications.test.ts +434 -0
- package/store/catalog.js +57 -0
- package/store/plugins.js +7 -4
- package/types/components/buttonGroup.ts +5 -0
- package/types/shell/index.d.ts +104 -70
- package/utils/__tests__/auth.test.ts +273 -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 +37 -1
- package/utils/__tests__/dynamic-importer.test.ts +102 -0
- package/utils/__tests__/fleet-appco.test.ts +312 -0
- package/utils/__tests__/monitoring.test.ts +130 -0
- package/utils/__tests__/object.test.ts +22 -0
- package/utils/__tests__/platform.test.ts +91 -0
- package/utils/__tests__/position.test.ts +237 -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__/time.test.ts +265 -1
- package/utils/__tests__/title.test.ts +47 -0
- package/utils/__tests__/width.test.ts +53 -0
- package/utils/__tests__/window.test.ts +158 -0
- package/utils/__tests__/xccdf.test.ts +126 -6
- 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/object.js +22 -2
- package/utils/provider.ts +12 -0
- package/utils/validators/__tests__/container-images.test.ts +104 -0
- package/utils/validators/__tests__/flow-output.test.ts +91 -0
- package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
- package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
- package/utils/xccdf.ts +39 -42
- package/vue.config.js +1 -1
- package/pages/support/index.vue +0 -264
- package/utils/duration.js +0 -43
|
@@ -52,4 +52,97 @@ describe('page: Charts Index', () => {
|
|
|
52
52
|
expect(hasExtensionCategory).toBe(false);
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
|
+
|
|
56
|
+
describe('method: loadMore', () => {
|
|
57
|
+
const createContext = (overrides: Record<string, any> = {}) => ({
|
|
58
|
+
isLoadingMore: false,
|
|
59
|
+
visibleChartsCount: 30,
|
|
60
|
+
initialVisibleChartsCount: 30,
|
|
61
|
+
filteredCharts: new Array(100),
|
|
62
|
+
_loadMoreTimer: null,
|
|
63
|
+
$nextTick: (cb: () => void) => cb(),
|
|
64
|
+
...overrides,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
jest.useFakeTimers();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
afterEach(() => {
|
|
72
|
+
jest.useRealTimers();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should set isLoadingMore, then increment visibleChartsCount and clear the flag after the delay', () => {
|
|
76
|
+
const ctx = createContext();
|
|
77
|
+
|
|
78
|
+
(Charts.methods!.loadMore as () => void).call(ctx);
|
|
79
|
+
|
|
80
|
+
expect(ctx.isLoadingMore).toBe(true);
|
|
81
|
+
expect(ctx.visibleChartsCount).toBe(30);
|
|
82
|
+
expect(ctx._loadMoreTimer).not.toBeNull();
|
|
83
|
+
|
|
84
|
+
jest.runAllTimers();
|
|
85
|
+
|
|
86
|
+
expect(ctx.visibleChartsCount).toBe(60);
|
|
87
|
+
expect(ctx.isLoadingMore).toBe(false);
|
|
88
|
+
expect(ctx._loadMoreTimer).toBeNull();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should do nothing when already loading', () => {
|
|
92
|
+
const ctx = createContext({ isLoadingMore: true });
|
|
93
|
+
|
|
94
|
+
(Charts.methods!.loadMore as () => void).call(ctx);
|
|
95
|
+
|
|
96
|
+
expect(ctx._loadMoreTimer).toBeNull();
|
|
97
|
+
expect(ctx.visibleChartsCount).toBe(30);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should do nothing when all charts are already visible', () => {
|
|
101
|
+
const ctx = createContext({ visibleChartsCount: 100 });
|
|
102
|
+
|
|
103
|
+
(Charts.methods!.loadMore as () => void).call(ctx);
|
|
104
|
+
|
|
105
|
+
expect(ctx.isLoadingMore).toBe(false);
|
|
106
|
+
expect(ctx._loadMoreTimer).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe('method: resetLazyLoadState', () => {
|
|
111
|
+
beforeEach(() => {
|
|
112
|
+
jest.useFakeTimers();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
afterEach(() => {
|
|
116
|
+
jest.useRealTimers();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should reset state and cancel a pending loadMore so visibleChartsCount is not incremented after reset', () => {
|
|
120
|
+
const ctx: Record<string, any> = {
|
|
121
|
+
isLoadingMore: false,
|
|
122
|
+
visibleChartsCount: 30,
|
|
123
|
+
initialVisibleChartsCount: 30,
|
|
124
|
+
observerInitialized: true,
|
|
125
|
+
hasOverflow: true,
|
|
126
|
+
filteredCharts: new Array(100),
|
|
127
|
+
_loadMoreTimer: null,
|
|
128
|
+
$nextTick: (cb: () => void) => cb(),
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
(Charts.methods!.loadMore as () => void).call(ctx);
|
|
132
|
+
expect(ctx._loadMoreTimer).not.toBeNull();
|
|
133
|
+
|
|
134
|
+
(Charts.methods!.resetLazyLoadState as () => void).call(ctx);
|
|
135
|
+
|
|
136
|
+
expect(ctx.visibleChartsCount).toBe(30);
|
|
137
|
+
expect(ctx.observerInitialized).toBe(false);
|
|
138
|
+
expect(ctx.hasOverflow).toBe(false);
|
|
139
|
+
expect(ctx.isLoadingMore).toBe(false);
|
|
140
|
+
expect(ctx._loadMoreTimer).toBeNull();
|
|
141
|
+
|
|
142
|
+
jest.runAllTimers();
|
|
143
|
+
|
|
144
|
+
// The cancelled timer must not have fired — count stays at the reset value.
|
|
145
|
+
expect(ctx.visibleChartsCount).toBe(30);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
55
148
|
});
|
|
@@ -859,6 +859,7 @@ export default {
|
|
|
859
859
|
.readme-wrapper {
|
|
860
860
|
position: relative;
|
|
861
861
|
flex: 1;
|
|
862
|
+
min-width: 0;
|
|
862
863
|
|
|
863
864
|
.open-readme-button {
|
|
864
865
|
display: flex;
|
|
@@ -881,7 +882,7 @@ export default {
|
|
|
881
882
|
|
|
882
883
|
&__readme {
|
|
883
884
|
flex: 1;
|
|
884
|
-
min-width:
|
|
885
|
+
min-width: 0;
|
|
885
886
|
padding: 12px 24px;
|
|
886
887
|
}
|
|
887
888
|
&__info {
|
|
@@ -25,6 +25,7 @@ import AppChartCardFooter from '@shell/pages/c/_cluster/apps/charts/AppChartCard
|
|
|
25
25
|
import AddRepoLink from '@shell/pages/c/_cluster/apps/charts/AddRepoLink';
|
|
26
26
|
import StatusLabel from '@shell/pages/c/_cluster/apps/charts/StatusLabel';
|
|
27
27
|
import RichTranslation from '@shell/components/RichTranslation.vue';
|
|
28
|
+
import SubtleLink from '@shell/components/SubtleLink.vue';
|
|
28
29
|
import { getLatestCompatibleVersion } from '@shell/utils/chart';
|
|
29
30
|
import Select from '@shell/components/form/Select';
|
|
30
31
|
import { getVersionData } from '@shell/config/version';
|
|
@@ -36,6 +37,8 @@ const createInitialFilters = () => ({
|
|
|
36
37
|
tags: []
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
const LOAD_MORE_DELAY_MS = 500;
|
|
41
|
+
|
|
39
42
|
export default {
|
|
40
43
|
name: 'Charts',
|
|
41
44
|
components: {
|
|
@@ -47,7 +50,8 @@ export default {
|
|
|
47
50
|
AppChartCardSubHeader,
|
|
48
51
|
AppChartCardFooter,
|
|
49
52
|
Select,
|
|
50
|
-
RichTranslation
|
|
53
|
+
RichTranslation,
|
|
54
|
+
SubtleLink,
|
|
51
55
|
},
|
|
52
56
|
|
|
53
57
|
async fetch() {
|
|
@@ -84,6 +88,10 @@ export default {
|
|
|
84
88
|
if (this.observer) {
|
|
85
89
|
this.observer.disconnect();
|
|
86
90
|
}
|
|
91
|
+
if (this._loadMoreTimer) {
|
|
92
|
+
clearTimeout(this._loadMoreTimer);
|
|
93
|
+
this._loadMoreTimer = null;
|
|
94
|
+
}
|
|
87
95
|
},
|
|
88
96
|
|
|
89
97
|
data() {
|
|
@@ -145,6 +153,7 @@ export default {
|
|
|
145
153
|
canCreateRepos: false,
|
|
146
154
|
showAppCollectionBanner: true,
|
|
147
155
|
isPrime: getVersionData().RancherPrime === 'true',
|
|
156
|
+
isLoadingMore: false,
|
|
148
157
|
};
|
|
149
158
|
},
|
|
150
159
|
|
|
@@ -482,6 +491,11 @@ export default {
|
|
|
482
491
|
this.visibleChartsCount = this.initialVisibleChartsCount;
|
|
483
492
|
this.observerInitialized = false;
|
|
484
493
|
this.hasOverflow = false;
|
|
494
|
+
this.isLoadingMore = false;
|
|
495
|
+
if (this._loadMoreTimer) {
|
|
496
|
+
clearTimeout(this._loadMoreTimer);
|
|
497
|
+
this._loadMoreTimer = null;
|
|
498
|
+
}
|
|
485
499
|
},
|
|
486
500
|
|
|
487
501
|
// The lazy loading implementation has two parts
|
|
@@ -529,10 +543,17 @@ export default {
|
|
|
529
543
|
},
|
|
530
544
|
|
|
531
545
|
loadMore() {
|
|
532
|
-
if (this.visibleChartsCount >= this.filteredCharts.length) {
|
|
546
|
+
if (this.isLoadingMore || this.visibleChartsCount >= this.filteredCharts.length) {
|
|
533
547
|
return;
|
|
534
548
|
}
|
|
535
|
-
this.
|
|
549
|
+
this.isLoadingMore = true;
|
|
550
|
+
this._loadMoreTimer = setTimeout(() => {
|
|
551
|
+
this._loadMoreTimer = null;
|
|
552
|
+
this.visibleChartsCount += this.initialVisibleChartsCount;
|
|
553
|
+
this.$nextTick(() => {
|
|
554
|
+
this.isLoadingMore = false;
|
|
555
|
+
});
|
|
556
|
+
}, LOAD_MORE_DELAY_MS);
|
|
536
557
|
},
|
|
537
558
|
|
|
538
559
|
initIntersectionObserver() {
|
|
@@ -683,16 +704,13 @@ export default {
|
|
|
683
704
|
tag="span"
|
|
684
705
|
>
|
|
685
706
|
<template #docsUrl="{ content }">
|
|
686
|
-
<
|
|
707
|
+
<SubtleLink
|
|
687
708
|
:href="`${DOCS_BASE}/how-to-guides/new-user-guides/helm-charts-in-rancher`"
|
|
688
|
-
class="secondary-text-link"
|
|
689
|
-
tabindex="0"
|
|
690
709
|
target="_blank"
|
|
691
|
-
|
|
710
|
+
:open-in-new-tab-label="t('generic.opensInNewTab')"
|
|
692
711
|
>
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
</a>
|
|
712
|
+
{{ content }}
|
|
713
|
+
</SubtleLink>
|
|
696
714
|
</template>
|
|
697
715
|
</RichTranslation>
|
|
698
716
|
</div>
|
|
@@ -785,6 +803,16 @@ export default {
|
|
|
785
803
|
</template>
|
|
786
804
|
</rc-item-card>
|
|
787
805
|
</div>
|
|
806
|
+
<div
|
|
807
|
+
v-if="isLoadingMore"
|
|
808
|
+
class="loading-more"
|
|
809
|
+
role="status"
|
|
810
|
+
aria-live="polite"
|
|
811
|
+
data-testid="charts-loading-more"
|
|
812
|
+
>
|
|
813
|
+
<i class="icon icon-spinner icon-spin" />
|
|
814
|
+
{{ t('catalog.charts.loadingMore') }}
|
|
815
|
+
</div>
|
|
788
816
|
<div
|
|
789
817
|
ref="sentinel"
|
|
790
818
|
class="sentinel-charts"
|
|
@@ -838,6 +866,16 @@ export default {
|
|
|
838
866
|
.sentinel-charts {
|
|
839
867
|
height: 1px;
|
|
840
868
|
}
|
|
869
|
+
|
|
870
|
+
.loading-more {
|
|
871
|
+
display: flex;
|
|
872
|
+
align-items: center;
|
|
873
|
+
justify-content: center;
|
|
874
|
+
gap: var(--gap);
|
|
875
|
+
padding: 16px;
|
|
876
|
+
font-size: 14px;
|
|
877
|
+
color: var(--muted);
|
|
878
|
+
}
|
|
841
879
|
}
|
|
842
880
|
|
|
843
881
|
.total-and-sort {
|
|
@@ -22,7 +22,6 @@ import Tabbed from '@shell/components/Tabbed';
|
|
|
22
22
|
import UnitInput from '@shell/components/form/UnitInput';
|
|
23
23
|
import YamlEditor, { EDITOR_MODES } from '@shell/components/YamlEditor';
|
|
24
24
|
import Wizard from '@shell/components/Wizard';
|
|
25
|
-
import TypeDescription from '@shell/components/TypeDescription';
|
|
26
25
|
import ChartMixin from '@shell/mixins/chart';
|
|
27
26
|
import ChildHook, { BEFORE_SAVE_HOOKS, AFTER_SAVE_HOOKS } from '@shell/mixins/child-hook';
|
|
28
27
|
import {
|
|
@@ -41,7 +40,7 @@ import {
|
|
|
41
40
|
import { ignoreVariables } from './install.helpers';
|
|
42
41
|
import { findBy, insertAt } from '@shell/utils/array';
|
|
43
42
|
import { saferDump } from '@shell/utils/create-yaml';
|
|
44
|
-
import { WINDOWS
|
|
43
|
+
import { WINDOWS } from '@shell/store/catalog';
|
|
45
44
|
import { SETTING } from '@shell/config/settings';
|
|
46
45
|
import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthSecret.vue';
|
|
47
46
|
import { generateRandomAlphaString } from '@shell/utils/string';
|
|
@@ -96,7 +95,6 @@ export default {
|
|
|
96
95
|
UnitInput,
|
|
97
96
|
YamlEditor,
|
|
98
97
|
Wizard,
|
|
99
|
-
TypeDescription,
|
|
100
98
|
SelectOrCreateAuthSecret
|
|
101
99
|
},
|
|
102
100
|
|
|
@@ -601,6 +599,10 @@ export default {
|
|
|
601
599
|
return out;
|
|
602
600
|
},
|
|
603
601
|
|
|
602
|
+
selectedVersionOption() {
|
|
603
|
+
return this.filteredVersions?.find((v) => v.id === this.query.versionName) || this.query.versionName;
|
|
604
|
+
},
|
|
605
|
+
|
|
604
606
|
showSelectVersionOrChart() {
|
|
605
607
|
// Allow the user to choose a version if:
|
|
606
608
|
// - the app exists (editing/upgrading)
|
|
@@ -680,7 +682,7 @@ export default {
|
|
|
680
682
|
},
|
|
681
683
|
|
|
682
684
|
stepperSubtext() {
|
|
683
|
-
return this.
|
|
685
|
+
return this.mappedVersions?.find((v) => v.id === this.targetVersion)?.label || this.targetVersion;
|
|
684
686
|
},
|
|
685
687
|
|
|
686
688
|
readmeWindowName() {
|
|
@@ -765,24 +767,6 @@ export default {
|
|
|
765
767
|
return { name: 'c-cluster-legacy-project' };
|
|
766
768
|
},
|
|
767
769
|
|
|
768
|
-
windowsIncompatible() {
|
|
769
|
-
if (this.versionInfo) {
|
|
770
|
-
const isRancher = isRancherRepo(this.repo, this.chart);
|
|
771
|
-
const permittedSystems = getPermittedOSs(this.versionInfo?.chart?.annotations, isRancher);
|
|
772
|
-
const incompatibleVersion = permittedSystems.length > 0 && !permittedSystems.includes('windows');
|
|
773
|
-
|
|
774
|
-
if (incompatibleVersion) {
|
|
775
|
-
if (!this.chart?.windowsIncompatible) {
|
|
776
|
-
return this.t('catalog.charts.versionWindowsIncompatible');
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
return this.t('catalog.charts.windowsIncompatible');
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
return null;
|
|
784
|
-
},
|
|
785
|
-
|
|
786
770
|
/**
|
|
787
771
|
* Check if the chart contains `systemDefaultRegistry` properties.
|
|
788
772
|
* If not we shouldn't apply the setting, because if the option
|
|
@@ -1554,10 +1538,9 @@ export default {
|
|
|
1554
1538
|
<Loading v-if="$fetchState.pending" />
|
|
1555
1539
|
<div
|
|
1556
1540
|
v-else-if="!legacyApp && !mcapp"
|
|
1557
|
-
class="install-steps
|
|
1541
|
+
class="install-steps"
|
|
1558
1542
|
:class="{ 'isPlainLayout': isPlainLayout}"
|
|
1559
1543
|
>
|
|
1560
|
-
<TypeDescription resource="chart" />
|
|
1561
1544
|
<Wizard
|
|
1562
1545
|
v-if="value"
|
|
1563
1546
|
:steps="steps"
|
|
@@ -1567,25 +1550,45 @@ export default {
|
|
|
1567
1550
|
:banner-title-subtext="stepperSubtext"
|
|
1568
1551
|
:finish-mode="action.name"
|
|
1569
1552
|
:header-mode="action.tKey"
|
|
1553
|
+
:show-step-header="false"
|
|
1570
1554
|
class="wizard"
|
|
1571
|
-
:class="{'windowsIncompatible': windowsIncompatible}"
|
|
1572
1555
|
@cancel="cancel"
|
|
1573
1556
|
@finish="finish"
|
|
1574
1557
|
>
|
|
1575
|
-
<template #
|
|
1576
|
-
<div>
|
|
1577
|
-
<div class="logo-
|
|
1578
|
-
<
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1558
|
+
<template #bannerTitle>
|
|
1559
|
+
<div class="chart-title-container">
|
|
1560
|
+
<div class="logo-container">
|
|
1561
|
+
<div class="logo-box">
|
|
1562
|
+
<LazyImage
|
|
1563
|
+
:src="chart ? chart.icon : ''"
|
|
1564
|
+
class="logo"
|
|
1565
|
+
/>
|
|
1566
|
+
</div>
|
|
1567
|
+
</div>
|
|
1568
|
+
<div class="chart-title">
|
|
1569
|
+
<h1>
|
|
1570
|
+
<router-link
|
|
1571
|
+
v-if="chart"
|
|
1572
|
+
:to="chartLocation()"
|
|
1573
|
+
data-testid="chart-install-name-link"
|
|
1574
|
+
>
|
|
1575
|
+
{{ stepperName }}
|
|
1576
|
+
</router-link>
|
|
1577
|
+
<span v-else>
|
|
1578
|
+
{{ stepperName }}
|
|
1579
|
+
</span>: {{ t(`wizard.${action.tKey}`) }}
|
|
1580
|
+
</h1>
|
|
1581
|
+
<span
|
|
1582
|
+
v-if="stepperSubtext"
|
|
1583
|
+
class="subtext"
|
|
1584
|
+
>
|
|
1585
|
+
<i
|
|
1586
|
+
v-clean-tooltip="t('tableHeaders.version')"
|
|
1587
|
+
class="icon icon-version-alt"
|
|
1588
|
+
/>
|
|
1589
|
+
{{ stepperSubtext }}
|
|
1590
|
+
</span>
|
|
1582
1591
|
</div>
|
|
1583
|
-
<label
|
|
1584
|
-
v-if="windowsIncompatible"
|
|
1585
|
-
class="os-label"
|
|
1586
|
-
>
|
|
1587
|
-
{{ windowsIncompatible }}
|
|
1588
|
-
</label>
|
|
1589
1592
|
</div>
|
|
1590
1593
|
</template>
|
|
1591
1594
|
<template #basics>
|
|
@@ -1629,20 +1632,26 @@ export default {
|
|
|
1629
1632
|
v-if="showSelectVersionOrChart"
|
|
1630
1633
|
class="row mb-20"
|
|
1631
1634
|
>
|
|
1632
|
-
|
|
1633
|
-
|
|
1635
|
+
<!-- We have a chart for the app, let the user select a new version -->
|
|
1636
|
+
<div
|
|
1637
|
+
v-if="chart"
|
|
1638
|
+
class="col span-4"
|
|
1639
|
+
>
|
|
1634
1640
|
<LabeledSelect
|
|
1635
|
-
v-if="chart"
|
|
1636
1641
|
data-testid="chart-version-selector"
|
|
1637
1642
|
:label="t('catalog.install.version')"
|
|
1638
|
-
:value="
|
|
1643
|
+
:value="selectedVersionOption"
|
|
1639
1644
|
:options="filteredVersions"
|
|
1640
1645
|
:selectable="version => !version.disabled"
|
|
1641
1646
|
@update:value="selectVersion"
|
|
1642
1647
|
/>
|
|
1643
|
-
|
|
1648
|
+
</div>
|
|
1649
|
+
<!-- Can't find the chart for the app, let the user try to select one -->
|
|
1650
|
+
<div
|
|
1651
|
+
v-else
|
|
1652
|
+
class="col span-4"
|
|
1653
|
+
>
|
|
1644
1654
|
<LabeledSelect
|
|
1645
|
-
v-else
|
|
1646
1655
|
:label="t('catalog.install.chart')"
|
|
1647
1656
|
:value="chart"
|
|
1648
1657
|
:options="charts"
|
|
@@ -1791,7 +1800,7 @@ export default {
|
|
|
1791
1800
|
<LabeledSelect
|
|
1792
1801
|
v-if="chart"
|
|
1793
1802
|
:label="t('catalog.install.version')"
|
|
1794
|
-
:value="
|
|
1803
|
+
:value="selectedVersionOption"
|
|
1795
1804
|
:options="filteredVersions"
|
|
1796
1805
|
:selectable="version => !version.disabled"
|
|
1797
1806
|
@update:value="selectVersion"
|
|
@@ -2046,30 +2055,37 @@ export default {
|
|
|
2046
2055
|
:class="{ 'isPlainLayout': isPlainLayout}"
|
|
2047
2056
|
>
|
|
2048
2057
|
<div class="outer-container">
|
|
2049
|
-
<div class="header
|
|
2050
|
-
<div class="
|
|
2051
|
-
<div class="
|
|
2052
|
-
<div class="
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
class="logo"
|
|
2059
|
-
/>
|
|
2060
|
-
</div>
|
|
2061
|
-
</slot>
|
|
2062
|
-
<!-- Title with subtext -->
|
|
2063
|
-
<div class="subtitle">
|
|
2064
|
-
<h2 v-if="stepperName">
|
|
2065
|
-
{{ stepperName }}
|
|
2066
|
-
</h2>
|
|
2067
|
-
<span
|
|
2068
|
-
v-if="stepperSubtext"
|
|
2069
|
-
class="subtext"
|
|
2070
|
-
>{{ stepperSubtext }}</span>
|
|
2058
|
+
<div class="header mmt-6 mmb-6">
|
|
2059
|
+
<div class="top choice-banner">
|
|
2060
|
+
<div class="chart-title-container mmb-6">
|
|
2061
|
+
<div class="logo-container">
|
|
2062
|
+
<div class="logo-box">
|
|
2063
|
+
<LazyImage
|
|
2064
|
+
:src="chart ? chart.icon : ''"
|
|
2065
|
+
class="logo"
|
|
2066
|
+
/>
|
|
2071
2067
|
</div>
|
|
2072
2068
|
</div>
|
|
2069
|
+
<div class="chart-title">
|
|
2070
|
+
<h2 v-if="stepperName">
|
|
2071
|
+
<router-link
|
|
2072
|
+
:to="chartLocation()"
|
|
2073
|
+
data-testid="chart-install-name-link"
|
|
2074
|
+
>
|
|
2075
|
+
{{ stepperName }}
|
|
2076
|
+
</router-link>
|
|
2077
|
+
</h2>
|
|
2078
|
+
<span
|
|
2079
|
+
v-if="stepperSubtext"
|
|
2080
|
+
class="subtext"
|
|
2081
|
+
>
|
|
2082
|
+
<i
|
|
2083
|
+
v-clean-tooltip="t('tableHeaders.version')"
|
|
2084
|
+
class="icon icon-version-alt"
|
|
2085
|
+
/>
|
|
2086
|
+
{{ stepperSubtext }}
|
|
2087
|
+
</span>
|
|
2088
|
+
</div>
|
|
2073
2089
|
</div>
|
|
2074
2090
|
</div>
|
|
2075
2091
|
</div>
|
|
@@ -2100,12 +2116,16 @@ export default {
|
|
|
2100
2116
|
</template>
|
|
2101
2117
|
|
|
2102
2118
|
<style lang="scss" scoped>
|
|
2119
|
+
.chart-version-footnote {
|
|
2120
|
+
margin-top: 8px;
|
|
2121
|
+
color: var(--input-label);
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2103
2124
|
$title-height: 50px;
|
|
2104
2125
|
$padding: 5px;
|
|
2105
2126
|
$slideout-width: 35%;
|
|
2106
2127
|
|
|
2107
2128
|
.install-steps {
|
|
2108
|
-
padding-top: 0;
|
|
2109
2129
|
height: 0;
|
|
2110
2130
|
position: relative;
|
|
2111
2131
|
overflow: hidden;
|
|
@@ -2121,37 +2141,29 @@ export default {
|
|
|
2121
2141
|
}
|
|
2122
2142
|
}
|
|
2123
2143
|
|
|
2124
|
-
.
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
width: $title-height;
|
|
2129
|
-
background-color: white;
|
|
2130
|
-
border: $padding solid white;
|
|
2131
|
-
border-radius: calc( 3 * var(--border-radius));
|
|
2132
|
-
position: relative;
|
|
2133
|
-
}
|
|
2144
|
+
.logo-container {
|
|
2145
|
+
display: flex;
|
|
2146
|
+
flex-direction: column;
|
|
2147
|
+
align-items: center;
|
|
2134
2148
|
|
|
2135
|
-
.logo {
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
bottom: 0;
|
|
2144
|
-
left: 0;
|
|
2145
|
-
margin: auto;
|
|
2146
|
-
}
|
|
2149
|
+
.logo-box {
|
|
2150
|
+
width: 60px;
|
|
2151
|
+
height: 60px;
|
|
2152
|
+
display: flex;
|
|
2153
|
+
justify-content: center;
|
|
2154
|
+
align-items: center;
|
|
2155
|
+
background: #fff;
|
|
2156
|
+
border-radius: var(--border-radius);
|
|
2147
2157
|
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
padding-bottom: 15px;
|
|
2158
|
+
.logo {
|
|
2159
|
+
width: 48px;
|
|
2160
|
+
height: 48px;
|
|
2161
|
+
object-fit: contain;
|
|
2153
2162
|
}
|
|
2154
2163
|
}
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
.wizard {
|
|
2155
2167
|
|
|
2156
2168
|
.os-label {
|
|
2157
2169
|
position: absolute;
|
|
@@ -2300,38 +2312,43 @@ export default {
|
|
|
2300
2312
|
|
|
2301
2313
|
border-bottom: var(--header-border-size) solid var(--header-border);
|
|
2302
2314
|
|
|
2303
|
-
& > .title {
|
|
2315
|
+
& > .chart-title-container {
|
|
2304
2316
|
flex: 1;
|
|
2305
2317
|
min-height: 75px;
|
|
2306
2318
|
}
|
|
2307
2319
|
|
|
2308
2320
|
.choice-banner {
|
|
2309
2321
|
|
|
2310
|
-
flex-basis:
|
|
2322
|
+
flex-basis: 100%;
|
|
2311
2323
|
display: flex;
|
|
2312
2324
|
align-items: center;
|
|
2313
2325
|
|
|
2314
2326
|
&.top {
|
|
2315
2327
|
|
|
2316
|
-
H2 {
|
|
2328
|
+
H1, H2 {
|
|
2317
2329
|
margin: 0px;
|
|
2318
2330
|
}
|
|
2319
2331
|
|
|
2320
|
-
.title{
|
|
2332
|
+
.chart-title-container {
|
|
2321
2333
|
display: flex;
|
|
2322
|
-
align-items:
|
|
2334
|
+
align-items: flex-start;
|
|
2323
2335
|
justify-content: space-evenly;
|
|
2324
|
-
|
|
2325
|
-
& > .subtitle {
|
|
2326
|
-
margin: 0 20px;
|
|
2327
|
-
}
|
|
2336
|
+
gap: 24px;
|
|
2328
2337
|
}
|
|
2329
2338
|
|
|
2330
|
-
.
|
|
2339
|
+
.chart-title {
|
|
2331
2340
|
display: flex;
|
|
2332
2341
|
flex-direction: column;
|
|
2333
2342
|
& .subtext {
|
|
2343
|
+
display: flex;
|
|
2344
|
+
align-items: center;
|
|
2345
|
+
gap: 8px;
|
|
2334
2346
|
color: var(--input-label);
|
|
2347
|
+
margin-top: 8px;
|
|
2348
|
+
|
|
2349
|
+
.icon-version-alt {
|
|
2350
|
+
font-size: 19px;
|
|
2351
|
+
}
|
|
2335
2352
|
}
|
|
2336
2353
|
}
|
|
2337
2354
|
|
|
@@ -2348,17 +2365,6 @@ export default {
|
|
|
2348
2365
|
}
|
|
2349
2366
|
}
|
|
2350
2367
|
|
|
2351
|
-
& .round-image {
|
|
2352
|
-
min-width: 50px;
|
|
2353
|
-
height: 50px;
|
|
2354
|
-
margin: 10px 10px 10px 0;
|
|
2355
|
-
border-radius: 50%;
|
|
2356
|
-
overflow: hidden;
|
|
2357
|
-
.logo {
|
|
2358
|
-
min-width: 50px;
|
|
2359
|
-
height: 50px;
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
2368
|
}
|
|
2363
2369
|
}
|
|
2364
2370
|
|
|
@@ -7,6 +7,7 @@ import Loading from '@shell/components/Loading';
|
|
|
7
7
|
import { SUBTYPE_MAPPING, CREATE_VERBS } from '@shell/models/management.cattle.io.roletemplate';
|
|
8
8
|
import { NAME } from '@shell/config/product/auth';
|
|
9
9
|
import { BLANK_CLUSTER } from '@shell/store/store-types.js';
|
|
10
|
+
import { RcButton } from '@components/RcButton';
|
|
10
11
|
|
|
11
12
|
const GLOBAL = SUBTYPE_MAPPING.GLOBAL.key;
|
|
12
13
|
const CLUSTER = SUBTYPE_MAPPING.CLUSTER.key;
|
|
@@ -31,7 +32,7 @@ export default {
|
|
|
31
32
|
name: 'Roles',
|
|
32
33
|
|
|
33
34
|
components: {
|
|
34
|
-
Tab, Tabbed, ResourceTable, Loading
|
|
35
|
+
Tab, Tabbed, ResourceTable, Loading, RcButton
|
|
35
36
|
},
|
|
36
37
|
|
|
37
38
|
async fetch() {
|
|
@@ -162,13 +163,13 @@ export default {
|
|
|
162
163
|
</div>
|
|
163
164
|
<div class="actions-container">
|
|
164
165
|
<div class="actions">
|
|
165
|
-
<
|
|
166
|
+
<rc-button
|
|
166
167
|
v-if="canCreate"
|
|
168
|
+
size="large"
|
|
167
169
|
:to="createLocation"
|
|
168
|
-
class="btn role-primary"
|
|
169
170
|
>
|
|
170
171
|
{{ createLabel }}
|
|
171
|
-
</
|
|
172
|
+
</rc-button>
|
|
172
173
|
</div>
|
|
173
174
|
</div>
|
|
174
175
|
</header>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import WorkloadNamespaceCard from './WorkloadNamespaceCard.vue';
|
|
3
|
+
import type { WorkloadDashboardByNamespaceCard, WorkloadDashboardNamespaceNavigateFn, WorkloadDashboardFilterByNamespaceFn } from './types';
|
|
4
|
+
|
|
5
|
+
defineProps<{
|
|
6
|
+
cards: WorkloadDashboardByNamespaceCard[];
|
|
7
|
+
navigateToNamespace: WorkloadDashboardNamespaceNavigateFn;
|
|
8
|
+
filterByNamespace: WorkloadDashboardFilterByNamespaceFn;
|
|
9
|
+
}>();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="card-grid">
|
|
14
|
+
<WorkloadNamespaceCard
|
|
15
|
+
v-for="card in cards"
|
|
16
|
+
:key="card.title"
|
|
17
|
+
:title="card.title"
|
|
18
|
+
:rows="card.rows"
|
|
19
|
+
:navigate-to-namespace="navigateToNamespace"
|
|
20
|
+
:filter-by-namespace="filterByNamespace"
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<style lang="scss" scoped>
|
|
26
|
+
.card-grid {
|
|
27
|
+
display: grid;
|
|
28
|
+
grid-template-columns: repeat(3, 1fr);
|
|
29
|
+
gap: 15px;
|
|
30
|
+
}
|
|
31
|
+
</style>
|