@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.
Files changed (145) hide show
  1. package/assets/translations/en-us.yaml +47 -26
  2. package/assets/translations/zh-hans.yaml +82 -16
  3. package/babel.config.js +17 -4
  4. package/chart/istio.vue +11 -11
  5. package/chart/rancher-backup/S3.vue +1 -1
  6. package/components/AsyncButton.vue +2 -2
  7. package/components/ButtonGroup.vue +1 -1
  8. package/components/CodeMirror.vue +146 -14
  9. package/components/CompoundStatusBadge.vue +1 -1
  10. package/components/ContainerResourceLimit.vue +14 -1
  11. package/components/CopyCode.vue +1 -1
  12. package/components/CruResource.vue +21 -5
  13. package/components/DetailTop.vue +1 -1
  14. package/components/ExplorerProjectsNamespaces.vue +8 -4
  15. package/components/GlobalRoleBindings.vue +1 -1
  16. package/components/GroupPanel.vue +57 -0
  17. package/components/HarvesterServiceAddOnConfig.vue +2 -117
  18. package/components/ResourceDetail/Masthead.vue +1 -1
  19. package/components/ResourceList/Masthead.vue +0 -6
  20. package/components/ResourceList/ResourceLoadingIndicator.vue +1 -9
  21. package/components/ResourceList/index.vue +7 -6
  22. package/components/ResourceTable.vue +13 -3
  23. package/components/SortableTable/THead.vue +3 -3
  24. package/components/SortableTable/index.vue +3 -3
  25. package/components/Tabbed/Tab.vue +1 -1
  26. package/components/Tabbed/index.vue +1 -1
  27. package/components/Wizard.vue +9 -6
  28. package/components/YamlEditor.vue +2 -2
  29. package/components/__tests__/NamespaceFilter.test.ts +26 -7
  30. package/components/auth/RoleDetailEdit.vue +1 -1
  31. package/components/auth/SelectPrincipal.vue +1 -1
  32. package/components/fleet/FleetRepos.vue +1 -1
  33. package/components/form/ArrayList.vue +2 -2
  34. package/components/form/KeyValue.vue +37 -3
  35. package/components/form/Labels.vue +34 -14
  36. package/components/form/MatchExpressions.vue +120 -21
  37. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  38. package/components/form/NameNsDescription.vue +1 -1
  39. package/components/form/NodeAffinity.vue +54 -4
  40. package/components/form/PlusMinus.vue +2 -2
  41. package/components/form/PodAffinity.vue +160 -47
  42. package/components/form/Probe.vue +1 -1
  43. package/components/form/ProjectMemberEditor.vue +8 -4
  44. package/components/form/ResourceQuota/NamespaceRow.vue +1 -1
  45. package/components/form/ServicePorts.vue +2 -2
  46. package/components/form/Tolerations.vue +70 -7
  47. package/components/form/WorkloadPorts.vue +2 -1
  48. package/components/form/__tests__/ArrayList.test.ts +3 -3
  49. package/components/form/__tests__/KeyValue.test.ts +17 -0
  50. package/components/form/__tests__/MatchExpressions.test.ts +1 -1
  51. package/components/formatter/ClusterLink.vue +3 -3
  52. package/components/formatter/LiveDate.vue +1 -1
  53. package/components/formatter/PodImages.vue +1 -1
  54. package/components/formatter/RKETemplateName.vue +1 -1
  55. package/components/formatter/Shortened.vue +1 -1
  56. package/components/nav/Header.vue +9 -7
  57. package/components/nav/NamespaceFilter.vue +103 -54
  58. package/config/labels-annotations.js +8 -5
  59. package/config/settings.ts +8 -6
  60. package/config/types.js +6 -4
  61. package/core/plugin-routes.ts +26 -7
  62. package/detail/provisioning.cattle.io.cluster.vue +4 -4
  63. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  64. package/edit/configmap.vue +33 -6
  65. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +19 -149
  66. package/edit/logging-flow/index.vue +2 -2
  67. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +12 -0
  68. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +12 -0
  69. package/edit/management.cattle.io.project.vue +7 -0
  70. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  71. package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +2 -2
  72. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +11 -8
  73. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +2 -2
  74. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -4
  75. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +140 -0
  76. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +158 -0
  77. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.ts +45 -0
  78. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  79. package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +326 -0
  80. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +1 -1
  81. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -1
  82. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +2 -2
  83. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +143 -169
  84. package/edit/provisioning.cattle.io.cluster/index.vue +1 -0
  85. package/edit/provisioning.cattle.io.cluster/rke2.vue +75 -6
  86. package/edit/resources.cattle.io.restore.vue +2 -2
  87. package/edit/service.vue +22 -3
  88. package/edit/storage.k8s.io.storageclass/index.vue +1 -1
  89. package/edit/workload/Job.vue +2 -2
  90. package/edit/workload/index.vue +1 -1
  91. package/edit/workload/mixins/workload.js +7 -1
  92. package/edit/workload/storage/__tests__/Storage.test.ts +84 -5
  93. package/initialize/index.js +1 -0
  94. package/layouts/default.vue +1 -1
  95. package/mixins/chart.js +1 -1
  96. package/mixins/resource-fetch-namespaced.js +19 -27
  97. package/mixins/resource-fetch.js +0 -5
  98. package/models/__tests__/namespace.test.ts +125 -0
  99. package/models/batch.cronjob.js +18 -3
  100. package/models/management.cattle.io.project.js +6 -1
  101. package/models/persistentvolume.js +1 -1
  102. package/models/workload.js +1 -1
  103. package/models/workload.service.js +22 -7
  104. package/package.json +17 -6
  105. package/pages/auth/login.vue +47 -49
  106. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  107. package/pages/c/_cluster/apps/charts/install.vue +42 -51
  108. package/pages/c/_cluster/explorer/index.vue +1 -1
  109. package/pages/c/_cluster/monitoring/index.vue +1 -1
  110. package/pages/c/_cluster/settings/performance.vue +53 -18
  111. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  112. package/pages/c/_cluster/uiplugins/index.vue +16 -5
  113. package/pages/home.vue +1 -1
  114. package/pages/prefs.vue +18 -2
  115. package/plugins/clean-html-directive.js +1 -1
  116. package/plugins/clean-tooltip-directive.js +33 -0
  117. package/plugins/codemirror.js +158 -0
  118. package/plugins/dashboard-store/actions.js +4 -2
  119. package/plugins/dashboard-store/getters.js +6 -0
  120. package/plugins/dashboard-store/mutations.js +2 -2
  121. package/plugins/plugin.js +6 -1
  122. package/plugins/steve/actions.js +1 -1
  123. package/plugins/steve/getters.js +14 -3
  124. package/plugins/steve/resourceWatcher.js +36 -62
  125. package/plugins/steve/subscribe.js +137 -21
  126. package/plugins/steve/worker/index.js +7 -1
  127. package/plugins/steve/worker/web-worker.advanced.js +26 -8
  128. package/plugins/steve/worker/web-worker.basic.js +23 -4
  129. package/public/index.html +1 -1
  130. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -2
  131. package/rancher-components/components/Form/Radio/RadioGroup.vue +2 -2
  132. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +1 -1
  133. package/store/index.js +16 -61
  134. package/store/store-types.js +5 -0
  135. package/store/type-map.js +1 -1
  136. package/types/shell/index.d.ts +42 -7
  137. package/utils/__tests__/create-yaml.test.ts +63 -0
  138. package/utils/array.ts +4 -0
  139. package/utils/create-yaml.js +105 -8
  140. package/utils/namespace-filter.js +17 -5
  141. package/utils/projectAndNamespaceFiltering.utils.ts +62 -0
  142. package/utils/selector.js +6 -5
  143. package/utils/settings.ts +17 -7
  144. package/vue.config.js +2 -2
  145. 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 { loaded: false };
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.cm ) {
62
- this.$refs.cm.codemirror.focus();
88
+ if ( this.$refs.codeMirrorRef ) {
89
+ this.$refs.codeMirrorRef.codemirror.focus();
63
90
  }
64
91
  },
65
92
 
66
93
  refresh() {
67
- if ( this.$refs.cm ) {
68
- this.$refs.cm.refresh();
94
+ if ( this.$refs.codeMirrorRef ) {
95
+ this.$refs.codeMirrorRef.refresh();
69
96
  }
70
97
  },
71
98
 
72
- onReady(cm) {
99
+ onReady(codeMirrorRef) {
73
100
  this.$nextTick(() => {
74
- cm.refresh();
101
+ codeMirrorRef.refresh();
102
+ this.codeMirrorRef = codeMirrorRef;
75
103
  });
76
- this.$emit('onReady', cm);
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(cm, changes) {
84
- this.$emit('onChanges', cm, changes);
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.cm ) {
89
- this.$refs.cm.codemirror.doc.setValue(value);
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 class="code-mirror">
134
+ <div
135
+ class="code-mirror"
136
+ :class="{['as-text-area']: asTextArea}"
137
+ >
99
138
  <codemirror
100
139
  v-if="loaded"
101
- ref="cm"
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>
@@ -24,7 +24,7 @@ export default {
24
24
 
25
25
  <template>
26
26
  <div
27
- v-tooltip.bottom="tooltipText"
27
+ v-clean-tooltip.bottom="tooltipText"
28
28
  class="compound-cluster-badge"
29
29
  :class="`bg-${badgeClass}`"
30
30
  >
@@ -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 class="row">
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>
@@ -53,7 +53,7 @@ export default {
53
53
 
54
54
  <template>
55
55
  <code
56
- v-tooltip="tooltip"
56
+ v-clean-tooltip="tooltip"
57
57
  class="copy"
58
58
  @click.stop.prevent="clicked"
59
59
  ><slot /></code>
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import isEmpty from 'lodash/isEmpty';
3
- import { createYaml } from '@shell/utils/create-yaml';
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 = createYaml(schemas, resource.type, clonedResource);
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.prevent
417
+ @keydown.enter="onPressEnter($event)"
402
418
  >
403
419
  <div
404
420
  v-if="hasErrors"
@@ -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 this.t('resourceTable.groupLabel.project', { name: row.project?.nameDisplay }, true);
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>
@@ -434,7 +434,7 @@ export default {
434
434
  class="masthead-istio"
435
435
  >
436
436
  <i
437
- v-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
437
+ v-clean-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
438
438
  class="icon icon-sm icon-istio"
439
439
  />
440
440
  </span>