@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
|
@@ -29,6 +29,13 @@ export default {
|
|
|
29
29
|
default: NODE
|
|
30
30
|
},
|
|
31
31
|
|
|
32
|
+
// has select for matching fields or expressions (used for node affinity)
|
|
33
|
+
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#nodeselectorterm-v1-core
|
|
34
|
+
matchingSelectorDisplay: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
38
|
+
|
|
32
39
|
// whether or not to show an initial empty row of inputs when value is empty in editing modes
|
|
33
40
|
initialEmptyRow: {
|
|
34
41
|
type: Boolean,
|
|
@@ -83,28 +90,39 @@ export default {
|
|
|
83
90
|
|
|
84
91
|
let rules;
|
|
85
92
|
|
|
86
|
-
|
|
93
|
+
// special case for matchFields and matchExpressions
|
|
94
|
+
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#nodeselectorterm-v1-core
|
|
95
|
+
if ( this.matchingSelectorDisplay) {
|
|
96
|
+
const rulesByType = {
|
|
97
|
+
matchFields: [],
|
|
98
|
+
matchExpressions: []
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
['matchFields', 'matchExpressions'].forEach((type) => {
|
|
102
|
+
rulesByType[type] = this.parseRules(this.value[type], type);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
rules = [...rulesByType.matchFields, ...rulesByType.matchExpressions];
|
|
106
|
+
} else if ( isArray(this.value) ) {
|
|
87
107
|
rules = [...this.value];
|
|
108
|
+
rules = this.parseRules(rules);
|
|
88
109
|
} else {
|
|
89
110
|
rules = convert(this.value.matchLabels, this.value.matchExpressions);
|
|
111
|
+
rules = this.parseRules(rules);
|
|
90
112
|
}
|
|
91
113
|
|
|
92
|
-
rules = rules.map((rule) => {
|
|
93
|
-
const newRule = clone(rule);
|
|
94
|
-
|
|
95
|
-
if (newRule.values && typeof newRule.values !== 'string') {
|
|
96
|
-
newRule.values = newRule.values.join(', ');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return newRule;
|
|
100
|
-
});
|
|
101
|
-
|
|
102
114
|
if (!rules.length && this.initialEmptyRow && !this.isView) {
|
|
103
|
-
|
|
115
|
+
const newRule = {
|
|
104
116
|
key: '',
|
|
105
117
|
operator: 'In',
|
|
106
118
|
values: ''
|
|
107
|
-
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (this.matchingSelectorDisplay) {
|
|
122
|
+
newRule.matching = 'matchExpressions';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
rules.push(newRule);
|
|
108
126
|
}
|
|
109
127
|
|
|
110
128
|
return {
|
|
@@ -131,27 +149,71 @@ export default {
|
|
|
131
149
|
return !!this.keysSelectOptions?.length;
|
|
132
150
|
},
|
|
133
151
|
|
|
152
|
+
matchingSelectOptions() {
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
label: this.t('workload.scheduling.affinity.matchExpressions.label'),
|
|
156
|
+
value: 'matchExpressions',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
label: this.t('workload.scheduling.affinity.matchFields.label'),
|
|
160
|
+
value: 'matchFields',
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
},
|
|
164
|
+
|
|
134
165
|
...mapGetters({ t: 'i18n/t' })
|
|
135
166
|
},
|
|
136
167
|
|
|
137
168
|
methods: {
|
|
169
|
+
parseRules(rules, matching) {
|
|
170
|
+
if (rules?.length) {
|
|
171
|
+
return rules.map((rule) => {
|
|
172
|
+
const newRule = clone(rule);
|
|
173
|
+
|
|
174
|
+
if (newRule.values && typeof newRule.values !== 'string') {
|
|
175
|
+
newRule.values = newRule.values.join(', ');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (matching) {
|
|
179
|
+
newRule.matching = matching;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return newRule;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return [];
|
|
187
|
+
},
|
|
188
|
+
|
|
138
189
|
removeRule(row) {
|
|
139
190
|
removeObject(this.rules, row);
|
|
140
191
|
this.update();
|
|
141
192
|
},
|
|
142
193
|
|
|
143
194
|
addRule() {
|
|
144
|
-
|
|
195
|
+
const newRule = {
|
|
145
196
|
key: '',
|
|
146
197
|
operator: 'In',
|
|
147
198
|
values: ''
|
|
148
|
-
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
if (this.matchingSelectorDisplay) {
|
|
202
|
+
newRule.matching = 'matchExpressions';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this.rules.push(newRule);
|
|
149
206
|
},
|
|
150
207
|
|
|
151
208
|
update() {
|
|
152
209
|
this.$nextTick(() => {
|
|
153
210
|
const out = this.rules.map((rule) => {
|
|
154
|
-
const
|
|
211
|
+
const expression = { key: rule.key, operator: rule.operator };
|
|
212
|
+
|
|
213
|
+
if (this.matchingSelectorDisplay) {
|
|
214
|
+
expression.matching = rule.matching;
|
|
215
|
+
}
|
|
216
|
+
|
|
155
217
|
let val = (rule.values || '').trim();
|
|
156
218
|
|
|
157
219
|
if ( rule.operator === 'Exists' || rule.operator === 'DoesNotExist') {
|
|
@@ -161,13 +223,13 @@ export default {
|
|
|
161
223
|
}
|
|
162
224
|
|
|
163
225
|
if ( val !== null ) {
|
|
164
|
-
|
|
226
|
+
expression.values = val.split(/\s*,\s*/).filter(x => !!x);
|
|
165
227
|
}
|
|
166
228
|
|
|
167
|
-
return
|
|
229
|
+
return expression;
|
|
168
230
|
}).filter(x => !!x);
|
|
169
231
|
|
|
170
|
-
if ( isArray(this.value) ) {
|
|
232
|
+
if ( isArray(this.value) || this.matchingSelectorDisplay ) {
|
|
171
233
|
this.$emit('input', out);
|
|
172
234
|
} else {
|
|
173
235
|
this.$emit('input', simplify(out));
|
|
@@ -192,8 +254,11 @@ export default {
|
|
|
192
254
|
<div
|
|
193
255
|
v-if="rules.length"
|
|
194
256
|
class="match-expression-header"
|
|
195
|
-
:class="{'view':isView}"
|
|
257
|
+
:class="{ 'view':isView, 'match-expression-header-matching': matchingSelectorDisplay }"
|
|
196
258
|
>
|
|
259
|
+
<label v-if="matchingSelectorDisplay">
|
|
260
|
+
{{ t('workload.scheduling.affinity.matchExpressions.matchType') }}
|
|
261
|
+
</label>
|
|
197
262
|
<label>
|
|
198
263
|
{{ t('workload.scheduling.affinity.matchExpressions.key') }}
|
|
199
264
|
</label>
|
|
@@ -209,8 +274,25 @@ export default {
|
|
|
209
274
|
v-for="(row, index) in rules"
|
|
210
275
|
:key="row.id"
|
|
211
276
|
class="match-expression-row"
|
|
212
|
-
:class="{'view':isView, 'mb-10': index !== rules.length - 1}"
|
|
277
|
+
:class="{'view':isView, 'mb-10': index !== rules.length - 1, 'match-expression-row-matching': matchingSelectorDisplay}"
|
|
213
278
|
>
|
|
279
|
+
<!-- Select for matchFields and matchExpressions -->
|
|
280
|
+
<div
|
|
281
|
+
v-if="matchingSelectorDisplay"
|
|
282
|
+
:data-testid="`input-match-type-field-${index}`"
|
|
283
|
+
>
|
|
284
|
+
<div v-if="isView">
|
|
285
|
+
{{ row.matching }}
|
|
286
|
+
</div>
|
|
287
|
+
<LabeledSelect
|
|
288
|
+
v-else
|
|
289
|
+
v-model="row.matching"
|
|
290
|
+
:mode="mode"
|
|
291
|
+
:options="matchingSelectOptions"
|
|
292
|
+
:data-testid="`input-match-type-field-control-${index}`"
|
|
293
|
+
@selecting="update"
|
|
294
|
+
/>
|
|
295
|
+
</div>
|
|
214
296
|
<div
|
|
215
297
|
:data-testid="`input-match-expression-key-${index}`"
|
|
216
298
|
>
|
|
@@ -221,6 +303,7 @@ export default {
|
|
|
221
303
|
v-else-if="!hasKeySelectOptions"
|
|
222
304
|
v-model="row.key"
|
|
223
305
|
:mode="mode"
|
|
306
|
+
:data-testid="`input-match-expression-key-control-${index}`"
|
|
224
307
|
@input="update"
|
|
225
308
|
>
|
|
226
309
|
<LabeledSelect
|
|
@@ -228,6 +311,7 @@ export default {
|
|
|
228
311
|
v-model="row.key"
|
|
229
312
|
:mode="mode"
|
|
230
313
|
:options="keysSelectOptions"
|
|
314
|
+
:data-testid="`input-match-expression-key-control-select-${index}`"
|
|
231
315
|
/>
|
|
232
316
|
</div>
|
|
233
317
|
<div
|
|
@@ -244,6 +328,7 @@ export default {
|
|
|
244
328
|
:clearable="false"
|
|
245
329
|
:reduce="opt=>opt.value"
|
|
246
330
|
:mode="mode"
|
|
331
|
+
:data-testid="`input-match-expression-operator-control-${index}`"
|
|
247
332
|
@input="update"
|
|
248
333
|
/>
|
|
249
334
|
</div>
|
|
@@ -266,6 +351,7 @@ export default {
|
|
|
266
351
|
v-model="row.values"
|
|
267
352
|
:mode="mode"
|
|
268
353
|
:disabled="row.operator==='Exists' || row.operator==='DoesNotExist'"
|
|
354
|
+
:data-testid="`input-match-expression-values-control-${index}`"
|
|
269
355
|
@input="update"
|
|
270
356
|
>
|
|
271
357
|
</div>
|
|
@@ -280,6 +366,7 @@ export default {
|
|
|
280
366
|
:style="{padding:'0px'}"
|
|
281
367
|
|
|
282
368
|
:disabled="mode==='view'"
|
|
369
|
+
:data-testid="`input-match-expression-remove-control-${index}`"
|
|
283
370
|
@click="removeRule(row)"
|
|
284
371
|
>
|
|
285
372
|
<t k="generic.remove" />
|
|
@@ -293,6 +380,7 @@ export default {
|
|
|
293
380
|
<button
|
|
294
381
|
type="button"
|
|
295
382
|
class="btn role-tertiary add"
|
|
383
|
+
:data-testid="`input-match-expression-add-rule`"
|
|
296
384
|
@click="addRule"
|
|
297
385
|
>
|
|
298
386
|
<t k="workload.scheduling.affinity.matchExpressions.addRule" />
|
|
@@ -344,4 +432,15 @@ export default {
|
|
|
344
432
|
grid-template-columns: repeat(3, 1fr) 50px;
|
|
345
433
|
}
|
|
346
434
|
}
|
|
435
|
+
|
|
436
|
+
.match-expression-row > div > input {
|
|
437
|
+
min-height: 40px !important;
|
|
438
|
+
}
|
|
439
|
+
.match-expression-row-matching, .match-expression-header-matching {
|
|
440
|
+
grid-template-columns: 1fr 1fr 1fr 1fr;
|
|
441
|
+
|
|
442
|
+
&:not(.view){
|
|
443
|
+
grid-template-columns: 1fr 1fr 1fr 1fr 100px;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
347
446
|
</style>
|
|
@@ -6,12 +6,13 @@ import { get, isEmpty, clone } from '@shell/utils/object';
|
|
|
6
6
|
import { NODE } from '@shell/config/types';
|
|
7
7
|
import MatchExpressions from '@shell/components/form/MatchExpressions';
|
|
8
8
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
9
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
9
10
|
import { randomStr } from '@shell/utils/string';
|
|
10
11
|
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
11
12
|
|
|
12
13
|
export default {
|
|
13
14
|
components: {
|
|
14
|
-
ArrayListGrouped, MatchExpressions, LabeledSelect
|
|
15
|
+
ArrayListGrouped, MatchExpressions, LabeledSelect, LabeledInput
|
|
15
16
|
},
|
|
16
17
|
|
|
17
18
|
props: {
|
|
@@ -27,6 +28,13 @@ export default {
|
|
|
27
28
|
type: String,
|
|
28
29
|
default: 'create'
|
|
29
30
|
},
|
|
31
|
+
|
|
32
|
+
// has select for matching fields or expressions (used for node affinity)
|
|
33
|
+
// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#nodeselectorterm-v1-core
|
|
34
|
+
matchingSelectorDisplay: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
30
38
|
},
|
|
31
39
|
|
|
32
40
|
data() {
|
|
@@ -89,7 +97,7 @@ export default {
|
|
|
89
97
|
|
|
90
98
|
this.allSelectorTerms.forEach((term) => {
|
|
91
99
|
if (term.weight) {
|
|
92
|
-
const neu = { weight:
|
|
100
|
+
const neu = { weight: term.weight, preference: term };
|
|
93
101
|
|
|
94
102
|
preferredDuringSchedulingIgnoredDuringExecution.push(neu);
|
|
95
103
|
} else {
|
|
@@ -103,6 +111,7 @@ export default {
|
|
|
103
111
|
if (requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.length) {
|
|
104
112
|
out.requiredDuringSchedulingIgnoredDuringExecution = requiredDuringSchedulingIgnoredDuringExecution;
|
|
105
113
|
}
|
|
114
|
+
|
|
106
115
|
this.$emit('input', out);
|
|
107
116
|
},
|
|
108
117
|
|
|
@@ -124,6 +133,28 @@ export default {
|
|
|
124
133
|
return term.weight ? this.t('workload.scheduling.affinity.preferred') : this.t('workload.scheduling.affinity.required');
|
|
125
134
|
},
|
|
126
135
|
|
|
136
|
+
updateExpressions(row, expressions) {
|
|
137
|
+
const expressionsMatching = {
|
|
138
|
+
matchFields: [],
|
|
139
|
+
matchExpressions: []
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
if (expressions.length) {
|
|
143
|
+
expressions.forEach((expression) => {
|
|
144
|
+
expressionsMatching[expression.matching || 'matchExpressions'].push(expression);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (expressionsMatching.matchFields.length) {
|
|
148
|
+
this.$set(row, 'matchFields', expressionsMatching.matchFields);
|
|
149
|
+
}
|
|
150
|
+
if (expressionsMatching.matchExpressions.length) {
|
|
151
|
+
this.$set(row, 'matchExpressions', expressionsMatching.matchExpressions);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.update();
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
|
|
127
158
|
get,
|
|
128
159
|
|
|
129
160
|
isEmpty
|
|
@@ -148,23 +179,42 @@ export default {
|
|
|
148
179
|
>
|
|
149
180
|
<template #default="props">
|
|
150
181
|
<div class="row">
|
|
151
|
-
<div class="col span-
|
|
182
|
+
<div class="col span-9">
|
|
152
183
|
<LabeledSelect
|
|
153
184
|
:options="affinityOptions"
|
|
154
185
|
:value="priorityDisplay(props.row.value)"
|
|
155
186
|
:label="t('workload.scheduling.affinity.priority')"
|
|
156
187
|
:mode="mode"
|
|
188
|
+
:data-testid="`node-affinity-priority-index${props.i}`"
|
|
157
189
|
@input="(changePriority(props.row.value))"
|
|
158
190
|
/>
|
|
159
191
|
</div>
|
|
192
|
+
<div
|
|
193
|
+
v-if="props.row.value.weight"
|
|
194
|
+
class="col span-3"
|
|
195
|
+
>
|
|
196
|
+
<LabeledInput
|
|
197
|
+
v-model.number="props.row.value.weight"
|
|
198
|
+
:mode="mode"
|
|
199
|
+
type="number"
|
|
200
|
+
min="1"
|
|
201
|
+
max="100"
|
|
202
|
+
:label="t('workload.scheduling.affinity.weight.label')"
|
|
203
|
+
:placeholder="t('workload.scheduling.affinity.weight.placeholder')"
|
|
204
|
+
:data-testid="`node-affinity-weight-index${props.i}`"
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
160
207
|
</div>
|
|
161
208
|
<MatchExpressions
|
|
162
209
|
:key="rerenderNums"
|
|
163
|
-
|
|
210
|
+
:value="matchingSelectorDisplay ? props.row.value : props.row.value.matchExpressions"
|
|
211
|
+
:matching-selector-display="matchingSelectorDisplay"
|
|
164
212
|
:mode="mode"
|
|
165
213
|
class="col span-12 mt-20"
|
|
166
214
|
:type="node"
|
|
167
215
|
:show-remove="false"
|
|
216
|
+
:data-testid="`node-affinity-expressions-index${props.i}`"
|
|
217
|
+
@input="(updateExpressions(props.row.value, $event))"
|
|
168
218
|
/>
|
|
169
219
|
</template>
|
|
170
220
|
</ArrayListGrouped>
|
|
@@ -50,7 +50,7 @@ export default {
|
|
|
50
50
|
class="label"
|
|
51
51
|
>{{ label }} </span>
|
|
52
52
|
<button
|
|
53
|
-
v-tooltip="minusTooltip"
|
|
53
|
+
v-clean-tooltip="minusTooltip"
|
|
54
54
|
:disabled="disabled || !canMinus"
|
|
55
55
|
type="button"
|
|
56
56
|
class="btn btn-sm role-secondary"
|
|
@@ -62,7 +62,7 @@ export default {
|
|
|
62
62
|
{{ value }}
|
|
63
63
|
</div>
|
|
64
64
|
<button
|
|
65
|
-
v-tooltip="plusTooltip"
|
|
65
|
+
v-clean-tooltip="plusTooltip"
|
|
66
66
|
:disabled="disabled || !canPlus"
|
|
67
67
|
type="button"
|
|
68
68
|
class="btn btn-sm role-secondary"
|