@rancher/shell 3.0.4 → 3.0.5-rc.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/sks.svg +1 -0
- package/assets/styles/base/_basic.scss +6 -0
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +1 -0
- package/assets/styles/global/_button.scss +1 -0
- package/assets/translations/en-us.yaml +65 -15
- package/assets/translations/zh-hans.yaml +4 -3
- package/chart/monitoring/index.vue +3 -1
- package/cloud-credential/aws.vue +2 -0
- package/components/ActionDropdownShell.vue +71 -0
- package/components/AppModal.vue +18 -4
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/CommunityLinks.vue +4 -59
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +6 -1
- package/components/DetailText.vue +5 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +68 -18
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrowlManager.vue +1 -0
- package/components/LandingPagePreference.vue +7 -3
- package/components/LocaleSelector.vue +39 -95
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +1 -0
- package/components/PromptModal.vue +47 -8
- package/components/PromptRemove.vue +1 -0
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +38 -12
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +47 -12
- package/components/ResourceTable.vue +54 -19
- package/components/SideNav.vue +5 -1
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +5 -2
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +64 -51
- package/components/SortableTable/paging.js +16 -19
- package/components/SortableTable/selection.js +0 -11
- package/components/Wizard.vue +2 -2
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/PromptModal.test.ts +148 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/AuthBanner.vue +13 -11
- package/components/auth/Principal.vue +1 -0
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/auth/login/ldap.vue +1 -1
- package/components/fleet/FleetResources.vue +21 -6
- package/components/form/ArrayList.vue +76 -60
- package/components/form/BannerSettings.vue +17 -2
- package/components/form/ColorInput.vue +35 -6
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/LabeledSelect.vue +18 -22
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +14 -8
- package/components/form/NameNsDescription.vue +128 -104
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/NotificationSettings.vue +15 -1
- package/components/form/Password.vue +1 -0
- package/components/form/PodAffinity.vue +43 -43
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +16 -24
- package/components/form/SSHKnownHosts/index.vue +30 -13
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +32 -21
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/ColorInput.test.ts +35 -0
- package/components/form/__tests__/LabeledSelect.test.ts +40 -0
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +22 -2
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Group.vue +27 -5
- package/components/nav/Header.vue +17 -43
- package/components/nav/NamespaceFilter.vue +134 -86
- package/components/nav/TopLevelMenu.vue +4 -5
- package/components/nav/Type.vue +12 -1
- package/components/nav/WindowManager/ContainerLogs.vue +87 -61
- package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -3
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -4
- package/composables/focusTrap.ts +12 -4
- package/composables/useRuntimeFlag.ts +29 -0
- package/config/router/routes.js +20 -13
- package/config/store.js +4 -0
- package/config/uiplugins.js +5 -1
- package/core/types.ts +12 -6
- package/detail/catalog.cattle.io.app.vue +6 -1
- package/detail/fleet.cattle.io.bundle.vue +70 -6
- package/detail/fleet.cattle.io.gitrepo.vue +1 -1
- package/detail/namespace.vue +0 -3
- package/detail/node.vue +17 -13
- package/detail/provisioning.cattle.io.cluster.vue +72 -6
- package/dialog/AddCustomBadgeDialog.vue +1 -1
- package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
- package/{components/AssignTo.vue → dialog/AssignToDialog.vue} +71 -80
- package/dialog/ChangePasswordDialog.vue +106 -0
- package/dialog/DeactivateDriverDialog.vue +1 -0
- package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
- package/dialog/DisableAuthProviderDialog.vue +101 -0
- package/dialog/DrainNode.vue +1 -1
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +69 -57
- package/dialog/FeatureFlagListDialog.vue +288 -0
- package/dialog/ForceMachineRemoveDialog.vue +5 -2
- package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
- package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
- package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -59
- package/dialog/MoveNamespaceDialog.vue +157 -0
- package/dialog/ScalePoolDownDialog.vue +1 -1
- package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
- package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
- package/dialog/WechatDialog.vue +57 -0
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
- package/edit/auth/__tests__/oidc.test.ts +152 -109
- package/edit/auth/azuread.vue +2 -1
- package/edit/auth/github.vue +1 -1
- package/edit/auth/googleoauth.vue +5 -1
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +38 -5
- package/edit/auth/saml.vue +1 -1
- package/edit/cloudcredential.vue +24 -9
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
- package/edit/management.cattle.io.user.vue +28 -3
- package/edit/namespace.vue +1 -4
- package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
- package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +49 -41
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
- package/edit/token.vue +2 -0
- package/edit/workload/index.vue +1 -0
- package/edit/workload/mixins/workload.js +0 -2
- package/initialize/install-plugins.js +2 -1
- package/list/harvesterhci.io.management.cluster.vue +4 -1
- package/list/management.cattle.io.feature.vue +4 -287
- package/list/provisioning.cattle.io.cluster.vue +20 -12
- package/machine-config/azure.vue +16 -4
- package/mixins/vue-select-overrides.js +0 -4
- package/models/__tests__/namespace.test.ts +25 -1
- package/models/cloudcredential.js +5 -0
- package/models/fleet.cattle.io.cluster.js +8 -2
- package/models/fleet.cattle.io.gitrepo.js +8 -34
- package/models/kontainerdriver.js +6 -3
- package/models/management.cattle.io.feature.js +7 -1
- package/models/management.cattle.io.node.js +3 -3
- package/models/namespace.js +11 -6
- package/models/nodedriver.js +6 -3
- package/models/workload.js +4 -1
- package/package.json +3 -3
- package/pages/about.vue +13 -3
- package/pages/account/index.vue +16 -6
- package/pages/auth/login.vue +18 -7
- package/pages/auth/logout.vue +4 -1
- package/pages/auth/setup.vue +2 -0
- package/pages/auth/verify.vue +13 -8
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +26 -26
- package/pages/c/_cluster/auth/config/index.vue +10 -12
- package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
- package/pages/c/_cluster/explorer/index.vue +17 -15
- package/pages/c/_cluster/istio/index.vue +2 -2
- package/pages/c/_cluster/longhorn/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
- package/pages/c/_cluster/neuvector/index.vue +1 -1
- package/pages/c/_cluster/settings/banners.vue +4 -3
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
- package/pages/c/_cluster/uiplugins/index.vue +98 -55
- package/pages/diagnostic.vue +59 -11
- package/pages/fail-whale.vue +14 -8
- package/pages/home.vue +24 -18
- package/pages/prefs.vue +7 -6
- package/pages/support/index.vue +4 -1
- package/plugins/internal-api/index.ts +37 -0
- package/plugins/internal-api/shared/base-api.ts +13 -0
- package/plugins/internal-api/shell/shell.api.ts +108 -0
- package/plugins/steve/actions.js +0 -12
- package/public/index.html +1 -0
- package/rancher-components/Card/Card.vue +1 -1
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +47 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
- package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
- package/rancher-components/Form/Radio/RadioButton.vue +20 -4
- package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +52 -10
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +5 -0
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
- package/rancher-components/RcButton/RcButton.vue +2 -1
- package/rancher-components/RcButton/types.ts +1 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +18 -6
- package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
- package/rancher-components/RcDropdown/index.ts +2 -0
- package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
- package/rancher-components/RcDropdown/useDropdownItem.ts +63 -0
- package/scripts/extension/bundle +20 -0
- package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
- package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
- package/scripts/extension/helmpatch +44 -31
- package/scripts/extension/publish +12 -12
- package/scripts/typegen.sh +2 -4
- package/server/har-file.js +25 -3
- package/store/action-menu.js +26 -56
- package/store/features.js +2 -1
- package/store/index.js +5 -0
- package/store/modal.ts +71 -0
- package/store/slideInPanel.ts +47 -0
- package/store/type-map.js +12 -1
- package/store/type-map.utils.ts +4 -4
- package/types/global-vue.d.ts +5 -0
- package/types/internal-api/shell/growl.d.ts +25 -0
- package/types/internal-api/shell/modal.d.ts +77 -0
- package/types/internal-api/shell/slideIn.d.ts +15 -0
- package/types/resources/fleet.d.ts +0 -14
- package/types/shell/index.d.ts +43 -24
- package/types/vue-shim.d.ts +4 -1
- package/utils/__mocks__/tabbable.js +13 -0
- package/utils/__tests__/object.test.ts +38 -4
- package/utils/cluster.js +35 -0
- package/utils/fleet.ts +15 -73
- package/utils/object.js +48 -5
- package/utils/validators/formRules/__tests__/index.test.ts +10 -1
- package/utils/validators/formRules/index.ts +27 -3
- package/utils/validators/machine-pool.ts +20 -0
- package/components/DisableAuthProviderModal.vue +0 -114
- package/components/MoveModal.vue +0 -166
- package/components/PromptChangePassword.vue +0 -123
- package/components/fleet/FleetBundleResources.vue +0 -86
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
- package/types/vue-shim.d +0 -20
|
@@ -43,23 +43,14 @@ export default {
|
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
data() {
|
|
46
|
-
const {
|
|
47
|
-
command,
|
|
48
|
-
args,
|
|
49
|
-
workingDir,
|
|
50
|
-
stdin = false,
|
|
51
|
-
stdinOnce = false,
|
|
52
|
-
tty = false,
|
|
53
|
-
} = this.value;
|
|
54
|
-
|
|
55
46
|
return {
|
|
56
|
-
args,
|
|
57
|
-
command,
|
|
47
|
+
args: this.value.args,
|
|
48
|
+
command: this.value.command,
|
|
58
49
|
commandOptions: ['No', 'Once', 'Yes'],
|
|
59
|
-
stdin,
|
|
60
|
-
stdinOnce,
|
|
61
|
-
tty,
|
|
62
|
-
workingDir,
|
|
50
|
+
stdin: this.value.stdin || false,
|
|
51
|
+
stdinOnce: this.value.stdin || false,
|
|
52
|
+
tty: this.value.tty || false,
|
|
53
|
+
workingDir: this.value.workingDir,
|
|
63
54
|
};
|
|
64
55
|
},
|
|
65
56
|
|
|
@@ -39,14 +39,10 @@ export default {
|
|
|
39
39
|
},
|
|
40
40
|
|
|
41
41
|
data() {
|
|
42
|
-
const { env = [], envFrom = [] } = this.value;
|
|
43
|
-
|
|
44
|
-
const allEnv = [...env, ...envFrom].map((row) => {
|
|
45
|
-
return { value: row, id: randomStr(4) };
|
|
46
|
-
});
|
|
47
|
-
|
|
48
42
|
return {
|
|
49
|
-
env,
|
|
43
|
+
env: [],
|
|
44
|
+
envFrom: [],
|
|
45
|
+
allEnv: [],
|
|
50
46
|
};
|
|
51
47
|
},
|
|
52
48
|
|
|
@@ -63,7 +59,18 @@ export default {
|
|
|
63
59
|
}
|
|
64
60
|
}
|
|
65
61
|
},
|
|
62
|
+
|
|
66
63
|
created() {
|
|
64
|
+
const { env = [], envFrom = [] } = this.value;
|
|
65
|
+
|
|
66
|
+
const allEnv = [...env, ...envFrom].map((row) => {
|
|
67
|
+
return { value: row, id: randomStr(4) };
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
this.env = env;
|
|
71
|
+
this.envFrom = envFrom;
|
|
72
|
+
this.allEnv = allEnv;
|
|
73
|
+
|
|
67
74
|
this.queueUpdate = debounce(this.update, 500);
|
|
68
75
|
},
|
|
69
76
|
|
|
@@ -107,7 +114,8 @@ export default {
|
|
|
107
114
|
<div :style="{'width':'100%'}">
|
|
108
115
|
<div
|
|
109
116
|
v-for="(row, i) in allEnv"
|
|
110
|
-
:key="
|
|
117
|
+
:key="row.id"
|
|
118
|
+
:data-testid="`env-var-row-${i}`"
|
|
111
119
|
>
|
|
112
120
|
<ValueFromResource
|
|
113
121
|
v-model:value="row.value"
|
|
@@ -18,10 +18,10 @@ export default {
|
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
data() {
|
|
21
|
-
const { readinessProbe, livenessProbe, startupProbe } = this.value;
|
|
22
|
-
|
|
23
21
|
return {
|
|
24
|
-
readinessProbe
|
|
22
|
+
readinessProbe: this.value.readinessProbe,
|
|
23
|
+
livenessProbe: this.value.livenessProbe,
|
|
24
|
+
startupProbe: this.value.startupProbe,
|
|
25
25
|
};
|
|
26
26
|
},
|
|
27
27
|
|
|
@@ -28,23 +28,18 @@ export default {
|
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
data() {
|
|
31
|
-
const selectHook = null;
|
|
32
|
-
|
|
33
|
-
const defaultExec = { exec: { command: [] } };
|
|
34
|
-
const defaultHttpGet = {
|
|
35
|
-
httpGet: {
|
|
36
|
-
host: '',
|
|
37
|
-
path: '',
|
|
38
|
-
port: null,
|
|
39
|
-
scheme: '',
|
|
40
|
-
httpHeaders: null
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
31
|
return {
|
|
45
|
-
selectHook,
|
|
46
|
-
defaultExec,
|
|
47
|
-
defaultHttpGet
|
|
32
|
+
selectHook: null,
|
|
33
|
+
defaultExec: { exec: { command: [] } },
|
|
34
|
+
defaultHttpGet: {
|
|
35
|
+
httpGet: {
|
|
36
|
+
host: '',
|
|
37
|
+
path: '',
|
|
38
|
+
port: null,
|
|
39
|
+
scheme: '',
|
|
40
|
+
httpHeaders: null
|
|
41
|
+
}
|
|
42
|
+
},
|
|
48
43
|
schemeOptions: ['HTTP', 'HTTPS']
|
|
49
44
|
};
|
|
50
45
|
},
|
|
@@ -116,9 +116,11 @@ export default {
|
|
|
116
116
|
|
|
117
117
|
data() {
|
|
118
118
|
return {
|
|
119
|
-
selectedVisibility:
|
|
120
|
-
shouldOpen:
|
|
121
|
-
|
|
119
|
+
selectedVisibility: 'visible',
|
|
120
|
+
shouldOpen: true,
|
|
121
|
+
labeledSelectLabelId: `ls-label-id-${ generateRandomAlphaString(12) }`,
|
|
122
|
+
isOpen: false,
|
|
123
|
+
generatedUid: `ls-uid-${ generateRandomAlphaString(12) }`
|
|
122
124
|
};
|
|
123
125
|
},
|
|
124
126
|
|
|
@@ -160,21 +162,6 @@ export default {
|
|
|
160
162
|
return;
|
|
161
163
|
}
|
|
162
164
|
|
|
163
|
-
// we need this override as in a "closeOnSelect" type of component
|
|
164
|
-
// if we don't have this override, it would open again
|
|
165
|
-
if (this.overridesMixinPreventDoubleTriggerKeysOpen) {
|
|
166
|
-
this.$nextTick(() => {
|
|
167
|
-
const el = this.$refs['select'];
|
|
168
|
-
|
|
169
|
-
if ( el ) {
|
|
170
|
-
el.focus();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
this.overridesMixinPreventDoubleTriggerKeysOpen = false;
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
165
|
this.$refs['select-input'].open = true;
|
|
179
166
|
|
|
180
167
|
this.$nextTick(() => {
|
|
@@ -197,11 +184,13 @@ export default {
|
|
|
197
184
|
},
|
|
198
185
|
|
|
199
186
|
onOpen() {
|
|
187
|
+
this.isOpen = true;
|
|
200
188
|
this.$emit('on-open');
|
|
201
189
|
this.resizeHandler();
|
|
202
190
|
},
|
|
203
191
|
|
|
204
192
|
onClose() {
|
|
193
|
+
this.isOpen = false;
|
|
205
194
|
this.$emit('on-close');
|
|
206
195
|
},
|
|
207
196
|
|
|
@@ -279,6 +268,7 @@ export default {
|
|
|
279
268
|
|
|
280
269
|
<template>
|
|
281
270
|
<div
|
|
271
|
+
:id="hasLabel ? labeledSelectLabelId : undefined"
|
|
282
272
|
ref="select"
|
|
283
273
|
class="labeled-select"
|
|
284
274
|
:class="[
|
|
@@ -296,6 +286,10 @@ export default {
|
|
|
296
286
|
}
|
|
297
287
|
]"
|
|
298
288
|
:tabindex="isView || disabled ? -1 : 0"
|
|
289
|
+
role="combobox"
|
|
290
|
+
:aria-expanded="isOpen"
|
|
291
|
+
:aria-describedby="$attrs['aria-describedby'] || undefined"
|
|
292
|
+
:aria-required="requiredField"
|
|
299
293
|
@click="focusSearch"
|
|
300
294
|
@keydown.enter="focusSearch"
|
|
301
295
|
@keydown.down.prevent="focusSearch"
|
|
@@ -307,7 +301,7 @@ export default {
|
|
|
307
301
|
>
|
|
308
302
|
<label
|
|
309
303
|
v-if="hasLabel"
|
|
310
|
-
:
|
|
304
|
+
:for="labeledSelectLabelId"
|
|
311
305
|
>
|
|
312
306
|
<t
|
|
313
307
|
v-if="labelKey"
|
|
@@ -318,12 +312,12 @@ export default {
|
|
|
318
312
|
<span
|
|
319
313
|
v-if="requiredField"
|
|
320
314
|
class="required"
|
|
315
|
+
:aria-hidden="true"
|
|
321
316
|
>*</span>
|
|
322
317
|
</label>
|
|
323
318
|
</div>
|
|
324
319
|
<v-select
|
|
325
320
|
ref="select-input"
|
|
326
|
-
:aria-labelledby="hasLabel ? `labeled-select-uid-${uid}` : ''"
|
|
327
321
|
v-bind="filteredAttrs"
|
|
328
322
|
class="inline"
|
|
329
323
|
:append-to-body="appendToBody"
|
|
@@ -344,7 +338,8 @@ export default {
|
|
|
344
338
|
:modelValue="value != null && !loading ? value : ''"
|
|
345
339
|
:dropdown-should-open="dropdownShouldOpen"
|
|
346
340
|
:tabindex="-1"
|
|
347
|
-
|
|
341
|
+
:uid="generatedUid"
|
|
342
|
+
:aria-label="'-'"
|
|
348
343
|
@update:modelValue="$emit('selecting', $event); $emit('update:value', $event)"
|
|
349
344
|
@search:blur="onBlur"
|
|
350
345
|
@search:focus="onFocus"
|
|
@@ -353,6 +348,7 @@ export default {
|
|
|
353
348
|
@close="onClose"
|
|
354
349
|
@option:selecting="$emit('selecting', $event)"
|
|
355
350
|
@option:deselecting="$emit('deselecting', $event)"
|
|
351
|
+
@keydown.enter.stop
|
|
356
352
|
>
|
|
357
353
|
<template #option="option">
|
|
358
354
|
<template v-if="showTagPrompts">
|
|
@@ -374,7 +370,7 @@ export default {
|
|
|
374
370
|
</div>
|
|
375
371
|
</template>
|
|
376
372
|
<template v-else-if="option.kind === 'divider'">
|
|
377
|
-
<hr>
|
|
373
|
+
<hr role="none">
|
|
378
374
|
</template>
|
|
379
375
|
<template v-else-if="option.kind === 'highlighted'">
|
|
380
376
|
<div class="option-kind-highlighted">
|
|
@@ -24,10 +24,10 @@ export default {
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
data() {
|
|
27
|
-
const { postStart, preStop } = this.value;
|
|
28
|
-
|
|
29
27
|
return {
|
|
30
|
-
postStart
|
|
28
|
+
postStart: this.value.postStart,
|
|
29
|
+
preStop: this.value.preStop,
|
|
30
|
+
hookOptions: ['postStart', 'preStop']
|
|
31
31
|
};
|
|
32
32
|
},
|
|
33
33
|
|
|
@@ -70,6 +70,14 @@ export default {
|
|
|
70
70
|
},
|
|
71
71
|
|
|
72
72
|
data() {
|
|
73
|
+
return {
|
|
74
|
+
ops: [],
|
|
75
|
+
rules: [],
|
|
76
|
+
custom: []
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
created() {
|
|
73
81
|
const t = this.$store.getters['i18n/t'];
|
|
74
82
|
|
|
75
83
|
const podOptions = [
|
|
@@ -88,8 +96,6 @@ export default {
|
|
|
88
96
|
{ label: t('workload.scheduling.affinity.matchExpressions.greaterThan'), value: 'Gt' },
|
|
89
97
|
];
|
|
90
98
|
|
|
91
|
-
const ops = this.type === NODE ? nodeOptions : podOptions;
|
|
92
|
-
|
|
93
99
|
let rules;
|
|
94
100
|
|
|
95
101
|
// special case for matchFields and matchExpressions
|
|
@@ -127,11 +133,8 @@ export default {
|
|
|
127
133
|
rules.push(newRule);
|
|
128
134
|
}
|
|
129
135
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
rules,
|
|
133
|
-
custom: []
|
|
134
|
-
};
|
|
136
|
+
this.rules = rules;
|
|
137
|
+
this.ops = this.type === NODE ? nodeOptions : podOptions;
|
|
135
138
|
},
|
|
136
139
|
|
|
137
140
|
computed: {
|
|
@@ -210,7 +213,10 @@ export default {
|
|
|
210
213
|
update() {
|
|
211
214
|
this.$nextTick(() => {
|
|
212
215
|
const out = this.rules.map((rule) => {
|
|
213
|
-
const expression = {
|
|
216
|
+
const expression = {
|
|
217
|
+
key: rule.key.trim(),
|
|
218
|
+
operator: rule.operator
|
|
219
|
+
};
|
|
214
220
|
|
|
215
221
|
if (this.matchingSelectorDisplay) {
|
|
216
222
|
expression.matching = rule.matching;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {
|
|
2
|
+
import { computed, ref, toRef, watch } from 'vue';
|
|
3
|
+
import { mapActions, useStore } from 'vuex';
|
|
4
|
+
|
|
3
5
|
import { get, set } from '@shell/utils/object';
|
|
4
6
|
import { sortBy } from '@shell/utils/sort';
|
|
5
7
|
import { NAMESPACE } from '@shell/config/types';
|
|
@@ -8,6 +10,7 @@ import { _VIEW, _EDIT, _CREATE } from '@shell/config/query-params';
|
|
|
8
10
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
9
11
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
10
12
|
import { normalizeName } from '@shell/utils/kube';
|
|
13
|
+
import { useI18n } from '@shell/composables/useI18n';
|
|
11
14
|
|
|
12
15
|
export default {
|
|
13
16
|
name: 'NameNsDescription',
|
|
@@ -28,6 +31,10 @@ export default {
|
|
|
28
31
|
type: String,
|
|
29
32
|
required: true,
|
|
30
33
|
},
|
|
34
|
+
nameHidden: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
31
38
|
nameNsHidden: {
|
|
32
39
|
type: Boolean,
|
|
33
40
|
default: false,
|
|
@@ -169,81 +176,74 @@ export default {
|
|
|
169
176
|
},
|
|
170
177
|
|
|
171
178
|
data() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
let namespace, name, description;
|
|
179
|
+
return { createNamespace: false };
|
|
180
|
+
},
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
182
|
+
setup(props, { emit }) {
|
|
183
|
+
const v = toRef(props.value);
|
|
184
|
+
const metadata = v.value.metadata;
|
|
185
|
+
const namespace = ref(null);
|
|
186
|
+
const name = ref(null);
|
|
187
|
+
const description = ref(null);
|
|
181
188
|
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
this.updateNamespace(namespace);
|
|
186
|
-
} else if (this.namespaceKey) {
|
|
187
|
-
namespace = get(v, this.namespaceKey);
|
|
188
|
-
} else {
|
|
189
|
-
namespace = metadata?.namespace;
|
|
189
|
+
watch(name, (val) => {
|
|
190
|
+
if (props.normalizeName) {
|
|
191
|
+
val = normalizeName(val);
|
|
190
192
|
}
|
|
191
193
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
194
|
+
if (props.nameKey) {
|
|
195
|
+
set(props.value, props.nameKey, val);
|
|
196
|
+
} else {
|
|
197
|
+
props.value.metadata['name'] = val;
|
|
197
198
|
}
|
|
198
|
-
|
|
199
|
+
emit('update:value', props.value);
|
|
200
|
+
});
|
|
199
201
|
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
+
if (props.nameKey) {
|
|
203
|
+
name.value = get(v.value, props.nameKey);
|
|
202
204
|
} else {
|
|
203
|
-
|
|
205
|
+
name.value = metadata?.name || '';
|
|
204
206
|
}
|
|
205
207
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
+
const isCreate = computed(() => {
|
|
209
|
+
return props.mode === _CREATE;
|
|
210
|
+
});
|
|
208
211
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
nsSchema
|
|
215
|
-
};
|
|
216
|
-
},
|
|
212
|
+
const store = useStore();
|
|
213
|
+
const { t } = useI18n(store);
|
|
214
|
+
const allowedNamespaces = computed(() => store.getters.allowedNamespaces());
|
|
215
|
+
const storeNamespaces = computed(() => store.getters.namespaces());
|
|
216
|
+
const currentCluster = computed(() => store.getters.currentCluster);
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
namespaceReallyDisabled() {
|
|
222
|
-
return (
|
|
223
|
-
!!this.forceNamespace || this.namespaceDisabled || this.mode === _EDIT
|
|
224
|
-
); // namespace is never editable
|
|
225
|
-
},
|
|
218
|
+
const inStore = computed(() => {
|
|
219
|
+
return store.getters['currentStore']();
|
|
220
|
+
});
|
|
226
221
|
|
|
227
|
-
|
|
228
|
-
return
|
|
229
|
-
}
|
|
222
|
+
const nsSchema = computed(() => {
|
|
223
|
+
return store.getters[`${ inStore.value }/schemaFor`](NAMESPACE);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const canCreateNamespace = computed(() => {
|
|
227
|
+
// Check if user can push to namespaces... and as the ns is outside of a project restrict to admins and cluster owners
|
|
228
|
+
return (nsSchema.value?.collectionMethods || []).includes('POST') && currentCluster.value?.canUpdate;
|
|
229
|
+
});
|
|
230
230
|
|
|
231
231
|
/**
|
|
232
232
|
* Map namespaces from the store to options, adding divider and create button
|
|
233
233
|
*/
|
|
234
|
-
options() {
|
|
234
|
+
const options = computed(() => {
|
|
235
235
|
let namespaces;
|
|
236
236
|
|
|
237
|
-
if (
|
|
237
|
+
if (props.namespacesOverride) {
|
|
238
238
|
// Use the resources provided
|
|
239
|
-
namespaces =
|
|
239
|
+
namespaces = props.namespacesOverride;
|
|
240
240
|
} else {
|
|
241
|
-
if (
|
|
241
|
+
if (props.namespaceOptions) {
|
|
242
242
|
// Use the namespaces provided
|
|
243
|
-
namespaces = (
|
|
243
|
+
namespaces = (props.namespaceOptions.map((ns) => ns.name) || []).sort();
|
|
244
244
|
} else {
|
|
245
245
|
// Determine the namespaces
|
|
246
|
-
const namespaceObjs =
|
|
246
|
+
const namespaceObjs = isCreate.value ? allowedNamespaces.value : storeNamespaces.value;
|
|
247
247
|
|
|
248
248
|
namespaces = Object.keys(namespaceObjs);
|
|
249
249
|
}
|
|
@@ -251,22 +251,22 @@ export default {
|
|
|
251
251
|
|
|
252
252
|
const options = namespaces
|
|
253
253
|
.map((namespace) => ({ nameDisplay: namespace, id: namespace }))
|
|
254
|
-
.map(
|
|
254
|
+
.map(props.namespaceMapper || ((obj) => ({
|
|
255
255
|
label: obj.nameDisplay,
|
|
256
256
|
value: obj.id,
|
|
257
257
|
})));
|
|
258
258
|
|
|
259
259
|
const sortedByLabel = sortBy(options, 'label');
|
|
260
260
|
|
|
261
|
-
if (
|
|
261
|
+
if (props.forceNamespace) {
|
|
262
262
|
sortedByLabel.unshift({
|
|
263
|
-
label:
|
|
264
|
-
value:
|
|
263
|
+
label: props.forceNamespace,
|
|
264
|
+
value: props.forceNamespace,
|
|
265
265
|
});
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
const createButton = {
|
|
269
|
-
label:
|
|
269
|
+
label: t('namespace.createNamespace'),
|
|
270
270
|
value: '',
|
|
271
271
|
kind: 'highlighted'
|
|
272
272
|
};
|
|
@@ -276,20 +276,78 @@ export default {
|
|
|
276
276
|
kind: 'divider'
|
|
277
277
|
};
|
|
278
278
|
|
|
279
|
-
const createOverhead =
|
|
279
|
+
const createOverhead = canCreateNamespace.value || props.createNamespaceOverride ? [createButton, divider] : [];
|
|
280
280
|
|
|
281
281
|
return [
|
|
282
282
|
...createOverhead,
|
|
283
283
|
...sortedByLabel
|
|
284
284
|
];
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const updateNamespace = (val) => {
|
|
288
|
+
if (props.forceNamespace) {
|
|
289
|
+
val = props.forceNamespace;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (props.namespaced) {
|
|
293
|
+
emit('isNamespaceNew', !val || (options.value && !options.value.find((n) => n.value === val)));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (props.namespaceKey) {
|
|
297
|
+
set(props.value, props.namespaceKey, val);
|
|
298
|
+
} else {
|
|
299
|
+
props.value.metadata.namespace = val;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
if (props.namespaced) {
|
|
304
|
+
if (props.forceNamespace) {
|
|
305
|
+
namespace.value = toRef(props.forceNamespace);
|
|
306
|
+
updateNamespace(namespace);
|
|
307
|
+
} else if (props.namespaceKey) {
|
|
308
|
+
namespace.value = get(v, props.namespaceKey);
|
|
309
|
+
} else {
|
|
310
|
+
namespace.value = metadata?.namespace;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!namespace.value && !props.noDefaultNamespace) {
|
|
314
|
+
namespace.value = store.getters['defaultNamespace'];
|
|
315
|
+
if (metadata) {
|
|
316
|
+
metadata.namespace = namespace;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (props.descriptionKey) {
|
|
322
|
+
description.value = get(v, props.descriptionKey);
|
|
323
|
+
} else {
|
|
324
|
+
description.value = metadata?.annotations?.[DESCRIPTION];
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return {
|
|
328
|
+
namespace,
|
|
329
|
+
name,
|
|
330
|
+
description,
|
|
331
|
+
isCreate,
|
|
332
|
+
options,
|
|
333
|
+
updateNamespace,
|
|
334
|
+
};
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
computed: {
|
|
338
|
+
...mapActions('cru-resource', ['setCreateNamespace']),
|
|
339
|
+
namespaceReallyDisabled() {
|
|
340
|
+
return (
|
|
341
|
+
!!this.forceNamespace || this.namespaceDisabled || this.mode === _EDIT
|
|
342
|
+
); // namespace is never editable
|
|
285
343
|
},
|
|
286
344
|
|
|
287
|
-
|
|
288
|
-
return this.mode ===
|
|
345
|
+
nameReallyDisabled() {
|
|
346
|
+
return this.nameDisabled || (this.mode === _EDIT && !this.nameEditable);
|
|
289
347
|
},
|
|
290
348
|
|
|
291
|
-
|
|
292
|
-
return this.mode ===
|
|
349
|
+
isView() {
|
|
350
|
+
return this.mode === _VIEW;
|
|
293
351
|
},
|
|
294
352
|
|
|
295
353
|
showCustomize() {
|
|
@@ -308,27 +366,9 @@ export default {
|
|
|
308
366
|
|
|
309
367
|
return `span-${ span }`;
|
|
310
368
|
},
|
|
311
|
-
|
|
312
|
-
canCreateNamespace() {
|
|
313
|
-
// Check if user can push to namespaces... and as the ns is outside of a project restrict to admins and cluster owners
|
|
314
|
-
return (this.nsSchema?.collectionMethods || []).includes('POST') && this.currentCluster?.canUpdate;
|
|
315
|
-
}
|
|
316
369
|
},
|
|
317
370
|
|
|
318
371
|
watch: {
|
|
319
|
-
name(val) {
|
|
320
|
-
if (this.normalizeName) {
|
|
321
|
-
val = normalizeName(val);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (this.nameKey) {
|
|
325
|
-
set(this.value, this.nameKey, val);
|
|
326
|
-
} else {
|
|
327
|
-
this.value.metadata['name'] = val;
|
|
328
|
-
}
|
|
329
|
-
this.$emit('update:value', this.value);
|
|
330
|
-
},
|
|
331
|
-
|
|
332
372
|
namespace(val) {
|
|
333
373
|
this.updateNamespace(val);
|
|
334
374
|
this.$emit('update:value', this.value);
|
|
@@ -346,29 +386,13 @@ export default {
|
|
|
346
386
|
|
|
347
387
|
mounted() {
|
|
348
388
|
this.$nextTick(() => {
|
|
349
|
-
if (this.$refs.
|
|
350
|
-
this.$refs.
|
|
389
|
+
if (this.$refs.nameInput) {
|
|
390
|
+
this.$refs.nameInput.focus();
|
|
351
391
|
}
|
|
352
392
|
});
|
|
353
393
|
},
|
|
354
394
|
|
|
355
395
|
methods: {
|
|
356
|
-
updateNamespace(val) {
|
|
357
|
-
if (this.forceNamespace) {
|
|
358
|
-
val = this.forceNamespace;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (this.namespaced) {
|
|
362
|
-
this.$emit('isNamespaceNew', !val || (this.options && !this.options.find((n) => n.value === val)));
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
if (this.namespaceKey) {
|
|
366
|
-
set(this.value, this.namespaceKey, val);
|
|
367
|
-
} else {
|
|
368
|
-
this.value.metadata.namespace = val;
|
|
369
|
-
}
|
|
370
|
-
},
|
|
371
|
-
|
|
372
396
|
changeNameAndNamespace(e) {
|
|
373
397
|
this.name = (e.text || '').toLowerCase();
|
|
374
398
|
this.namespace = e.selected;
|
|
@@ -389,7 +413,7 @@ export default {
|
|
|
389
413
|
true,
|
|
390
414
|
);
|
|
391
415
|
this.$emit('isNamespaceNew', true);
|
|
392
|
-
this.$nextTick(() => this.$refs.
|
|
416
|
+
this.$nextTick(() => this.$refs.namespaceInput.focus());
|
|
393
417
|
} else {
|
|
394
418
|
this.createNamespace = false;
|
|
395
419
|
this.$store.dispatch(
|
|
@@ -411,7 +435,7 @@ export default {
|
|
|
411
435
|
class="col span-3"
|
|
412
436
|
>
|
|
413
437
|
<LabeledInput
|
|
414
|
-
ref="
|
|
438
|
+
ref="namespaceInput"
|
|
415
439
|
v-model:value="namespace"
|
|
416
440
|
:label="t('namespace.label')"
|
|
417
441
|
:placeholder="t('namespace.createNamespace')"
|
|
@@ -454,14 +478,15 @@ export default {
|
|
|
454
478
|
</div>
|
|
455
479
|
|
|
456
480
|
<div
|
|
457
|
-
v-if="!nameNsHidden"
|
|
481
|
+
v-if="!nameHidden && !nameNsHidden"
|
|
458
482
|
:data-testid="componentTestid + '-name'"
|
|
459
483
|
class="col span-3"
|
|
460
484
|
>
|
|
461
485
|
<LabeledInput
|
|
462
|
-
ref="
|
|
486
|
+
ref="nameInput"
|
|
463
487
|
key="name"
|
|
464
488
|
v-model:value="name"
|
|
489
|
+
data-testid="NameNsDescriptionNameInput"
|
|
465
490
|
:label="t(nameLabel)"
|
|
466
491
|
:placeholder="t(namePlaceholder)"
|
|
467
492
|
:disabled="nameReallyDisabled"
|
|
@@ -473,7 +498,6 @@ export default {
|
|
|
473
498
|
</div>
|
|
474
499
|
|
|
475
500
|
<slot name="customize" />
|
|
476
|
-
<!-- // TODO: here goes the custom component -->
|
|
477
501
|
<div
|
|
478
502
|
v-show="!descriptionHidden"
|
|
479
503
|
:data-testid="componentTestid + '-description'"
|