@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.3
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/translations/en-us.yaml +22 -5
- package/chart/monitoring/index.vue +10 -1
- package/components/ActionDropdownShell.vue +2 -1
- package/components/CruResourceFooter.vue +9 -5
- package/components/ExplorerProjectsNamespaces.vue +1 -1
- package/components/InstallHelmCharts.vue +2 -2
- package/components/LandingPagePreference.vue +14 -5
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
- 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/ResourceList/Masthead.vue +12 -8
- package/components/SelectIconGrid.vue +0 -10
- 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/Wizard.vue +14 -13
- package/components/fleet/FleetBundles.vue +100 -12
- package/components/fleet/FleetClusterTargets/index.vue +37 -15
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
- package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
- package/components/form/LabeledSelect.vue +20 -3
- package/components/form/NameNsDescription.vue +11 -0
- package/components/form/Security.vue +6 -2
- package/components/form/WorkloadPorts.vue +2 -7
- 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/MachineSummaryGraph.vue +1 -1
- package/components/formatter/PodsUsage.vue +2 -2
- package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
- package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
- package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
- package/components/nav/NamespaceFilter.vue +2 -2
- package/components/nav/TopLevelMenu.helper.ts +15 -3
- package/components/nav/TopLevelMenu.vue +16 -5
- package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
- package/components/templates/home.vue +18 -0
- package/components/templates/plain.vue +18 -0
- package/components/templates/standalone.vue +17 -0
- package/composables/useFormValidation.ts +93 -0
- package/composables/useVeeValidateField.test.ts +159 -0
- package/composables/useVeeValidateField.ts +67 -0
- package/config/pagination-table-headers.js +18 -1
- package/config/product/manager.js +82 -21
- package/config/router/routes.js +6 -0
- package/config/table-headers.js +20 -1
- package/config/types.js +2 -1
- package/core/__tests__/plugin-products.test.ts +904 -20
- package/core/plugin-products-base.ts +107 -7
- package/core/plugin-products.ts +4 -0
- package/core/plugin-types.ts +111 -1
- package/core/plugin.ts +15 -7
- package/core/productDebugger.js +9 -4
- package/core/types-provisioning.ts +43 -30
- package/core/types.ts +57 -20
- package/detail/__tests__/pod.test.ts +41 -0
- package/detail/harvesterhci.io.management.cluster.vue +6 -2
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -10
- package/edit/auth/__tests__/azuread.test.ts +217 -34
- package/edit/auth/azuread.vue +122 -14
- package/edit/auth/oidc.vue +2 -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 +8 -4
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -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/provisioning.cattle.io.cluster.vue +262 -180
- package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
- package/mixins/__tests__/chart.test.ts +112 -0
- package/mixins/brand.js +2 -1
- package/mixins/chart.js +12 -8
- package/mixins/resource-fetch-api-pagination.js +41 -5
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
- package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
- package/models/__tests__/management.cattle.io.node.ts +6 -5
- package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
- package/models/base-cluster.x-k8s.io.js +26 -0
- 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 +130 -2
- package/models/ext.cattle.io.kubeconfig.ts +4 -7
- package/models/fleet-application.js +3 -1
- package/models/management.cattle.io.cluster.js +417 -40
- package/models/management.cattle.io.node.js +6 -4
- package/models/management.cattle.io.nodepool.js +1 -1
- package/models/networking.k8s.io.ingress.js +12 -4
- package/models/provisioning.cattle.io.cluster.js +47 -330
- package/models/rke.cattle.io.etcdsnapshot.js +1 -2
- package/package.json +11 -29
- package/pages/__tests__/readme.test.ts +49 -0
- package/pages/auth/setup.vue +2 -3
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
- package/pages/c/_cluster/apps/charts/chart.vue +60 -8
- package/pages/c/_cluster/apps/charts/install.vue +10 -7
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
- package/pages/c/_cluster/explorer/index.vue +5 -49
- 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 +719 -2
- package/pages/c/_cluster/uiplugins/index.vue +203 -197
- package/pages/diagnostic.vue +13 -17
- package/pages/fail-whale.vue +18 -0
- package/pages/home.vue +77 -260
- package/pages/readme.vue +88 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
- package/plugins/dashboard-store/actions.js +40 -18
- package/plugins/dashboard-store/resource-class.js +5 -2
- package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
- package/plugins/steve/steve-pagination-utils.ts +11 -3
- package/plugins/steve/subscribe.js +35 -5
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
- package/rancher-components/RcButton/RcButton.test.ts +37 -1
- package/rancher-components/RcButton/RcButton.vue +38 -8
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
- package/store/__tests__/catalog.test.ts +115 -1
- 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 +27 -3
- package/store/digitalocean.js +20 -38
- package/store/index.js +2 -0
- package/store/linode.js +25 -40
- package/store/pnap.js +1 -0
- package/store/type-map.js +111 -29
- package/tsconfig.paths.json +8 -8
- 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 +102 -2
- 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__/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__/duration.test.ts +140 -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__/namespace-filter.test.ts +109 -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__/poller-sequential.test.ts +177 -0
- package/utils/__tests__/poller.test.ts +170 -0
- package/utils/__tests__/promise.test.ts +346 -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__/units.test.ts +417 -0
- package/utils/__tests__/versions.test.ts +128 -0
- package/utils/__tests__/xccdf.test.ts +391 -0
- package/utils/chart.js +36 -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/pagination-utils.ts +2 -1
- 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__/cron-schedule.test.ts +79 -0
- package/utils/validators/__tests__/index.test.ts +481 -0
- package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
- package/utils/validators/__tests__/misc-validators.test.ts +246 -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 +418 -0
- 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
|
@@ -35,6 +35,7 @@ const setBulkActionOfInterest = (act: HiddenAction | null, event: 'mouseover' |
|
|
|
35
35
|
>
|
|
36
36
|
<rc-dropdown-trigger
|
|
37
37
|
class="bulk-actions-dropdown"
|
|
38
|
+
size="large"
|
|
38
39
|
:disabled="disabled"
|
|
39
40
|
>
|
|
40
41
|
<template #before>
|
|
@@ -42,7 +43,7 @@ const setBulkActionOfInterest = (act: HiddenAction | null, event: 'mouseover' |
|
|
|
42
43
|
</template>
|
|
43
44
|
<span>{{ t('sortableTable.bulkActions.collapsed.label') }}</span>
|
|
44
45
|
<template #after>
|
|
45
|
-
<i class="
|
|
46
|
+
<i class="icon icon-chevron-down" />
|
|
46
47
|
</template>
|
|
47
48
|
</rc-dropdown-trigger>
|
|
48
49
|
<template #dropdownCollection>
|
|
@@ -3,13 +3,16 @@ import { mapGetters } from 'vuex';
|
|
|
3
3
|
|
|
4
4
|
import AsyncButton from '@shell/components/AsyncButton';
|
|
5
5
|
import ResourceCancelModal from '@shell/components/ResourceCancelModal';
|
|
6
|
+
import { RcButton } from '@components/RcButton';
|
|
6
7
|
import { _VIEW } from '@shell/config/query-params';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
emits: ['cancel-confirmed', 'finish'],
|
|
10
11
|
|
|
11
|
-
components: {
|
|
12
|
-
|
|
12
|
+
components: {
|
|
13
|
+
AsyncButton, RcButton, ResourceCancelModal
|
|
14
|
+
},
|
|
15
|
+
props: {
|
|
13
16
|
mode: {
|
|
14
17
|
type: String,
|
|
15
18
|
default: 'create',
|
|
@@ -84,16 +87,17 @@ export default {
|
|
|
84
87
|
<div class="cru-resource-footer">
|
|
85
88
|
<slot name="footer-prefix" />
|
|
86
89
|
<slot name="cancel">
|
|
87
|
-
<
|
|
90
|
+
<RcButton
|
|
88
91
|
v-if="!isView && showCancel"
|
|
89
92
|
id="cru-cancel"
|
|
90
93
|
:data-testid="componentTestid + '-cancel'"
|
|
91
94
|
type="button"
|
|
92
|
-
|
|
95
|
+
variant="secondary"
|
|
96
|
+
size="large"
|
|
93
97
|
@click="confirmCancelRequired ? checkCancel(true) : $emit('cancel-confirmed', true)"
|
|
94
98
|
>
|
|
95
99
|
<t k="generic.cancel" />
|
|
96
|
-
</
|
|
100
|
+
</RcButton>
|
|
97
101
|
</slot>
|
|
98
102
|
<slot :checkCancel="checkCancel">
|
|
99
103
|
<AsyncButton
|
|
@@ -295,7 +295,7 @@ export default {
|
|
|
295
295
|
return this.$store.getters['i18n/t']('resourceTable.groupLabel.notInAProject');
|
|
296
296
|
},
|
|
297
297
|
showCreateNsButton() {
|
|
298
|
-
return this.groupPreference !== 'namespace';
|
|
298
|
+
return this.groupPreference !== 'namespace' && this.isNamespaceCreatable;
|
|
299
299
|
},
|
|
300
300
|
projectGroupBy() {
|
|
301
301
|
return this.groupPreference === 'none' ? null : 'groupById';
|
|
@@ -248,7 +248,7 @@ export default {
|
|
|
248
248
|
|
|
249
249
|
};
|
|
250
250
|
|
|
251
|
-
this.installCmd.namespace = this.targetNamespace || this.chart?.targetNamespace || 'default';
|
|
251
|
+
this.installCmd.namespace = this.targetNamespace || this.versionInfo?.chart?.annotations?.[CATALOG_ANNOTATIONS.NAMESPACE] || this.chart?.targetNamespace || 'default';
|
|
252
252
|
}
|
|
253
253
|
},
|
|
254
254
|
|
|
@@ -360,7 +360,7 @@ export default {
|
|
|
360
360
|
this.canInstallChart = false;
|
|
361
361
|
} else {
|
|
362
362
|
try {
|
|
363
|
-
const app = await this.$store.dispatch(`${ this.store }/find`, { type: CATALOG.APP, id: `${ this.targetNamespace || this.chart?.targetNamespace || 'default' }/${ this.chartName }` });
|
|
363
|
+
const app = await this.$store.dispatch(`${ this.store }/find`, { type: CATALOG.APP, id: `${ this.targetNamespace || this.versionInfo?.chart?.annotations?.[CATALOG_ANNOTATIONS.NAMESPACE] || this.chart?.targetNamespace || 'default' }/${ this.chartName }` });
|
|
364
364
|
|
|
365
365
|
if (app) {
|
|
366
366
|
this.installedVersion = app?.spec?.chart?.metadata?.appVersion;
|
|
@@ -14,10 +14,6 @@ export default {
|
|
|
14
14
|
Select,
|
|
15
15
|
},
|
|
16
16
|
|
|
17
|
-
async fetch() {
|
|
18
|
-
this.clusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
|
|
19
|
-
},
|
|
20
|
-
|
|
21
17
|
data() {
|
|
22
18
|
// Store the route as it was on page load (before the user may have changed it)
|
|
23
19
|
const customRoute = this.$store.getters['prefs/get'](AFTER_LOGIN_ROUTE);
|
|
@@ -90,13 +86,25 @@ export default {
|
|
|
90
86
|
},
|
|
91
87
|
|
|
92
88
|
methods: {
|
|
93
|
-
updateLoginRoute(neu) {
|
|
89
|
+
async updateLoginRoute(neu) {
|
|
94
90
|
if (neu) {
|
|
95
91
|
this.afterLoginRoute = neu;
|
|
96
92
|
} else {
|
|
93
|
+
this.clusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
|
|
97
94
|
this.afterLoginRoute = this.routeFromDropdown?.value || this.routeDropdownOptions[0]?.value;
|
|
98
95
|
}
|
|
99
96
|
},
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
watch: {
|
|
100
|
+
afterLoginRoute: {
|
|
101
|
+
async handler(neu) {
|
|
102
|
+
if (typeof neu === 'object') {
|
|
103
|
+
this.clusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
immediate: true
|
|
107
|
+
},
|
|
100
108
|
}
|
|
101
109
|
};
|
|
102
110
|
</script>
|
|
@@ -129,6 +137,7 @@ export default {
|
|
|
129
137
|
/>
|
|
130
138
|
<Select
|
|
131
139
|
v-model:value="routeFromDropdown"
|
|
140
|
+
:loading="clusters.length < 1"
|
|
132
141
|
:aria-label="t('landing.landingPrefs.ariaLabelTakeMeToCluster')"
|
|
133
142
|
:searchable="true"
|
|
134
143
|
:disabled="afterLoginRoute === 'home' || afterLoginRoute === 'last-visited'"
|
|
@@ -103,12 +103,26 @@ const getRowValueId = (row:Row): string => `value-${ row.label }:${ row.value }`
|
|
|
103
103
|
flex-direction: column;
|
|
104
104
|
|
|
105
105
|
.row {
|
|
106
|
+
gap: 8px;
|
|
107
|
+
|
|
108
|
+
// Hide clearfix pseudo-elements inherited from the global .row class
|
|
109
|
+
&::before, &::after {
|
|
110
|
+
display: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
106
113
|
&:not(:last-of-type) {
|
|
107
114
|
margin-bottom: 8px;
|
|
108
115
|
}
|
|
109
116
|
|
|
110
117
|
.full-custom-value {
|
|
111
118
|
flex: 1;
|
|
119
|
+
min-width: 0;
|
|
120
|
+
|
|
121
|
+
// Override inline-block on .popover-card-target so it respects the
|
|
122
|
+
// parent's width constraint instead of sizing to its content
|
|
123
|
+
:deep(.popover-card-target) {
|
|
124
|
+
width: 100%;
|
|
125
|
+
}
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
.value {
|
|
@@ -128,7 +142,7 @@ const getRowValueId = (row:Row): string => `value-${ row.label }:${ row.value }`
|
|
|
128
142
|
|
|
129
143
|
.label {
|
|
130
144
|
width: 30%;
|
|
131
|
-
min-width:
|
|
145
|
+
min-width: min-content;
|
|
132
146
|
}
|
|
133
147
|
|
|
134
148
|
.status {
|
|
@@ -82,6 +82,12 @@ const showBothEmpty = computed(() => labels.length === 0 && annotations.length =
|
|
|
82
82
|
|
|
83
83
|
<style lang="scss" scoped>
|
|
84
84
|
.metadata {
|
|
85
|
+
.identifying-info {
|
|
86
|
+
// Allow the grid cell to shrink below its content size without
|
|
87
|
+
// using overflow:hidden, which would clip the namespace popover
|
|
88
|
+
min-width: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
.labels-and-annotations-empty {
|
|
86
92
|
grid-column: span 2;
|
|
87
93
|
}
|
|
@@ -115,11 +115,22 @@ const actionInvoked = () => {
|
|
|
115
115
|
|
|
116
116
|
.display {
|
|
117
117
|
display: inline-flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
max-width: 100%;
|
|
120
|
+
|
|
121
|
+
// Truncate the link text instead of wrapping to a second line
|
|
122
|
+
a {
|
|
123
|
+
overflow: hidden;
|
|
124
|
+
text-overflow: ellipsis;
|
|
125
|
+
white-space: nowrap;
|
|
126
|
+
min-width: 0;
|
|
127
|
+
}
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
.rc-status-indicator {
|
|
131
|
+
// Keep the status dot from collapsing when the link text is long
|
|
132
|
+
flex-shrink: 0;
|
|
121
133
|
margin-right: 12px;
|
|
122
|
-
margin-top: 4px;
|
|
123
134
|
height: initial;
|
|
124
135
|
line-height: initial;
|
|
125
136
|
}
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
<style lang="scss" scoped>
|
|
8
8
|
.spaced-row {
|
|
9
9
|
display: grid;
|
|
10
|
-
grid-template-columns: repeat(3, minmax(0, 1fr))
|
|
10
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
11
11
|
grid-auto-flow: dense;
|
|
12
12
|
grid-gap: 24px;
|
|
13
13
|
justify-content: space-evenly;
|
|
14
|
+
// Match the title bar floor so sections scroll together
|
|
15
|
+
min-width: $resource-detail-min-width;
|
|
14
16
|
}
|
|
15
17
|
</style>
|
|
@@ -159,23 +159,20 @@ const showAdditionalActionButtons = computed(() => isArray(additionalActions));
|
|
|
159
159
|
|
|
160
160
|
<style lang="scss" scoped>
|
|
161
161
|
.title-bar {
|
|
162
|
-
min-width:
|
|
162
|
+
min-width: $resource-detail-min-width;
|
|
163
163
|
|
|
164
164
|
.badge-state {
|
|
165
165
|
font-size: 16px;
|
|
166
166
|
margin-left: 12px;
|
|
167
167
|
position: relative;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
.icon-document {
|
|
171
|
-
width: 15px;
|
|
172
|
-
font-size: 16px;
|
|
173
|
-
margin-right: 10px;
|
|
168
|
+
flex: 0 0 auto;
|
|
174
169
|
}
|
|
175
170
|
|
|
176
171
|
.actions {
|
|
177
172
|
display: flex;
|
|
178
173
|
align-items: center;
|
|
174
|
+
flex: 0 0 auto;
|
|
175
|
+
margin-left: 16px;
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
.show-configuration, &:deep() .actions > button {
|
|
@@ -198,15 +195,17 @@ const showAdditionalActionButtons = computed(() => isArray(additionalActions));
|
|
|
198
195
|
max-width: 60%;
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
//
|
|
198
|
+
// Title takes the remaining row space; min-width: 0 lets its children
|
|
199
|
+
// (resource-name) shrink so the action buttons stay visible on narrow viewports.
|
|
202
200
|
.title {
|
|
203
|
-
|
|
201
|
+
flex: 1 1 auto;
|
|
202
|
+
min-width: 0;
|
|
204
203
|
}
|
|
205
204
|
|
|
206
|
-
// We want the resource name to be what collaspes wh
|
|
207
205
|
.resource-name {
|
|
208
206
|
display: inline-block;
|
|
209
|
-
flex: 1;
|
|
207
|
+
flex: 0 1 auto;
|
|
208
|
+
min-width: 0;
|
|
210
209
|
white-space: nowrap;
|
|
211
210
|
overflow-x: hidden;
|
|
212
211
|
overflow-y: clip;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
3
|
import Favorite from '@shell/components/nav/Favorite';
|
|
4
4
|
import TypeDescription from '@shell/components/TypeDescription';
|
|
5
|
+
import { RcButton } from '@components/RcButton';
|
|
5
6
|
import { get } from '@shell/utils/object';
|
|
6
7
|
import { AS, _YAML } from '@shell/config/query-params';
|
|
7
8
|
import ResourceLoadingIndicator from './ResourceLoadingIndicator';
|
|
@@ -16,6 +17,7 @@ export default {
|
|
|
16
17
|
|
|
17
18
|
components: {
|
|
18
19
|
Favorite,
|
|
20
|
+
RcButton,
|
|
19
21
|
TypeDescription,
|
|
20
22
|
ResourceLoadingIndicator,
|
|
21
23
|
TabTitle
|
|
@@ -221,22 +223,24 @@ export default {
|
|
|
221
223
|
<slot name="extraActions" />
|
|
222
224
|
|
|
223
225
|
<slot name="createButton">
|
|
224
|
-
<
|
|
226
|
+
<RcButton
|
|
225
227
|
v-if="hasEditComponent && _isCreatable"
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
variant="primary"
|
|
229
|
+
size="large"
|
|
228
230
|
:data-testid="componentTestid+'-create'"
|
|
231
|
+
:to="_createLocation"
|
|
229
232
|
>
|
|
230
233
|
{{ _createButtonlabel }}
|
|
231
|
-
</
|
|
232
|
-
<
|
|
234
|
+
</RcButton>
|
|
235
|
+
<RcButton
|
|
233
236
|
v-else-if="_isYamlCreatable"
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
variant="primary"
|
|
238
|
+
size="large"
|
|
236
239
|
:data-testid="componentTestid+'-create-yaml'"
|
|
240
|
+
:to="_yamlCreateLocation"
|
|
237
241
|
>
|
|
238
242
|
{{ t("resourceList.head.createFromYaml") }}
|
|
239
|
-
</
|
|
243
|
+
</RcButton>
|
|
240
244
|
</slot>
|
|
241
245
|
</div>
|
|
242
246
|
</slot>
|
|
@@ -131,16 +131,6 @@ export default {
|
|
|
131
131
|
class="side-label"
|
|
132
132
|
:class="{'indicator': true }"
|
|
133
133
|
/>
|
|
134
|
-
<div v-if="r.deploysOnWindows">
|
|
135
|
-
<label class="deploys-os-label">
|
|
136
|
-
{{ t('catalog.charts.deploysOnWindows') }}
|
|
137
|
-
</label>
|
|
138
|
-
</div>
|
|
139
|
-
<div v-if="r.windowsIncompatible">
|
|
140
|
-
<label class="os-incompatible-label">
|
|
141
|
-
{{ t('catalog.charts.windowsIncompatible') }}
|
|
142
|
-
</label>
|
|
143
|
-
</div>
|
|
144
134
|
<div
|
|
145
135
|
v-if="get(r, sideLabelField)"
|
|
146
136
|
class="side-label"
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import sorting from '@shell/components/SortableTable/sorting';
|
|
2
|
+
|
|
3
|
+
const { arrangedRows } = sorting.computed;
|
|
4
|
+
|
|
5
|
+
describe('sorting mixin', () => {
|
|
6
|
+
describe('arrangedRows', () => {
|
|
7
|
+
function createContext({
|
|
8
|
+
rows = [] as any[],
|
|
9
|
+
sortFields = ['id'],
|
|
10
|
+
descending = false,
|
|
11
|
+
sortGeneration = undefined as string | undefined,
|
|
12
|
+
sortGenerationFn = (() => 'gen1') as (() => string) | undefined,
|
|
13
|
+
externalPaginationEnabled = false,
|
|
14
|
+
cacheKey = null as string | null,
|
|
15
|
+
cachedRows = null as any[] | null,
|
|
16
|
+
cachedRowsRef = null as any[] | null,
|
|
17
|
+
} = {}) {
|
|
18
|
+
return {
|
|
19
|
+
rows,
|
|
20
|
+
sortFields,
|
|
21
|
+
descending,
|
|
22
|
+
sortGeneration,
|
|
23
|
+
sortGenerationFn,
|
|
24
|
+
externalPaginationEnabled,
|
|
25
|
+
cacheKey,
|
|
26
|
+
cachedRows,
|
|
27
|
+
cachedRowsRef,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
it('should return undefined when externalPaginationEnabled is true', () => {
|
|
32
|
+
const ctx = createContext({ externalPaginationEnabled: true });
|
|
33
|
+
|
|
34
|
+
expect(arrangedRows.call(ctx)).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should sort rows by the given sort fields', () => {
|
|
38
|
+
const rows = [{ id: 'b' }, { id: 'a' }, { id: 'c' }];
|
|
39
|
+
const ctx = createContext({ rows, sortGenerationFn: undefined });
|
|
40
|
+
|
|
41
|
+
const result = arrangedRows.call(ctx);
|
|
42
|
+
|
|
43
|
+
expect(result.map((r: any) => r.id)).toStrictEqual(['a', 'b', 'c']);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should cache results when sortGenerationFn is provided', () => {
|
|
47
|
+
const rows = [{ id: 'b' }, { id: 'a' }];
|
|
48
|
+
const ctx = createContext({ rows });
|
|
49
|
+
|
|
50
|
+
const result1 = arrangedRows.call(ctx);
|
|
51
|
+
|
|
52
|
+
expect(ctx.cacheKey).not.toBeNull();
|
|
53
|
+
expect(ctx.cachedRows).toStrictEqual(result1);
|
|
54
|
+
|
|
55
|
+
const result2 = arrangedRows.call(ctx);
|
|
56
|
+
|
|
57
|
+
expect(result2).toBe(ctx.cachedRows);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should invalidate cache when rows change to different items with the same count', () => {
|
|
61
|
+
const rowsA = [{ id: 'alpha' }];
|
|
62
|
+
const rowsB = [{ id: 'beta' }];
|
|
63
|
+
const ctx = createContext({ rows: rowsA });
|
|
64
|
+
|
|
65
|
+
const resultA = arrangedRows.call(ctx);
|
|
66
|
+
|
|
67
|
+
expect(resultA.map((r: any) => r.id)).toStrictEqual(['alpha']);
|
|
68
|
+
|
|
69
|
+
ctx.rows = rowsB;
|
|
70
|
+
const resultB = arrangedRows.call(ctx);
|
|
71
|
+
|
|
72
|
+
expect(resultB.map((r: any) => r.id)).toStrictEqual(['beta']);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should return cached rows when same rows are passed again', () => {
|
|
76
|
+
const rows = [{ id: 'x' }, { id: 'y' }];
|
|
77
|
+
const ctx = createContext({ rows });
|
|
78
|
+
|
|
79
|
+
arrangedRows.call(ctx);
|
|
80
|
+
const cached = ctx.cachedRows;
|
|
81
|
+
|
|
82
|
+
const result = arrangedRows.call(ctx);
|
|
83
|
+
|
|
84
|
+
expect(result).toBe(cached);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should invalidate cache when descending changes', () => {
|
|
88
|
+
const rows = [{ id: 'a' }, { id: 'b' }];
|
|
89
|
+
const ctx = createContext({ rows });
|
|
90
|
+
|
|
91
|
+
arrangedRows.call(ctx);
|
|
92
|
+
|
|
93
|
+
ctx.descending = true;
|
|
94
|
+
const result = arrangedRows.call(ctx);
|
|
95
|
+
|
|
96
|
+
expect(result.map((r: any) => r.id)).toStrictEqual(['b', 'a']);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should not cache when there is no sortGenerationFn or sortGeneration', () => {
|
|
100
|
+
const rows = [{ id: 'a' }];
|
|
101
|
+
const ctx = createContext({ rows });
|
|
102
|
+
|
|
103
|
+
ctx.sortGenerationFn = undefined;
|
|
104
|
+
ctx.sortGeneration = undefined;
|
|
105
|
+
|
|
106
|
+
arrangedRows.call(ctx);
|
|
107
|
+
|
|
108
|
+
expect(ctx.cacheKey).toBeNull();
|
|
109
|
+
expect(ctx.cachedRows).toBeNull();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should use sortGeneration over sortGenerationFn when provided', () => {
|
|
113
|
+
const rows = [{ id: 'a' }];
|
|
114
|
+
const ctx = createContext({
|
|
115
|
+
rows,
|
|
116
|
+
sortGeneration: 'custom-gen',
|
|
117
|
+
sortGenerationFn: () => 'fn-gen',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
arrangedRows.call(ctx);
|
|
121
|
+
|
|
122
|
+
expect(ctx.cacheKey).toContain('custom-gen');
|
|
123
|
+
expect(ctx.cacheKey).not.toContain('fn-gen');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -26,6 +26,7 @@ import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
|
|
|
26
26
|
import ActionMenu from '@shell/components/ActionMenuShell.vue';
|
|
27
27
|
import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
|
|
28
28
|
import ActionDropdownShell from '@shell/components/ActionDropdownShell.vue';
|
|
29
|
+
import { RcButton } from '@components/RcButton';
|
|
29
30
|
import { useTabCountUpdater } from '@shell/components/form/ResourceTabs/composable';
|
|
30
31
|
|
|
31
32
|
// Uncomment for table performance debugging
|
|
@@ -65,6 +66,7 @@ export default {
|
|
|
65
66
|
ButtonMultiAction,
|
|
66
67
|
ActionMenu,
|
|
67
68
|
ActionDropdownShell,
|
|
69
|
+
RcButton,
|
|
68
70
|
},
|
|
69
71
|
|
|
70
72
|
mixins: [
|
|
@@ -1116,17 +1118,17 @@ export default {
|
|
|
1116
1118
|
>
|
|
1117
1119
|
<slot name="header-left">
|
|
1118
1120
|
<template v-if="tableActions">
|
|
1119
|
-
<
|
|
1121
|
+
<RcButton
|
|
1120
1122
|
v-for="(act) in availableActions"
|
|
1121
1123
|
:id="act.action"
|
|
1122
1124
|
:key="act.action"
|
|
1123
1125
|
v-clean-tooltip="actionTooltip"
|
|
1124
1126
|
type="button"
|
|
1125
|
-
|
|
1127
|
+
variant="primary"
|
|
1128
|
+
size="large"
|
|
1126
1129
|
:class="{[bulkActionClass]:true}"
|
|
1127
1130
|
:disabled="!act.enabled"
|
|
1128
1131
|
:data-testid="componentTestid + '-' + act.action"
|
|
1129
|
-
role="button"
|
|
1130
1132
|
:aria-label="act.label"
|
|
1131
1133
|
@click="applyTableAction(act, null, $event)"
|
|
1132
1134
|
@keydown.enter.stop
|
|
@@ -1138,7 +1140,7 @@ export default {
|
|
|
1138
1140
|
:class="act.icon"
|
|
1139
1141
|
/>
|
|
1140
1142
|
<span v-clean-html="act.label" />
|
|
1141
|
-
</
|
|
1143
|
+
</RcButton>
|
|
1142
1144
|
<template v-if="featureDropdownMenu">
|
|
1143
1145
|
<ActionDropdownShell
|
|
1144
1146
|
:disabled="!selectedRows.length"
|
|
@@ -2154,11 +2156,6 @@ export default {
|
|
|
2154
2156
|
}
|
|
2155
2157
|
}
|
|
2156
2158
|
|
|
2157
|
-
.bulk-action {
|
|
2158
|
-
.icon {
|
|
2159
|
-
vertical-align: -10%;
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
2159
|
}
|
|
2163
2160
|
|
|
2164
2161
|
.middle {
|
|
@@ -626,27 +626,45 @@ function _execute(resources, action, args, opts = {}, ctx) {
|
|
|
626
626
|
return action.invoke.apply(ctx, [actionOpts, resources || [], args]);
|
|
627
627
|
}
|
|
628
628
|
|
|
629
|
+
/**
|
|
630
|
+
* for the given resource find it's action matching the target action. if that target action has an alt resource return it
|
|
631
|
+
*/
|
|
632
|
+
const findResourceFromAction = (r) => {
|
|
633
|
+
const actualAction = r.availableActions.find((aa) => aa.action === action.action);
|
|
634
|
+
|
|
635
|
+
return actualAction?.altResource || r;
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
// if there there are multiple resources and a bulk action, use it and pass in the resources
|
|
639
|
+
// for example cluster management cluster list Download KubeConfig
|
|
629
640
|
if ( resources.length > 1 && action.bulkAction && !opts.alt ) {
|
|
630
|
-
const
|
|
641
|
+
const applyResource = findResourceFromAction(resources[0]);
|
|
642
|
+
const fn = applyResource[action.bulkAction];
|
|
631
643
|
|
|
632
644
|
if ( fn ) {
|
|
633
|
-
|
|
645
|
+
const applyResources = resources.map(findResourceFromAction);
|
|
646
|
+
|
|
647
|
+
return fn.call(applyResource, applyResources, ...args);
|
|
634
648
|
}
|
|
635
649
|
}
|
|
636
650
|
|
|
637
651
|
const promises = [];
|
|
638
652
|
|
|
653
|
+
// if there is a single resource or no bulk action, for each resource execute it's action
|
|
654
|
+
// for example delete when only one row is selected
|
|
639
655
|
for ( const resource of resources ) {
|
|
640
656
|
let fn;
|
|
641
657
|
|
|
658
|
+
const applyResource = findResourceFromAction(resource);
|
|
659
|
+
|
|
642
660
|
if (opts.alt && action.altAction) {
|
|
643
|
-
fn =
|
|
661
|
+
fn = applyResource[action.altAction];
|
|
644
662
|
} else {
|
|
645
|
-
fn =
|
|
663
|
+
fn = applyResource[action.action];
|
|
646
664
|
}
|
|
647
665
|
|
|
648
666
|
if ( fn ) {
|
|
649
|
-
promises.push(fn.apply(
|
|
667
|
+
promises.push(fn.apply(applyResource, args));
|
|
650
668
|
}
|
|
651
669
|
}
|
|
652
670
|
|
|
@@ -50,7 +50,8 @@ export default {
|
|
|
50
50
|
|
|
51
51
|
if ( sortGenerationKey) {
|
|
52
52
|
key = `${ sortGenerationKey }/${ this.rows.length }/${ this.descending }/${ this.sortFields.join(',') }`;
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
if ( this.cacheKey === key && this.cachedRowsRef === this.rows ) {
|
|
54
55
|
return this.cachedRows;
|
|
55
56
|
}
|
|
56
57
|
}
|
|
@@ -60,6 +61,7 @@ export default {
|
|
|
60
61
|
if ( key ) {
|
|
61
62
|
this.cacheKey = key;
|
|
62
63
|
this.cachedRows = out;
|
|
64
|
+
this.cachedRowsRef = this.rows;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
return out;
|
|
@@ -104,8 +106,9 @@ export default {
|
|
|
104
106
|
return {
|
|
105
107
|
sortBy,
|
|
106
108
|
descending,
|
|
107
|
-
cachedRows:
|
|
108
|
-
|
|
109
|
+
cachedRows: null,
|
|
110
|
+
cachedRowsRef: null,
|
|
111
|
+
cacheKey: null,
|
|
109
112
|
};
|
|
110
113
|
},
|
|
111
114
|
|