@rancher/shell 0.3.8 → 0.3.10
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/translations/en-us.yaml +47 -26
- package/assets/translations/zh-hans.yaml +82 -16
- package/babel.config.js +17 -4
- package/chart/istio.vue +11 -11
- package/chart/rancher-backup/S3.vue +1 -1
- package/components/AsyncButton.vue +2 -2
- package/components/ButtonGroup.vue +1 -1
- package/components/CodeMirror.vue +146 -14
- package/components/CompoundStatusBadge.vue +1 -1
- package/components/ContainerResourceLimit.vue +14 -1
- package/components/CopyCode.vue +1 -1
- package/components/CruResource.vue +21 -5
- package/components/DetailTop.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +8 -4
- package/components/GlobalRoleBindings.vue +1 -1
- package/components/GroupPanel.vue +57 -0
- package/components/HarvesterServiceAddOnConfig.vue +2 -117
- package/components/ResourceDetail/Masthead.vue +1 -1
- package/components/ResourceList/Masthead.vue +0 -6
- package/components/ResourceList/ResourceLoadingIndicator.vue +1 -9
- package/components/ResourceList/index.vue +7 -6
- package/components/ResourceTable.vue +13 -3
- package/components/SortableTable/THead.vue +3 -3
- package/components/SortableTable/index.vue +3 -3
- package/components/Tabbed/Tab.vue +1 -1
- package/components/Tabbed/index.vue +1 -1
- package/components/Wizard.vue +9 -6
- package/components/YamlEditor.vue +2 -2
- package/components/__tests__/NamespaceFilter.test.ts +26 -7
- package/components/auth/RoleDetailEdit.vue +1 -1
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetRepos.vue +1 -1
- package/components/form/ArrayList.vue +2 -2
- package/components/form/KeyValue.vue +37 -3
- package/components/form/Labels.vue +34 -14
- package/components/form/MatchExpressions.vue +120 -21
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/NodeAffinity.vue +54 -4
- package/components/form/PlusMinus.vue +2 -2
- package/components/form/PodAffinity.vue +160 -47
- package/components/form/Probe.vue +1 -1
- package/components/form/ProjectMemberEditor.vue +8 -4
- package/components/form/ResourceQuota/NamespaceRow.vue +1 -1
- package/components/form/ServicePorts.vue +2 -2
- package/components/form/Tolerations.vue +70 -7
- package/components/form/WorkloadPorts.vue +2 -1
- package/components/form/__tests__/ArrayList.test.ts +3 -3
- package/components/form/__tests__/KeyValue.test.ts +17 -0
- package/components/form/__tests__/MatchExpressions.test.ts +1 -1
- package/components/formatter/ClusterLink.vue +3 -3
- package/components/formatter/LiveDate.vue +1 -1
- package/components/formatter/PodImages.vue +1 -1
- package/components/formatter/RKETemplateName.vue +1 -1
- package/components/formatter/Shortened.vue +1 -1
- package/components/nav/Header.vue +9 -7
- package/components/nav/NamespaceFilter.vue +103 -54
- package/config/labels-annotations.js +8 -5
- package/config/settings.ts +8 -6
- package/config/types.js +6 -4
- package/core/plugin-routes.ts +26 -7
- package/detail/provisioning.cattle.io.cluster.vue +4 -4
- package/edit/cis.cattle.io.clusterscan.vue +1 -1
- package/edit/configmap.vue +33 -6
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +19 -149
- package/edit/logging-flow/index.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +12 -0
- package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +12 -0
- package/edit/management.cattle.io.project.vue +7 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +11 -8
- package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +2 -2
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -4
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +140 -0
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +158 -0
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.ts +45 -0
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +326 -0
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +143 -169
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +75 -6
- package/edit/resources.cattle.io.restore.vue +2 -2
- package/edit/service.vue +22 -3
- package/edit/storage.k8s.io.storageclass/index.vue +1 -1
- package/edit/workload/Job.vue +2 -2
- package/edit/workload/index.vue +1 -1
- package/edit/workload/mixins/workload.js +7 -1
- package/edit/workload/storage/__tests__/Storage.test.ts +84 -5
- package/initialize/index.js +1 -0
- package/layouts/default.vue +1 -1
- package/mixins/chart.js +1 -1
- package/mixins/resource-fetch-namespaced.js +19 -27
- package/mixins/resource-fetch.js +0 -5
- package/models/__tests__/namespace.test.ts +125 -0
- package/models/batch.cronjob.js +18 -3
- package/models/management.cattle.io.project.js +6 -1
- package/models/persistentvolume.js +1 -1
- package/models/workload.js +1 -1
- package/models/workload.service.js +22 -7
- package/package.json +17 -6
- package/pages/auth/login.vue +47 -49
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +42 -51
- package/pages/c/_cluster/explorer/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +53 -18
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
- package/pages/c/_cluster/uiplugins/index.vue +16 -5
- package/pages/home.vue +1 -1
- package/pages/prefs.vue +18 -2
- package/plugins/clean-html-directive.js +1 -1
- package/plugins/clean-tooltip-directive.js +33 -0
- package/plugins/codemirror.js +158 -0
- package/plugins/dashboard-store/actions.js +4 -2
- package/plugins/dashboard-store/getters.js +6 -0
- package/plugins/dashboard-store/mutations.js +2 -2
- package/plugins/plugin.js +6 -1
- package/plugins/steve/actions.js +1 -1
- package/plugins/steve/getters.js +14 -3
- package/plugins/steve/resourceWatcher.js +36 -62
- package/plugins/steve/subscribe.js +137 -21
- package/plugins/steve/worker/index.js +7 -1
- package/plugins/steve/worker/web-worker.advanced.js +26 -8
- package/plugins/steve/worker/web-worker.basic.js +23 -4
- package/public/index.html +1 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -2
- package/rancher-components/components/Form/Radio/RadioGroup.vue +2 -2
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +1 -1
- package/store/index.js +16 -61
- package/store/store-types.js +5 -0
- package/store/type-map.js +1 -1
- package/types/shell/index.d.ts +42 -7
- package/utils/__tests__/create-yaml.test.ts +63 -0
- package/utils/array.ts +4 -0
- package/utils/create-yaml.js +105 -8
- package/utils/namespace-filter.js +17 -5
- package/utils/projectAndNamespaceFiltering.utils.ts +62 -0
- package/utils/selector.js +6 -5
- package/utils/settings.ts +17 -7
- package/vue.config.js +2 -2
- package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -93
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { KEYMAP } from '@shell/store/prefs';
|
|
3
|
+
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
name: 'CodeMirror',
|
|
6
7
|
props: {
|
|
8
|
+
/**
|
|
9
|
+
* Sets the edit mode for Text Area.
|
|
10
|
+
* @values _EDIT, _VIEW
|
|
11
|
+
*/
|
|
12
|
+
mode: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: _EDIT
|
|
15
|
+
},
|
|
7
16
|
value: {
|
|
8
17
|
type: String,
|
|
9
18
|
required: true,
|
|
@@ -11,14 +20,26 @@ export default {
|
|
|
11
20
|
options: {
|
|
12
21
|
type: Object,
|
|
13
22
|
default: () => {}
|
|
23
|
+
},
|
|
24
|
+
asTextArea: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: false
|
|
14
27
|
}
|
|
15
28
|
},
|
|
16
29
|
|
|
17
30
|
data() {
|
|
18
|
-
return {
|
|
31
|
+
return {
|
|
32
|
+
codeMirrorRef: null,
|
|
33
|
+
loaded: false
|
|
34
|
+
};
|
|
19
35
|
},
|
|
20
36
|
|
|
21
37
|
computed: {
|
|
38
|
+
|
|
39
|
+
isDisabled() {
|
|
40
|
+
return this.mode === _VIEW;
|
|
41
|
+
},
|
|
42
|
+
|
|
22
43
|
combinedOptions() {
|
|
23
44
|
const theme = this.$store.getters['prefs/theme'];
|
|
24
45
|
const keymap = this.$store.getters['prefs/get'](KEYMAP);
|
|
@@ -39,6 +60,12 @@ export default {
|
|
|
39
60
|
showCursorWhenSelecting: true,
|
|
40
61
|
};
|
|
41
62
|
|
|
63
|
+
if (this.asTextArea) {
|
|
64
|
+
out.lineNumbers = false;
|
|
65
|
+
out.tabSize = 0;
|
|
66
|
+
out.extraKeys = { Tab: false };
|
|
67
|
+
}
|
|
68
|
+
|
|
42
69
|
Object.assign(out, this.options);
|
|
43
70
|
|
|
44
71
|
return out;
|
|
@@ -58,35 +85,44 @@ export default {
|
|
|
58
85
|
methods: {
|
|
59
86
|
|
|
60
87
|
focus() {
|
|
61
|
-
if ( this.$refs.
|
|
62
|
-
this.$refs.
|
|
88
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
89
|
+
this.$refs.codeMirrorRef.codemirror.focus();
|
|
63
90
|
}
|
|
64
91
|
},
|
|
65
92
|
|
|
66
93
|
refresh() {
|
|
67
|
-
if ( this.$refs.
|
|
68
|
-
this.$refs.
|
|
94
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
95
|
+
this.$refs.codeMirrorRef.refresh();
|
|
69
96
|
}
|
|
70
97
|
},
|
|
71
98
|
|
|
72
|
-
onReady(
|
|
99
|
+
onReady(codeMirrorRef) {
|
|
73
100
|
this.$nextTick(() => {
|
|
74
|
-
|
|
101
|
+
codeMirrorRef.refresh();
|
|
102
|
+
this.codeMirrorRef = codeMirrorRef;
|
|
75
103
|
});
|
|
76
|
-
this.$emit('onReady',
|
|
104
|
+
this.$emit('onReady', codeMirrorRef);
|
|
77
105
|
},
|
|
78
106
|
|
|
79
107
|
onInput(newCode) {
|
|
80
108
|
this.$emit('onInput', newCode);
|
|
81
109
|
},
|
|
82
110
|
|
|
83
|
-
onChanges(
|
|
84
|
-
this.$emit('onChanges',
|
|
111
|
+
onChanges(codeMirrorRef, changes) {
|
|
112
|
+
this.$emit('onChanges', codeMirrorRef, changes);
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
onFocus() {
|
|
116
|
+
this.$emit('onFocus', true);
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
onBlur() {
|
|
120
|
+
this.$emit('onFocus', false);
|
|
85
121
|
},
|
|
86
122
|
|
|
87
123
|
updateValue(value) {
|
|
88
|
-
if ( this.$refs.
|
|
89
|
-
this.$refs.
|
|
124
|
+
if ( this.$refs.codeMirrorRef ) {
|
|
125
|
+
this.$refs.codeMirrorRef.codemirror.doc.setValue(value);
|
|
90
126
|
}
|
|
91
127
|
}
|
|
92
128
|
}
|
|
@@ -95,15 +131,21 @@ export default {
|
|
|
95
131
|
|
|
96
132
|
<template>
|
|
97
133
|
<client-only placeholder=" Loading...">
|
|
98
|
-
<div
|
|
134
|
+
<div
|
|
135
|
+
class="code-mirror"
|
|
136
|
+
:class="{['as-text-area']: asTextArea}"
|
|
137
|
+
>
|
|
99
138
|
<codemirror
|
|
100
139
|
v-if="loaded"
|
|
101
|
-
ref="
|
|
140
|
+
ref="codeMirrorRef"
|
|
102
141
|
:value="value"
|
|
103
142
|
:options="combinedOptions"
|
|
143
|
+
:disabled="isDisabled"
|
|
104
144
|
@ready="onReady"
|
|
105
145
|
@input="onInput"
|
|
106
146
|
@changes="onChanges"
|
|
147
|
+
@focus="onFocus"
|
|
148
|
+
@blur="onBlur"
|
|
107
149
|
/>
|
|
108
150
|
<div v-else>
|
|
109
151
|
Loading...
|
|
@@ -120,5 +162,95 @@ export default {
|
|
|
120
162
|
height: initial;
|
|
121
163
|
background: none
|
|
122
164
|
}
|
|
165
|
+
|
|
166
|
+
&.as-text-area {
|
|
167
|
+
min-height: 40px;
|
|
168
|
+
position: relative;
|
|
169
|
+
display: block;
|
|
170
|
+
box-sizing: border-box;
|
|
171
|
+
width: 100%;
|
|
172
|
+
padding: 10px;
|
|
173
|
+
background-color: var(--input-bg);
|
|
174
|
+
border-radius: var(--border-radius);
|
|
175
|
+
border: solid var(--border-width) var(--input-border);
|
|
176
|
+
color: var(--input-text);
|
|
177
|
+
|
|
178
|
+
&:hover {
|
|
179
|
+
border-color: var(--input-hover-border);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
&:focus, &.focus {
|
|
183
|
+
outline: none;
|
|
184
|
+
border-color: var(--outline);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.CodeMirror-wrap pre {
|
|
188
|
+
word-break: break-word;
|
|
189
|
+
}
|
|
190
|
+
.CodeMirror-code {
|
|
191
|
+
.CodeMirror-line {
|
|
192
|
+
&:not(:last-child)>span:after,
|
|
193
|
+
.cm-markdown-single-trailing-space-odd:before,
|
|
194
|
+
.cm-markdown-single-trailing-space-even:before {
|
|
195
|
+
color: var(--muted);
|
|
196
|
+
position: absolute;
|
|
197
|
+
line-height: 20px;
|
|
198
|
+
pointer-events: none;
|
|
199
|
+
}
|
|
200
|
+
&:not(:last-child)>span:after {
|
|
201
|
+
content: '↵';
|
|
202
|
+
margin-left: 2px;
|
|
203
|
+
}
|
|
204
|
+
.cm-markdown-single-trailing-space-odd:before,
|
|
205
|
+
.cm-markdown-single-trailing-space-even:before {
|
|
206
|
+
font-weight: bold;
|
|
207
|
+
content: '·';
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.CodeMirror-lines {
|
|
213
|
+
color: var(--input-text);
|
|
214
|
+
padding: 0;
|
|
215
|
+
|
|
216
|
+
.CodeMirror-line > span > span {
|
|
217
|
+
&.cm-overlay {
|
|
218
|
+
font-family: monospace;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.CodeMirror-line > span {
|
|
223
|
+
font-family: $body-font;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.CodeMirror-sizer {
|
|
228
|
+
min-height: 20px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.CodeMirror-selected {
|
|
232
|
+
background-color: var(--primary) !important;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.CodeMirror-selectedtext {
|
|
236
|
+
color: var(--primary-text);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.CodeMirror-line::selection,
|
|
240
|
+
.CodeMirror-line > span::selection,
|
|
241
|
+
.CodeMirror-line > span > span::selection {
|
|
242
|
+
color: var(--primary-text);
|
|
243
|
+
background-color: var(--primary);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.CodeMirror-line::-moz-selection,
|
|
247
|
+
.CodeMirror-line > span::-moz-selection,
|
|
248
|
+
.CodeMirror-line > span > span::-moz-selection {
|
|
249
|
+
color: var(--primary-text);
|
|
250
|
+
background-color: var(--primary);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
123
254
|
}
|
|
255
|
+
|
|
124
256
|
</style>
|
|
@@ -26,6 +26,11 @@ export default {
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
+
handleGpuLimit: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: true
|
|
32
|
+
},
|
|
33
|
+
|
|
29
34
|
registerBeforeHook: {
|
|
30
35
|
type: Function,
|
|
31
36
|
default: null
|
|
@@ -180,6 +185,7 @@ export default {
|
|
|
180
185
|
:input-exponent="-1"
|
|
181
186
|
:output-modifier="true"
|
|
182
187
|
:base-unit="t('suffix.cpus')"
|
|
188
|
+
data-testid="cpu-reservation"
|
|
183
189
|
@input="updateLimits"
|
|
184
190
|
/>
|
|
185
191
|
</span>
|
|
@@ -192,6 +198,7 @@ export default {
|
|
|
192
198
|
:input-exponent="2"
|
|
193
199
|
:increment="1024"
|
|
194
200
|
:output-modifier="true"
|
|
201
|
+
data-testid="memory-reservation"
|
|
195
202
|
@input="updateLimits"
|
|
196
203
|
/>
|
|
197
204
|
</span>
|
|
@@ -207,6 +214,7 @@ export default {
|
|
|
207
214
|
:input-exponent="-1"
|
|
208
215
|
:output-modifier="true"
|
|
209
216
|
:base-unit="t('suffix.cpus')"
|
|
217
|
+
data-testid="cpu-limit"
|
|
210
218
|
@input="updateLimits"
|
|
211
219
|
/>
|
|
212
220
|
</span>
|
|
@@ -219,11 +227,15 @@ export default {
|
|
|
219
227
|
:input-exponent="2"
|
|
220
228
|
:increment="1024"
|
|
221
229
|
:output-modifier="true"
|
|
230
|
+
data-testid="memory-limit"
|
|
222
231
|
@input="updateLimits"
|
|
223
232
|
/>
|
|
224
233
|
</span>
|
|
225
234
|
</div>
|
|
226
|
-
<div
|
|
235
|
+
<div
|
|
236
|
+
v-if="handleGpuLimit"
|
|
237
|
+
class="row"
|
|
238
|
+
>
|
|
227
239
|
<span class="col span-6">
|
|
228
240
|
<UnitInput
|
|
229
241
|
v-model="limitsGpu"
|
|
@@ -231,6 +243,7 @@ export default {
|
|
|
231
243
|
:label="t('containerResourceLimit.limitsGpu')"
|
|
232
244
|
:mode="mode"
|
|
233
245
|
:base-unit="t('suffix.gpus')"
|
|
246
|
+
data-testid="gpu-limit"
|
|
234
247
|
@input="updateLimits"
|
|
235
248
|
/>
|
|
236
249
|
</span>
|
package/components/CopyCode.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import {
|
|
3
|
+
import { createYamlWithOptions } from '@shell/utils/create-yaml';
|
|
4
4
|
import { clone, get } from '@shell/utils/object';
|
|
5
5
|
import { SCHEMA, NAMESPACE } from '@shell/config/types';
|
|
6
6
|
import ResourceYaml from '@shell/components/ResourceYaml';
|
|
@@ -101,6 +101,11 @@ export default {
|
|
|
101
101
|
default: null,
|
|
102
102
|
},
|
|
103
103
|
|
|
104
|
+
preventEnterSubmit: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
default: false,
|
|
107
|
+
},
|
|
108
|
+
|
|
104
109
|
applyHooks: {
|
|
105
110
|
type: Function,
|
|
106
111
|
default: null,
|
|
@@ -141,6 +146,11 @@ export default {
|
|
|
141
146
|
description: {
|
|
142
147
|
type: String,
|
|
143
148
|
default: ''
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
yamlModifiers: {
|
|
152
|
+
type: Object,
|
|
153
|
+
default: undefined
|
|
144
154
|
}
|
|
145
155
|
},
|
|
146
156
|
|
|
@@ -296,7 +306,7 @@ export default {
|
|
|
296
306
|
}
|
|
297
307
|
},
|
|
298
308
|
|
|
299
|
-
createResourceYaml() {
|
|
309
|
+
createResourceYaml(modifiers) {
|
|
300
310
|
const resource = this.resource;
|
|
301
311
|
|
|
302
312
|
if ( typeof this.generateYaml === 'function' ) {
|
|
@@ -306,7 +316,7 @@ export default {
|
|
|
306
316
|
const schemas = this.$store.getters[`${ inStore }/all`](SCHEMA);
|
|
307
317
|
const clonedResource = clone(resource);
|
|
308
318
|
|
|
309
|
-
const out =
|
|
319
|
+
const out = createYamlWithOptions(schemas, resource.type, clonedResource, modifiers);
|
|
310
320
|
|
|
311
321
|
return out;
|
|
312
322
|
}
|
|
@@ -317,7 +327,7 @@ export default {
|
|
|
317
327
|
await this.applyHooks(BEFORE_SAVE_HOOKS);
|
|
318
328
|
}
|
|
319
329
|
|
|
320
|
-
const resourceYaml = this.createResourceYaml();
|
|
330
|
+
const resourceYaml = this.createResourceYaml(this.yamlModifiers);
|
|
321
331
|
|
|
322
332
|
this.resourceYaml = resourceYaml;
|
|
323
333
|
this.showAsForm = false;
|
|
@@ -380,6 +390,12 @@ export default {
|
|
|
380
390
|
throw new Error(`Could not create the new namespace. ${ e.message }`);
|
|
381
391
|
}
|
|
382
392
|
}
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
onPressEnter(event) {
|
|
396
|
+
if (this.preventEnterSubmit) {
|
|
397
|
+
event.preventDefault();
|
|
398
|
+
}
|
|
383
399
|
}
|
|
384
400
|
}
|
|
385
401
|
};
|
|
@@ -398,7 +414,7 @@ export default {
|
|
|
398
414
|
:is="(isView? 'div' : 'form')"
|
|
399
415
|
class="create-resource-container cru__form"
|
|
400
416
|
@submit.prevent
|
|
401
|
-
@keydown.enter
|
|
417
|
+
@keydown.enter="onPressEnter($event)"
|
|
402
418
|
>
|
|
403
419
|
<div
|
|
404
420
|
v-if="hasErrors"
|
package/components/DetailTop.vue
CHANGED
|
@@ -252,7 +252,7 @@ export default {
|
|
|
252
252
|
/>
|
|
253
253
|
<span
|
|
254
254
|
v-if="internalTooltips[key]"
|
|
255
|
-
v-tooltip="prop ? `${key} : ${prop}` : key"
|
|
255
|
+
v-clean-tooltip="prop ? `${key} : ${prop}` : key"
|
|
256
256
|
>
|
|
257
257
|
<span>{{ internalTooltips[key] ? internalTooltips[key] : key }}</span>
|
|
258
258
|
<span v-if="showAllLabels">: {{ key }}</span>
|
|
@@ -11,6 +11,7 @@ import MoveModal from '@shell/components/MoveModal';
|
|
|
11
11
|
import { defaultTableSortGenerationFn } from '@shell/components/ResourceTable.vue';
|
|
12
12
|
import { NAMESPACE_FILTER_ALL_ORPHANS } from '@shell/utils/namespace-filter';
|
|
13
13
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
14
|
+
import DOMPurify from 'dompurify';
|
|
14
15
|
|
|
15
16
|
export default {
|
|
16
17
|
name: 'ListProjectNamespace',
|
|
@@ -319,7 +320,10 @@ export default {
|
|
|
319
320
|
const row = group.rows[0];
|
|
320
321
|
|
|
321
322
|
if (row.isFake) {
|
|
322
|
-
return
|
|
323
|
+
return DOMPurify.sanitize(
|
|
324
|
+
this.t('resourceTable.groupLabel.project', { name: row.project?.nameDisplay }, true),
|
|
325
|
+
{ ALLOWED_TAGS: ['span'] }
|
|
326
|
+
);
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
return row.groupByLabel;
|
|
@@ -447,12 +451,12 @@ export default {
|
|
|
447
451
|
</span>
|
|
448
452
|
<i
|
|
449
453
|
v-if="row.injectionEnabled"
|
|
450
|
-
v-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
|
|
454
|
+
v-clean-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
|
|
451
455
|
class="icon icon-istio ml-5"
|
|
452
456
|
/>
|
|
453
457
|
<i
|
|
454
458
|
v-if="row.hasSystemLabels"
|
|
455
|
-
v-tooltip="getPsaTooltip(row)"
|
|
459
|
+
v-clean-tooltip="getPsaTooltip(row)"
|
|
456
460
|
class="icon icon-lock ml-5"
|
|
457
461
|
/>
|
|
458
462
|
</div>
|
|
@@ -533,7 +537,7 @@ export default {
|
|
|
533
537
|
<style lang="scss">
|
|
534
538
|
.psa-tooltip {
|
|
535
539
|
// These could pop up a lot as the mouse moves around, keep them as small and unintrusive as possible
|
|
536
|
-
// (easier to test with v-tooltip="{ content: getPSA(row), autoHide: false, show: true }")
|
|
540
|
+
// (easier to test with v-clean-tooltip="{ content: getPSA(row), autoHide: false, show: true }")
|
|
537
541
|
margin: 3px 0;
|
|
538
542
|
padding: 0 8px 0 22px;
|
|
539
543
|
}
|
|
@@ -341,7 +341,7 @@ export default {
|
|
|
341
341
|
<span class="checkbox-label">{{ role.nameDisplay }}</span>
|
|
342
342
|
<i
|
|
343
343
|
v-if="!!assignOnlyRoles[role.id]"
|
|
344
|
-
v-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
344
|
+
v-clean-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
345
345
|
class="checkbox-info icon icon-info icon-lg"
|
|
346
346
|
/>
|
|
347
347
|
</div>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export default {
|
|
3
|
+
props: {
|
|
4
|
+
/**
|
|
5
|
+
* Label for the group
|
|
6
|
+
*/
|
|
7
|
+
label: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: null
|
|
10
|
+
},
|
|
11
|
+
/**
|
|
12
|
+
* The i18n key to use for the label
|
|
13
|
+
*/
|
|
14
|
+
labelKey: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: null
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
</script>
|
|
21
|
+
<template>
|
|
22
|
+
<div class="group-panel-outer">
|
|
23
|
+
<div class="group-panel">
|
|
24
|
+
<div class="group-panel-title">
|
|
25
|
+
<t
|
|
26
|
+
v-if="labelKey"
|
|
27
|
+
:k="labelKey"
|
|
28
|
+
/>
|
|
29
|
+
<template v-else-if="label">
|
|
30
|
+
{{ label }}
|
|
31
|
+
</template>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="group-panel-content">
|
|
34
|
+
<slot />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<style lang="scss" scoped>
|
|
41
|
+
.group-panel {
|
|
42
|
+
border: 1px solid var(--border);
|
|
43
|
+
border-radius: 5px;
|
|
44
|
+
padding: 10px;
|
|
45
|
+
position: relative;
|
|
46
|
+
margin-top: 10px;
|
|
47
|
+
.group-panel-title {
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: -7px;
|
|
50
|
+
background-color: var(--body-bg);
|
|
51
|
+
padding: 0 5px;
|
|
52
|
+
}
|
|
53
|
+
.group-panel-content {
|
|
54
|
+
position: relative;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
2
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
4
|
-
import { RadioGroup } from '@components/Form/Radio';
|
|
5
3
|
import { _CREATE } from '@shell/config/query-params';
|
|
6
4
|
import { get } from '@shell/utils/object';
|
|
7
5
|
import { HCI as HCI_LABELS_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
@@ -10,34 +8,10 @@ const HARVESTER_ADD_ON_CONFIG = [{
|
|
|
10
8
|
variableName: 'ipam',
|
|
11
9
|
key: HCI_LABELS_ANNOTATIONS.CLOUD_PROVIDER_IPAM,
|
|
12
10
|
default: 'dhcp'
|
|
13
|
-
}, {
|
|
14
|
-
variableName: 'healthcheckPort',
|
|
15
|
-
key: 'cloudprovider.harvesterhci.io/healthcheck-port',
|
|
16
|
-
default: '',
|
|
17
|
-
}, {
|
|
18
|
-
variableName: 'healthCheckSuccessThreshold',
|
|
19
|
-
key: 'cloudprovider.harvesterhci.io/healthcheck-success-threshold',
|
|
20
|
-
default: 1,
|
|
21
|
-
}, {
|
|
22
|
-
variableName: 'healthCheckFailureThreshold',
|
|
23
|
-
key: 'cloudprovider.harvesterhci.io/healthcheck-failure-threshold',
|
|
24
|
-
default: 3,
|
|
25
|
-
}, {
|
|
26
|
-
variableName: 'healthCheckPeriod',
|
|
27
|
-
key: 'cloudprovider.harvesterhci.io/healthcheck-periodseconds',
|
|
28
|
-
default: 5,
|
|
29
|
-
}, {
|
|
30
|
-
variableName: 'healthCheckTimeout',
|
|
31
|
-
key: 'cloudprovider.harvesterhci.io/healthcheck-timeoutseconds',
|
|
32
|
-
default: 3,
|
|
33
11
|
}];
|
|
34
12
|
|
|
35
13
|
export default {
|
|
36
|
-
components: {
|
|
37
|
-
LabeledInput,
|
|
38
|
-
LabeledSelect,
|
|
39
|
-
RadioGroup,
|
|
40
|
-
},
|
|
14
|
+
components: { LabeledSelect },
|
|
41
15
|
|
|
42
16
|
props: {
|
|
43
17
|
mode: {
|
|
@@ -71,10 +45,7 @@ export default {
|
|
|
71
45
|
harvesterAddOnConfig[c.variableName] = this.value.metadata.annotations[c.key] || c.default;
|
|
72
46
|
});
|
|
73
47
|
|
|
74
|
-
return {
|
|
75
|
-
...harvesterAddOnConfig,
|
|
76
|
-
healthCheckEnabled: !!harvesterAddOnConfig.healthcheckPort,
|
|
77
|
-
};
|
|
48
|
+
return { ...harvesterAddOnConfig };
|
|
78
49
|
},
|
|
79
50
|
|
|
80
51
|
computed: {
|
|
@@ -97,27 +68,9 @@ export default {
|
|
|
97
68
|
|
|
98
69
|
methods: {
|
|
99
70
|
willSave() {
|
|
100
|
-
const errors = [];
|
|
101
|
-
|
|
102
|
-
if (this.healthCheckEnabled && !this.healthcheckPort) {
|
|
103
|
-
errors.push(this.t('validation.required', { key: this.t('servicesPage.harvester.healthCheckPort.label') }, true));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (errors.length > 0) {
|
|
107
|
-
return Promise.reject(errors);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
71
|
HARVESTER_ADD_ON_CONFIG.forEach((c) => {
|
|
111
72
|
this.value.metadata.annotations[c.key] = String(get(this, c.variableName));
|
|
112
73
|
});
|
|
113
|
-
|
|
114
|
-
if (!this.healthCheckEnabled) {
|
|
115
|
-
delete this.value.metadata.annotations['cloudprovider.harvesterhci.io/healthcheck-port'];
|
|
116
|
-
delete this.value.metadata.annotations['cloudprovider.harvesterhci.io/healthcheck-success-threshold'];
|
|
117
|
-
delete this.value.metadata.annotations['cloudprovider.harvesterhci.io/healthcheck-failure-threshold'];
|
|
118
|
-
delete this.value.metadata.annotations['cloudprovider.harvesterhci.io/healthcheck-periodseconds'];
|
|
119
|
-
delete this.value.metadata.annotations['cloudprovider.harvesterhci.io/healthcheck-timeoutseconds'];
|
|
120
|
-
}
|
|
121
74
|
},
|
|
122
75
|
},
|
|
123
76
|
};
|
|
@@ -132,76 +85,8 @@ export default {
|
|
|
132
85
|
:mode="mode"
|
|
133
86
|
:options="ipamOptions"
|
|
134
87
|
:label="t('servicesPage.harvester.ipam.label')"
|
|
135
|
-
:disabled="mode === 'edit'"
|
|
136
88
|
/>
|
|
137
89
|
</div>
|
|
138
90
|
</div>
|
|
139
|
-
|
|
140
|
-
<div class="row mt-30">
|
|
141
|
-
<div class="col span-6">
|
|
142
|
-
<RadioGroup
|
|
143
|
-
v-model="healthCheckEnabled"
|
|
144
|
-
:mode="mode"
|
|
145
|
-
name="healthCheckEnabled"
|
|
146
|
-
:label="t('servicesPage.harvester.healthCheckEnabled.label')"
|
|
147
|
-
:labels="[t('generic.disabled'),t('generic.enabled')]"
|
|
148
|
-
:options="[false, true]"
|
|
149
|
-
/>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
152
|
-
<div v-if="healthCheckEnabled">
|
|
153
|
-
<div class="row mt-10">
|
|
154
|
-
<div
|
|
155
|
-
v-if="healthCheckEnabled"
|
|
156
|
-
class="col span-6"
|
|
157
|
-
>
|
|
158
|
-
<LabeledSelect
|
|
159
|
-
v-model="healthcheckPort"
|
|
160
|
-
:mode="mode"
|
|
161
|
-
:options="portOptions"
|
|
162
|
-
required
|
|
163
|
-
:label="t('servicesPage.harvester.healthCheckPort.label')"
|
|
164
|
-
/>
|
|
165
|
-
</div>
|
|
166
|
-
<div class="col span-6">
|
|
167
|
-
<LabeledInput
|
|
168
|
-
v-model="healthCheckSuccessThreshold"
|
|
169
|
-
:mode="mode"
|
|
170
|
-
type="number"
|
|
171
|
-
:label="t('servicesPage.harvester.healthCheckSuccessThreshold.label')"
|
|
172
|
-
:tooltip="t('servicesPage.harvester.healthCheckSuccessThreshold.description')"
|
|
173
|
-
/>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
<div class="row mt-10">
|
|
177
|
-
<div class="col span-6">
|
|
178
|
-
<LabeledInput
|
|
179
|
-
v-model="healthCheckFailureThreshold"
|
|
180
|
-
:mode="mode"
|
|
181
|
-
type="number"
|
|
182
|
-
:label="t('servicesPage.harvester.healthCheckFailureThreshold.label')"
|
|
183
|
-
:tooltip="t('servicesPage.harvester.healthCheckFailureThreshold.description')"
|
|
184
|
-
/>
|
|
185
|
-
</div>
|
|
186
|
-
<div class="col span-6">
|
|
187
|
-
<LabeledInput
|
|
188
|
-
v-model="healthCheckPeriod"
|
|
189
|
-
:mode="mode"
|
|
190
|
-
type="number"
|
|
191
|
-
:label="t('servicesPage.harvester.healthCheckPeriod.label')"
|
|
192
|
-
/>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
<div class="row mt-10">
|
|
196
|
-
<div class="col span-6">
|
|
197
|
-
<LabeledInput
|
|
198
|
-
v-model="healthCheckTimeout"
|
|
199
|
-
:mode="mode"
|
|
200
|
-
type="number"
|
|
201
|
-
:label="t('servicesPage.harvester.healthCheckTimeout.label')"
|
|
202
|
-
/>
|
|
203
|
-
</div>
|
|
204
|
-
</div>
|
|
205
|
-
</div>
|
|
206
91
|
</div>
|
|
207
92
|
</template>
|