@rancher/shell 3.0.2-rc.5 → 3.0.2
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/images/providers/nutanix.svg +12 -1
- package/assets/styles/base/_basic.scss +2 -1
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/global/_labeled-input.scss +5 -13
- package/assets/styles/global/_layout.scss +4 -1
- package/assets/styles/global/_select.scss +5 -0
- package/assets/styles/themes/_dark.scss +1 -3
- package/assets/styles/themes/_light.scss +5 -1
- package/assets/translations/en-us.yaml +130 -23
- package/assets/translations/zh-hans.yaml +0 -3
- package/cloud-credential/azure.vue +1 -1
- package/components/ActionMenuShell.vue +105 -0
- package/components/AppModal.vue +2 -2
- package/components/AsyncButton.vue +2 -0
- package/components/ButtonGroup.vue +9 -2
- package/components/ClusterBadge.vue +1 -0
- package/components/ClusterIconMenu.vue +3 -0
- package/components/ClusterProviderIcon.vue +14 -1
- package/components/CodeMirror.vue +96 -5
- package/components/Collapse.vue +16 -3
- package/components/CruResource.vue +9 -0
- package/components/CruResourceFooter.vue +1 -1
- package/components/ExplorerMembers.vue +2 -1
- package/components/FixedBanner.vue +19 -12
- package/components/Import.vue +14 -1
- package/components/LandingPagePreference.vue +4 -2
- package/components/PodSecurityAdmission.vue +8 -6
- package/components/PromptChangePassword.vue +1 -0
- package/components/PromptRemove.vue +23 -21
- package/components/ResourceDetail/Masthead.vue +30 -11
- package/components/ResourceDetail/__tests__/Masthead.test.ts +61 -0
- package/components/ResourceDetail/index.vue +6 -0
- package/components/ResourceTable.vue +6 -1
- package/components/ResourceYaml.vue +1 -0
- package/components/Setting.vue +115 -0
- package/components/SortableTable/THead.vue +2 -0
- package/components/SortableTable/index.vue +7 -12
- package/components/StatusBadge.vue +71 -0
- package/components/Tabbed/index.vue +16 -15
- package/components/Wizard.vue +108 -104
- package/components/YamlEditor.vue +12 -2
- package/components/__tests__/Collapse.test.ts +2 -2
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/auth/Principal.vue +29 -17
- package/components/auth/__tests__/Principal.test.ts +40 -0
- package/components/auth/login/ldap.vue +7 -0
- package/components/fleet/FleetBundles.vue +1 -1
- package/components/fleet/FleetRepos.vue +1 -1
- package/components/fleet/FleetResources.vue +0 -2
- package/components/fleet/FleetSummary.vue +60 -65
- package/components/fleet/ForceDirectedTreeChart/index.vue +5 -1
- package/components/fleet/__tests__/FleetSummary.test.ts +49 -9
- package/components/form/ArrayList.vue +6 -2
- package/components/form/ColorInput.vue +1 -0
- package/components/form/KeyValue.vue +11 -12
- package/components/form/LabeledSelect.vue +15 -3
- package/components/form/Labels.vue +8 -1
- package/components/form/Members/MembershipEditor.vue +230 -222
- package/components/form/Members/__tests__/MembershipEditor.test.ts +62 -0
- package/components/form/Password.vue +3 -0
- package/components/form/ProjectMemberEditor.vue +6 -3
- package/components/form/ResourceTabs/index.vue +15 -13
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +5 -4
- package/components/form/SchedulingCustomization.vue +85 -0
- package/components/form/Select.vue +3 -2
- package/components/form/SelectOrCreateAuthSecret.vue +2 -1
- package/components/form/UnitInput.vue +3 -4
- package/components/form/__tests__/ArrayList.test.ts +9 -6
- package/components/form/__tests__/LabeledSelect.test.ts +37 -0
- package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +34 -0
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/formatter/LiveDate.vue +3 -1
- package/components/formatter/ServiceType.vue +12 -4
- package/components/formatter/WorkloadHealthScale.vue +2 -1
- package/components/nav/Header.vue +35 -2
- package/components/nav/HeaderPageActionMenu.vue +11 -40
- package/components/nav/Jump.vue +8 -2
- package/components/nav/NamespaceFilter.vue +5 -4
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.helper.ts +5 -5
- package/components/nav/TopLevelMenu.vue +1 -12
- package/components/nav/WindowManager/ContainerLogs.vue +96 -58
- package/components/nav/WindowManager/ContainerShell.vue +99 -18
- package/components/nav/WindowManager/index.vue +74 -6
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/components/templates/default.vue +2 -47
- package/config/features.js +1 -0
- package/config/labels-annotations.js +11 -1
- package/config/router/navigation-guards/index.js +2 -1
- package/config/router/navigation-guards/record-last-route.js +24 -0
- package/config/settings.ts +66 -98
- package/config/version.js +1 -1
- package/core/types-provisioning.ts +7 -0
- package/detail/fleet.cattle.io.bundle.vue +7 -0
- package/detail/fleet.cattle.io.cluster.vue +0 -3
- package/detail/fleet.cattle.io.gitrepo.vue +8 -15
- package/detail/provisioning.cattle.io.cluster.vue +8 -2
- package/dialog/DeactivateDriverDialog.vue +5 -5
- package/dialog/GitRepoForceUpdateDialog.vue +132 -0
- package/directives/strip-html-aria-label.js +19 -0
- package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +87 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +217 -37
- package/edit/auth/__tests__/oidc.test.ts +60 -12
- package/edit/auth/ldap/__tests__/config.test.ts +40 -0
- package/edit/auth/ldap/config.vue +67 -89
- package/edit/auth/oidc.vue +16 -2
- package/edit/catalog.cattle.io.clusterrepo.vue +12 -8
- package/edit/cis.cattle.io.clusterscan.vue +13 -1
- package/edit/fleet.cattle.io.gitrepo.vue +198 -72
- package/edit/logging-flow/Match.vue +0 -21
- package/edit/management.cattle.io.project.vue +1 -1
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +10 -3
- package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +5 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +5 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +8 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +2 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +55 -15
- package/edit/provisioning.cattle.io.cluster/index.vue +28 -30
- package/edit/provisioning.cattle.io.cluster/rke2.vue +64 -13
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +37 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +3 -2
- package/edit/resources.cattle.io.backup.vue +150 -15
- package/edit/secret/__tests__/ssh.test.ts +79 -0
- package/edit/secret/ssh.vue +7 -1
- package/edit/service.vue +0 -3
- package/edit/workload/Job.vue +8 -8
- package/edit/workload/__tests__/Job.test.ts +0 -1
- package/edit/workload/index.vue +3 -1
- package/initialize/install-directives.js +2 -0
- package/initialize/install-plugins.js +6 -1
- package/list/catalog.cattle.io.app.vue +21 -4
- package/list/fleet.cattle.io.bundle.vue +1 -1
- package/list/management.cattle.io.setting.vue +34 -132
- package/list/provisioning.cattle.io.cluster.vue +11 -3
- package/machine-config/vmwarevsphere.vue +15 -8
- package/mixins/__tests__/auth-config.test.ts +74 -0
- package/mixins/__tests__/chart.test.ts +5 -4
- package/mixins/__tests__/create-edit-view.test.ts +38 -0
- package/mixins/auth-config.js +8 -0
- package/mixins/chart.js +2 -2
- package/mixins/create-edit-view/impl.js +4 -1
- package/mixins/vue-select-overrides.js +10 -0
- package/models/__tests__/catalog.cattle.io.app.test.ts +148 -0
- package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +157 -0
- package/models/__tests__/secret.test.ts +56 -13
- package/models/catalog.cattle.io.app.js +112 -37
- package/models/cluster.js +11 -0
- package/models/fleet.cattle.io.bundle.js +40 -2
- package/models/fleet.cattle.io.gitrepo.js +169 -109
- package/models/management.cattle.io.fleetworkspace.js +4 -0
- package/models/management.cattle.io.kontainerdriver.js +7 -0
- package/models/nodedriver.js +4 -1
- package/models/provisioning.cattle.io.cluster.js +24 -0
- package/models/secret.js +1 -1
- package/package.json +5 -5
- package/pages/auth/login.vue +5 -11
- package/pages/auth/verify.vue +11 -1
- package/pages/c/_cluster/apps/charts/index.vue +6 -4
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/explorer/ConfigBadge.vue +3 -5
- package/pages/c/_cluster/explorer/EventsTable.vue +3 -2
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +9 -9
- package/pages/c/_cluster/explorer/index.vue +33 -35
- package/pages/c/_cluster/explorer/tools/index.vue +3 -3
- package/pages/c/_cluster/fleet/index.vue +0 -5
- package/pages/c/_cluster/legacy/project/index.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +52 -53
- package/pages/c/_cluster/uiplugins/index.vue +19 -22
- package/pages/home.vue +17 -12
- package/pages/prefs.vue +5 -1
- package/plugins/shortkey.js +10 -1
- package/plugins/steve/steve-pagination-utils.ts +58 -8
- package/promptRemove/management.cattle.io.fleetworkspace.vue +98 -0
- package/promptRemove/management.cattle.io.globalrole.vue +1 -1
- package/promptRemove/management.cattle.io.project.vue +2 -8
- package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
- package/promptRemove/mixin/roleDeletionCheck.js +1 -7
- package/promptRemove/pod.vue +7 -28
- package/rancher-components/Card/Card.vue +9 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +42 -6
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +30 -3
- package/rancher-components/Form/Radio/RadioButton.vue +18 -3
- package/rancher-components/Form/Radio/RadioGroup.vue +39 -5
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +13 -1
- package/rancher-components/RcButton/RcButton.test.ts +97 -0
- package/rancher-components/RcButton/RcButton.vue +14 -9
- package/rancher-components/RcDropdown/RcDropdown.vue +3 -1
- package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -2
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +66 -0
- package/rancher-components/RcDropdown/index.ts +1 -0
- package/rancher-components/RcDropdown/types.ts +27 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +5 -2
- package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +2 -2
- package/scripts/typegen.sh +1 -0
- package/store/__tests__/auth.test.ts +120 -0
- package/store/action-menu.js +13 -3
- package/store/auth.js +14 -9
- package/store/aws.js +9 -2
- package/store/catalog.js +14 -7
- package/store/features.js +1 -0
- package/store/prefs.js +9 -28
- package/store/type-map.utils.ts +4 -0
- package/types/resources/settings.d.ts +27 -20
- package/types/shell/index.d.ts +18 -12
- package/utils/__tests__/array.test.ts +13 -1
- package/utils/__tests__/string.test.ts +80 -1
- package/utils/array.ts +13 -0
- package/utils/auth.js +4 -0
- package/utils/banners.js +0 -45
- package/utils/cluster.js +1 -1
- package/{edit/monitoring.coreos.com.prometheusrule → utils}/duration.js +5 -3
- package/utils/object.js +0 -3
- package/utils/pagination-utils.ts +15 -2
- package/utils/string.js +31 -7
- package/utils/validators/formRules/__tests__/index.test.ts +27 -0
- package/utils/validators/formRules/index.ts +16 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +0 -198
|
@@ -229,17 +229,17 @@ export default defineComponent({
|
|
|
229
229
|
@update:value="updateLabels()"
|
|
230
230
|
/>
|
|
231
231
|
<p v-else>
|
|
232
|
-
<t
|
|
232
|
+
<t
|
|
233
|
+
:id="`psa-label-for-level-${ level }`"
|
|
234
|
+
:k="`podSecurityAdmission.labels.${level}`"
|
|
235
|
+
/>
|
|
233
236
|
</p>
|
|
234
237
|
</span>
|
|
235
238
|
|
|
236
|
-
<span
|
|
237
|
-
class="
|
|
238
|
-
col
|
|
239
|
-
span-4"
|
|
240
|
-
>
|
|
239
|
+
<span class="col span-4">
|
|
241
240
|
<LabeledSelect
|
|
242
241
|
v-model:value="psaControl.level"
|
|
242
|
+
:aria-labelledby="`psa-label-for-level-${ level }`"
|
|
243
243
|
:data-testid="componentTestid + '--psaControl-' + i + '-level'"
|
|
244
244
|
:disabled="isPsaControlDisabled(psaControl.active)"
|
|
245
245
|
:options="options"
|
|
@@ -256,6 +256,7 @@ export default defineComponent({
|
|
|
256
256
|
:options="options"
|
|
257
257
|
:placeholder="t('podSecurityAdmission.version.placeholder', { psaControl: mode })"
|
|
258
258
|
:mode="mode"
|
|
259
|
+
:aria-label="`${t(`podSecurityAdmission.labels.${level}`)} - ${t('podSecurityAdmission.version.placeholder', { psaControl: mode })}`"
|
|
259
260
|
@update:value="updateLabels()"
|
|
260
261
|
/>
|
|
261
262
|
</span>
|
|
@@ -295,6 +296,7 @@ export default defineComponent({
|
|
|
295
296
|
:options="options"
|
|
296
297
|
:placeholder="t('podSecurityAdmission.exemptions.placeholder', { psaExemptionsControl: dimension })"
|
|
297
298
|
:mode="mode"
|
|
299
|
+
:aria-label="`${t(`podSecurityAdmission.labels.${ dimension }`)} - ${t('podSecurityAdmission.exemptions.placeholder', { psaExemptionsControl: dimension })}`"
|
|
298
300
|
@update:value="updateExemptions()"
|
|
299
301
|
/>
|
|
300
302
|
</span>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { shallowRef } from 'vue';
|
|
2
3
|
import { mapState, mapGetters } from 'vuex';
|
|
3
4
|
import { get, isEmpty } from '@shell/utils/object';
|
|
4
5
|
import { escapeHtml, resourceNames } from '@shell/utils/string';
|
|
@@ -38,7 +39,7 @@ export default {
|
|
|
38
39
|
error: '',
|
|
39
40
|
warning: '',
|
|
40
41
|
preventDelete: false,
|
|
41
|
-
removeComponent: this.$store.getters['type-map/importCustomPromptRemove'](resource),
|
|
42
|
+
removeComponent: shallowRef(this.$store.getters['type-map/importCustomPromptRemove'](resource)),
|
|
42
43
|
chartsToRemoveIsApp: false,
|
|
43
44
|
chartsDeleteCrd: false,
|
|
44
45
|
showModal: false,
|
|
@@ -46,7 +47,7 @@ export default {
|
|
|
46
47
|
},
|
|
47
48
|
computed: {
|
|
48
49
|
names() {
|
|
49
|
-
return this.toRemove.map((obj) => obj.nameDisplay)
|
|
50
|
+
return this.toRemove.map((obj) => obj.nameDisplay);
|
|
50
51
|
},
|
|
51
52
|
|
|
52
53
|
nameToMatchPosition() {
|
|
@@ -92,12 +93,6 @@ export default {
|
|
|
92
93
|
return first?.confirmRemove;
|
|
93
94
|
},
|
|
94
95
|
|
|
95
|
-
plusMore() {
|
|
96
|
-
const remaining = this.toRemove.length - this.names.length;
|
|
97
|
-
|
|
98
|
-
return this.t('promptRemove.andOthers', { count: remaining });
|
|
99
|
-
},
|
|
100
|
-
|
|
101
96
|
// if the current route ends with the ID of the resource being deleted, whatever page this is wont be valid after successful deletion: navigate away
|
|
102
97
|
doneLocation() {
|
|
103
98
|
// if deleting more than one resource, this is happening in list view and shouldn't redirect anywhere
|
|
@@ -167,7 +162,7 @@ export default {
|
|
|
167
162
|
if (show) {
|
|
168
163
|
const selected = this.toRemove[0];
|
|
169
164
|
|
|
170
|
-
if (this.currentRouter?.currentRoute?.name === 'c-cluster-explorer-tools' &&
|
|
165
|
+
if (this.currentRouter?.currentRoute?.value?.name === 'c-cluster-explorer-tools' &&
|
|
171
166
|
selected.type === CATALOG.APP &&
|
|
172
167
|
selected.spec?.chart?.metadata?.annotations[CATALOG_ANNOTATIONS.AUTO_INSTALL]) {
|
|
173
168
|
this.chartsToRemoveIsApp = true;
|
|
@@ -183,7 +178,7 @@ export default {
|
|
|
183
178
|
|
|
184
179
|
this.hasCustomRemove = this.$store.getters['type-map/hasCustomPromptRemove'](resource);
|
|
185
180
|
|
|
186
|
-
this.removeComponent = this.$store.getters['type-map/importCustomPromptRemove'](resource);
|
|
181
|
+
this.removeComponent = shallowRef(this.$store.getters['type-map/importCustomPromptRemove'](resource));
|
|
187
182
|
} else {
|
|
188
183
|
this.showModal = false;
|
|
189
184
|
}
|
|
@@ -359,7 +354,7 @@ export default {
|
|
|
359
354
|
<div class="mb-10">
|
|
360
355
|
<template v-if="!hasCustomRemove">
|
|
361
356
|
{{ t('promptRemove.attemptingToRemove', { type }) }} <span
|
|
362
|
-
v-clean-html="resourceNames(names,
|
|
357
|
+
v-clean-html="resourceNames(names, t)"
|
|
363
358
|
/>
|
|
364
359
|
</template>
|
|
365
360
|
|
|
@@ -368,7 +363,7 @@ export default {
|
|
|
368
363
|
v-if="hasCustomRemove"
|
|
369
364
|
ref="customPrompt"
|
|
370
365
|
v-model:value="toRemove"
|
|
371
|
-
v-bind="
|
|
366
|
+
v-bind="$data"
|
|
372
367
|
:close="close"
|
|
373
368
|
:needs-confirm="needsConfirm"
|
|
374
369
|
:value="toRemove"
|
|
@@ -394,6 +389,7 @@ export default {
|
|
|
394
389
|
v-focus
|
|
395
390
|
:data-testid="componentTestid + '-input'"
|
|
396
391
|
type="text"
|
|
392
|
+
:aria-label="t('promptRemove.confirmName', { nameToMatch: escapeHtml(nameToMatch) })"
|
|
397
393
|
>
|
|
398
394
|
<div class="text-warning mb-10 mt-10">
|
|
399
395
|
{{ warning }}
|
|
@@ -407,22 +403,28 @@ export default {
|
|
|
407
403
|
>
|
|
408
404
|
{{ protip }}
|
|
409
405
|
</div>
|
|
410
|
-
<Checkbox
|
|
411
|
-
v-if="chartsToRemoveIsApp"
|
|
412
|
-
v-model:value="chartsDeleteCrd"
|
|
413
|
-
label-key="promptRemoveApp.removeCrd"
|
|
414
|
-
class="mt-10 type"
|
|
415
|
-
@update:value="chartAddCrdToRemove"
|
|
416
|
-
/>
|
|
417
406
|
</LabeledInput>
|
|
418
407
|
<div v-else-if="!hasCustomRemove">
|
|
419
|
-
<div
|
|
408
|
+
<div
|
|
409
|
+
v-if="warning"
|
|
410
|
+
class="text-warning mb-10 mt-10"
|
|
411
|
+
>
|
|
420
412
|
{{ warning }}
|
|
421
413
|
</div>
|
|
422
|
-
<div
|
|
414
|
+
<div
|
|
415
|
+
v-if="error"
|
|
416
|
+
class="text-error mb-10 mt-10"
|
|
417
|
+
>
|
|
423
418
|
{{ error }}
|
|
424
419
|
</div>
|
|
425
420
|
</div>
|
|
421
|
+
<Checkbox
|
|
422
|
+
v-if="chartsToRemoveIsApp"
|
|
423
|
+
v-model:value="chartsDeleteCrd"
|
|
424
|
+
label-key="promptRemoveApp.removeCrd"
|
|
425
|
+
class="mt-10 type"
|
|
426
|
+
@update:value="chartAddCrdToRemove"
|
|
427
|
+
/>
|
|
426
428
|
</template>
|
|
427
429
|
<template #actions>
|
|
428
430
|
<button
|
|
@@ -504,10 +504,32 @@ export default {
|
|
|
504
504
|
{{ namespace }}
|
|
505
505
|
</span>
|
|
506
506
|
</span>
|
|
507
|
-
<span v-if="parent.showAge">
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
507
|
+
<span v-if="parent.showAge">
|
|
508
|
+
{{ t("resourceDetail.masthead.age") }}:
|
|
509
|
+
<LiveDate
|
|
510
|
+
class="live-date"
|
|
511
|
+
:value="value.creationTimestamp"
|
|
512
|
+
/>
|
|
513
|
+
</span>
|
|
514
|
+
<span
|
|
515
|
+
v-if="value.showCreatedBy"
|
|
516
|
+
data-testid="masthead-subheader-createdBy"
|
|
517
|
+
>
|
|
518
|
+
{{ t("resourceDetail.masthead.createdBy") }}:
|
|
519
|
+
<router-link
|
|
520
|
+
v-if="value.createdBy.location"
|
|
521
|
+
:to="value.createdBy.location"
|
|
522
|
+
data-testid="masthead-subheader-createdBy-link"
|
|
523
|
+
>
|
|
524
|
+
{{ value.createdBy.displayName }}
|
|
525
|
+
</router-link>
|
|
526
|
+
<span
|
|
527
|
+
v-else
|
|
528
|
+
data-testid="masthead-subheader-createdBy_plain-text"
|
|
529
|
+
>
|
|
530
|
+
{{ value.createdBy.displayName }}
|
|
531
|
+
</span>
|
|
532
|
+
</span>
|
|
511
533
|
<span v-if="value.showPodRestarts">{{ t("resourceDetail.masthead.restartCount") }}:<span class="live-data"> {{ value.restartCount }}</span></span>
|
|
512
534
|
</div>
|
|
513
535
|
</div>
|
|
@@ -587,11 +609,8 @@ export default {
|
|
|
587
609
|
}
|
|
588
610
|
|
|
589
611
|
HEADER {
|
|
590
|
-
margin: 0
|
|
591
|
-
|
|
592
|
-
.title {
|
|
593
|
-
overflow-x: hidden;
|
|
594
|
-
}
|
|
612
|
+
margin: 0;
|
|
613
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
595
614
|
}
|
|
596
615
|
|
|
597
616
|
.primaryheader {
|
|
@@ -600,14 +619,13 @@ export default {
|
|
|
600
619
|
align-items: center;
|
|
601
620
|
|
|
602
621
|
h1 {
|
|
603
|
-
margin: 0;
|
|
622
|
+
margin: 0 0 0 -5px;
|
|
604
623
|
overflow-x: hidden;
|
|
605
624
|
display: flex;
|
|
606
625
|
flex-direction: row;
|
|
607
626
|
align-items: center;
|
|
608
627
|
|
|
609
628
|
.masthead-resource-title {
|
|
610
|
-
padding: 0 8px;
|
|
611
629
|
text-overflow: ellipsis;
|
|
612
630
|
overflow: hidden;
|
|
613
631
|
white-space: nowrap;
|
|
@@ -638,6 +656,7 @@ export default {
|
|
|
638
656
|
}
|
|
639
657
|
|
|
640
658
|
.masthead-state {
|
|
659
|
+
margin-left: 8px;
|
|
641
660
|
font-size: initial;
|
|
642
661
|
}
|
|
643
662
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { mount, RouterLinkStub } from '@vue/test-utils';
|
|
2
|
+
import { _VIEW } from '@shell/config/query-params';
|
|
3
|
+
import Masthead from '@shell/components/ResourceDetail/Masthead.vue';
|
|
4
|
+
|
|
5
|
+
const mockedStore = () => {
|
|
6
|
+
return {
|
|
7
|
+
getters: {
|
|
8
|
+
currentStore: () => 'current_store',
|
|
9
|
+
currentProduct: { inStore: 'cluster' },
|
|
10
|
+
isExplorer: false,
|
|
11
|
+
currentCluster: {},
|
|
12
|
+
'type-map/labelFor': jest.fn(),
|
|
13
|
+
'type-map/optionsFor': jest.fn(),
|
|
14
|
+
'current_store/schemaFor': jest.fn(),
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const requiredSetup = () => {
|
|
20
|
+
return {
|
|
21
|
+
stubs: {
|
|
22
|
+
'router-link': RouterLinkStub,
|
|
23
|
+
LiveDate: true
|
|
24
|
+
},
|
|
25
|
+
mocks: { $store: mockedStore() }
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe('component: Masthead', () => {
|
|
30
|
+
it.each([
|
|
31
|
+
['hidden', '', false, { displayName: 'admin', location: { id: 'resource-id' } }, false, false],
|
|
32
|
+
['plain-text', 'admin', true, { displayName: 'admin', location: null }, false, true],
|
|
33
|
+
['link', 'foo', true, { displayName: 'foo', location: { id: 'resource-id' } }, true, false],
|
|
34
|
+
])('"Created By" should be %p, with text: %p', (
|
|
35
|
+
_,
|
|
36
|
+
text,
|
|
37
|
+
showCreatedBy,
|
|
38
|
+
createdBy,
|
|
39
|
+
showLink,
|
|
40
|
+
showPlainText,
|
|
41
|
+
) => {
|
|
42
|
+
const wrapper = mount(Masthead, {
|
|
43
|
+
props: {
|
|
44
|
+
mode: _VIEW,
|
|
45
|
+
value: {
|
|
46
|
+
showCreatedBy,
|
|
47
|
+
createdBy,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
global: { ...requiredSetup() }
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const container = wrapper.find('[data-testid="masthead-subheader-createdBy"]');
|
|
54
|
+
const link = wrapper.find('[data-testid="masthead-subheader-createdBy-link"]');
|
|
55
|
+
const plainText = wrapper.find('[data-testid="masthead-subheader-createdBy_plain-text"]');
|
|
56
|
+
|
|
57
|
+
expect(link.exists()).toBe(showLink);
|
|
58
|
+
expect(plainText.exists()).toBe(showPlainText);
|
|
59
|
+
expect(showLink || showPlainText ? container.element.textContent : '').toContain(text);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -71,6 +71,11 @@ export default {
|
|
|
71
71
|
default: null,
|
|
72
72
|
},
|
|
73
73
|
|
|
74
|
+
flexContent: {
|
|
75
|
+
type: Boolean,
|
|
76
|
+
default: false,
|
|
77
|
+
},
|
|
78
|
+
|
|
74
79
|
/**
|
|
75
80
|
* Inherited global identifier prefix for tests
|
|
76
81
|
* Define a term based on the parent component to avoid conflicts on multiple components
|
|
@@ -484,6 +489,7 @@ export default {
|
|
|
484
489
|
:initial-value="initialModel"
|
|
485
490
|
:live-value="liveModel"
|
|
486
491
|
:real-mode="realMode"
|
|
492
|
+
:class="{'flex-content': flexContent}"
|
|
487
493
|
@update:value="$emit('input', $event)"
|
|
488
494
|
@set-subtype="setSubtype"
|
|
489
495
|
/>
|
|
@@ -188,6 +188,11 @@ export default {
|
|
|
188
188
|
type: Number,
|
|
189
189
|
default: null, // Default comes from the user preference
|
|
190
190
|
},
|
|
191
|
+
|
|
192
|
+
hideGroupingControls: {
|
|
193
|
+
type: Boolean,
|
|
194
|
+
default: false
|
|
195
|
+
}
|
|
191
196
|
},
|
|
192
197
|
|
|
193
198
|
data() {
|
|
@@ -591,7 +596,7 @@ export default {
|
|
|
591
596
|
@enter="handleEnterKeyPress"
|
|
592
597
|
>
|
|
593
598
|
<template
|
|
594
|
-
v-if="showGrouping"
|
|
599
|
+
v-if="!hideGroupingControls && showGrouping"
|
|
595
600
|
#header-middle
|
|
596
601
|
>
|
|
597
602
|
<slot name="more-header-middle" />
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import ActionMenu from '@shell/components/ActionMenuShell.vue';
|
|
3
|
+
import { mapGetters } from 'vuex';
|
|
4
|
+
export default {
|
|
5
|
+
name: 'Setting',
|
|
6
|
+
components: { ActionMenu },
|
|
7
|
+
props: {
|
|
8
|
+
value: {
|
|
9
|
+
type: Object,
|
|
10
|
+
required: true,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
computed: {
|
|
14
|
+
...mapGetters({ t: 'i18n/t' }),
|
|
15
|
+
...mapGetters({ options: 'action-menu/optionsArray' }),
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div
|
|
22
|
+
class="advanced-setting mb-20"
|
|
23
|
+
:data-testid="`advanced-setting__option-${value.id}`"
|
|
24
|
+
>
|
|
25
|
+
<div class="header">
|
|
26
|
+
<div class="title">
|
|
27
|
+
<h1>
|
|
28
|
+
{{ value.id }}
|
|
29
|
+
<span
|
|
30
|
+
v-if="value.fromEnv"
|
|
31
|
+
class="modified"
|
|
32
|
+
>{{ t('advancedSettings.setEnv') }}</span>
|
|
33
|
+
<span
|
|
34
|
+
v-else-if="value.customized"
|
|
35
|
+
class="modified"
|
|
36
|
+
>{{ t('advancedSettings.modified') }}</span>
|
|
37
|
+
</h1>
|
|
38
|
+
<h2>{{ t(`advancedSettings.descriptions.${value.id}`) }}</h2>
|
|
39
|
+
</div>
|
|
40
|
+
<div
|
|
41
|
+
v-if="value.hasActions"
|
|
42
|
+
class="action"
|
|
43
|
+
>
|
|
44
|
+
<action-menu
|
|
45
|
+
:resource="value.data"
|
|
46
|
+
:button-aria-label="t('advancedSettings.edit.label')"
|
|
47
|
+
data-testid="action-button"
|
|
48
|
+
button-role="tertiary"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div value>
|
|
53
|
+
<div v-if="value.canHide">
|
|
54
|
+
<button
|
|
55
|
+
class="btn btn-sm role-primary"
|
|
56
|
+
role="button"
|
|
57
|
+
:aria-label="t('advancedSettings.hideShow')"
|
|
58
|
+
@click="value.hide = !value.hide"
|
|
59
|
+
>
|
|
60
|
+
{{ value.hide ? t('advancedSettings.show') : t('advancedSettings.hide') }} {{ value.id }}
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
<div
|
|
64
|
+
v-show="!value.canHide || (value.canHide && !value.hide)"
|
|
65
|
+
class="settings-value"
|
|
66
|
+
>
|
|
67
|
+
<pre v-if="value.kind === 'json'">{{ value.json }}</pre>
|
|
68
|
+
<pre v-else-if="value.kind === 'multiline'">{{ value.data.value || value.data.default }}</pre>
|
|
69
|
+
<pre v-else-if="value.kind === 'enum'">{{ t(value.enum) }}</pre>
|
|
70
|
+
<pre v-else-if="value.data.value || value.data.default">{{ value.data.value || value.data.default }}</pre>
|
|
71
|
+
<pre
|
|
72
|
+
v-else
|
|
73
|
+
class="text-muted"
|
|
74
|
+
><{{ t('advancedSettings.none') }}></pre>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<style lang='scss' scoped>
|
|
81
|
+
.settings-value pre {
|
|
82
|
+
margin: 0;
|
|
83
|
+
}
|
|
84
|
+
.advanced-setting {
|
|
85
|
+
border: 1px solid var(--border);
|
|
86
|
+
padding: 20px;
|
|
87
|
+
border-radius: var(--border-radius);
|
|
88
|
+
|
|
89
|
+
h1 {
|
|
90
|
+
font-size: 14px;
|
|
91
|
+
}
|
|
92
|
+
h2 {
|
|
93
|
+
font-size: 12px;
|
|
94
|
+
margin-bottom: 0;
|
|
95
|
+
opacity: 0.8;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.header {
|
|
100
|
+
display: flex;
|
|
101
|
+
margin-bottom: 20px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.title {
|
|
105
|
+
flex: 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.modified {
|
|
109
|
+
margin-left: 10px;
|
|
110
|
+
border: 1px solid var(--primary);
|
|
111
|
+
border-radius: 5px;
|
|
112
|
+
padding: 2px 10px;
|
|
113
|
+
font-size: 12px;
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
@@ -230,6 +230,7 @@ export default {
|
|
|
230
230
|
data-testid="sortable-table_check_select_all"
|
|
231
231
|
:indeterminate="isIndeterminate"
|
|
232
232
|
:disabled="noRows || noResults"
|
|
233
|
+
:alternate-label="t('sortableTable.genericGroupCheckbox')"
|
|
233
234
|
/>
|
|
234
235
|
</th>
|
|
235
236
|
<th
|
|
@@ -269,6 +270,7 @@ export default {
|
|
|
269
270
|
<div
|
|
270
271
|
v-if="col.sort"
|
|
271
272
|
class="sort"
|
|
273
|
+
aria-hidden="true"
|
|
272
274
|
>
|
|
273
275
|
<i
|
|
274
276
|
v-show="hasAdvancedFiltering && !col.isFilter"
|
|
@@ -23,6 +23,7 @@ import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
|
23
23
|
import { getParent } from '@shell/utils/dom';
|
|
24
24
|
import { FORMATTERS } from '@shell/components/SortableTable/sortable-config';
|
|
25
25
|
import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
|
|
26
|
+
import ActionMenu from '@shell/components/ActionMenuShell.vue';
|
|
26
27
|
|
|
27
28
|
// Uncomment for table performance debugging
|
|
28
29
|
// import tableDebug from './debug';
|
|
@@ -58,6 +59,7 @@ export default {
|
|
|
58
59
|
ActionDropdown,
|
|
59
60
|
LabeledSelect,
|
|
60
61
|
ButtonMultiAction,
|
|
62
|
+
ActionMenu,
|
|
61
63
|
},
|
|
62
64
|
mixins: [
|
|
63
65
|
filtering,
|
|
@@ -1383,6 +1385,7 @@ export default {
|
|
|
1383
1385
|
:data-node-id="row.key"
|
|
1384
1386
|
:data-testid="componentTestid + '-' + i + '-checkbox'"
|
|
1385
1387
|
:value="selectedRows.includes(row.row)"
|
|
1388
|
+
:alternate-label="t('sortableTable.genericRowCheckbox', { item: row && row.row ? row.row.id : '' })"
|
|
1386
1389
|
/>
|
|
1387
1390
|
</td>
|
|
1388
1391
|
<td
|
|
@@ -1468,23 +1471,16 @@ export default {
|
|
|
1468
1471
|
</template>
|
|
1469
1472
|
<td
|
|
1470
1473
|
v-if="rowActions"
|
|
1471
|
-
align="middle"
|
|
1472
1474
|
>
|
|
1473
1475
|
<slot
|
|
1474
1476
|
name="row-actions"
|
|
1475
1477
|
:row="row.row"
|
|
1478
|
+
:index="i"
|
|
1476
1479
|
>
|
|
1477
|
-
<
|
|
1478
|
-
:
|
|
1479
|
-
:ref="`actionButton${i}`"
|
|
1480
|
-
aria-haspopup="true"
|
|
1481
|
-
aria-expanded="false"
|
|
1482
|
-
:aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
|
|
1480
|
+
<ActionMenu
|
|
1481
|
+
:resource="row.row"
|
|
1483
1482
|
:data-testid="componentTestid + '-' + i + '-action-button'"
|
|
1484
|
-
:
|
|
1485
|
-
@click="handleActionButtonClick(i, $event)"
|
|
1486
|
-
@keyup.enter="handleActionButtonClick(i, $event)"
|
|
1487
|
-
@keyup.space="handleActionButtonClick(i, $event)"
|
|
1483
|
+
:button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
|
|
1488
1484
|
/>
|
|
1489
1485
|
</slot>
|
|
1490
1486
|
</td>
|
|
@@ -1782,7 +1778,6 @@ export default {
|
|
|
1782
1778
|
min-width: 400px;
|
|
1783
1779
|
border-radius: 5px 5px 0 0;
|
|
1784
1780
|
outline: 1px solid var(--border);
|
|
1785
|
-
overflow: hidden;
|
|
1786
1781
|
background: var(--sortable-table-bg);
|
|
1787
1782
|
border-radius: 4px;
|
|
1788
1783
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
|
|
3
|
+
const STATUS = {
|
|
4
|
+
success: {
|
|
5
|
+
color: 'text-success',
|
|
6
|
+
icon: 'icon-checkmark'
|
|
7
|
+
},
|
|
8
|
+
warning: {
|
|
9
|
+
color: 'text-warning',
|
|
10
|
+
icon: 'icon-warning'
|
|
11
|
+
},
|
|
12
|
+
info: {
|
|
13
|
+
color: 'text-info',
|
|
14
|
+
icon: 'icon-info'
|
|
15
|
+
},
|
|
16
|
+
error: {
|
|
17
|
+
color: 'text-error',
|
|
18
|
+
icon: 'icon-error'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const { status = 'success', label } = defineProps<{
|
|
23
|
+
status?: 'success' | 'warning' | 'info' | 'error',
|
|
24
|
+
label?: string
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<div
|
|
30
|
+
class="status-badge"
|
|
31
|
+
>
|
|
32
|
+
<i
|
|
33
|
+
class="status-badge__icon icon"
|
|
34
|
+
:class="{
|
|
35
|
+
[STATUS[status].icon]: true,
|
|
36
|
+
[STATUS[status].color]: true
|
|
37
|
+
}"
|
|
38
|
+
/>
|
|
39
|
+
<div
|
|
40
|
+
v-if="label"
|
|
41
|
+
class="status-badge__label"
|
|
42
|
+
>
|
|
43
|
+
{{ label }}
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<style lang="scss" scoped>
|
|
49
|
+
.status-badge {
|
|
50
|
+
align-items: center;
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
border: 1px solid;
|
|
53
|
+
border-color: var(--border);
|
|
54
|
+
margin-top: 20px;
|
|
55
|
+
|
|
56
|
+
& + & {
|
|
57
|
+
margin-left: 20px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&__label {
|
|
61
|
+
border-left: 1px solid var(--border);
|
|
62
|
+
padding: 5px 20px;
|
|
63
|
+
color: var(--body-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&__icon {
|
|
67
|
+
text-align: center;
|
|
68
|
+
padding: 5px 10px;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
</style>
|