@rancher/shell 0.3.15 → 0.3.17

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 (155) hide show
  1. package/assets/images/wechat-qr-code.jpg +0 -0
  2. package/assets/translations/en-us.yaml +70 -15
  3. package/assets/translations/zh-hans.yaml +155 -33
  4. package/chart/__tests__/S3.test.ts +50 -0
  5. package/chart/rancher-backup/S3.vue +21 -0
  6. package/chart/rancher-backup/index.vue +4 -0
  7. package/cloud-credential/generic.vue +1 -1
  8. package/components/BannerGraphic.vue +1 -0
  9. package/components/CommunityLinks.vue +1 -0
  10. package/components/CruResource.vue +1 -1
  11. package/components/EmberPage.vue +1 -0
  12. package/components/FileDiff.vue +92 -85
  13. package/components/GrafanaDashboard.vue +7 -1
  14. package/components/ResourceDetail/index.vue +4 -12
  15. package/components/ResourceList/index.vue +1 -1
  16. package/components/ResourceTable.vue +50 -2
  17. package/components/SimpleBox.vue +1 -0
  18. package/components/SortableTable/index.vue +5 -1
  19. package/components/YamlEditor.vue +1 -0
  20. package/components/auth/RoleDetailEdit.vue +1 -0
  21. package/components/form/GitPicker.vue +1 -1
  22. package/components/form/NameNsDescription.vue +28 -12
  23. package/components/form/NodeAffinity.vue +2 -2
  24. package/components/form/PodAffinity.vue +8 -3
  25. package/components/form/ResourceTabs/index.vue +8 -2
  26. package/components/form/Select.vue +16 -0
  27. package/components/form/__tests__/NodeAffinity.test.ts +38 -0
  28. package/components/form/__tests__/PodAffinity.test.ts +46 -0
  29. package/components/formatter/ClusterLink.vue +8 -4
  30. package/components/formatter/ImageName.vue +23 -0
  31. package/components/formatter/PodImages.vue +7 -1
  32. package/components/formatter/__tests__/ClusterLink.test.ts +101 -0
  33. package/components/nav/Header.vue +2 -2
  34. package/config/__test__/home-links.test.ts +62 -0
  35. package/config/home-links.js +15 -3
  36. package/config/labels-annotations.js +5 -1
  37. package/config/product/auth.js +1 -1
  38. package/config/router.js +0 -9
  39. package/config/settings.ts +4 -0
  40. package/config/table-headers.js +6 -5
  41. package/config/uiplugins.js +50 -5
  42. package/core/plugin-helpers.js +20 -12
  43. package/core/plugin.ts +9 -0
  44. package/core/plugins.js +1 -1
  45. package/core/types-provisioning.ts +253 -0
  46. package/core/types.ts +17 -3
  47. package/detail/autoscaling.horizontalpodautoscaler/index.vue +50 -1
  48. package/detail/catalog.cattle.io.clusterrepo.vue +8 -1
  49. package/detail/node.vue +6 -6
  50. package/detail/pod.vue +2 -6
  51. package/detail/provisioning.cattle.io.cluster.vue +46 -7
  52. package/detail/workload/index.vue +9 -9
  53. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +62 -0
  54. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +56 -0
  55. package/edit/auth/github.vue +1 -0
  56. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +130 -0
  57. package/edit/autoscaling.horizontalpodautoscaler/index.vue +79 -0
  58. package/edit/fleet.cattle.io.gitrepo.vue +18 -1
  59. package/edit/monitoring.coreos.com.prometheusrule/index.vue +8 -3
  60. package/edit/namespace.vue +9 -1
  61. package/edit/networking.k8s.io.ingress/RulePath.vue +0 -2
  62. package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +1 -30
  63. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +79 -1
  64. package/edit/provisioning.cattle.io.cluster/index.vue +52 -0
  65. package/edit/provisioning.cattle.io.cluster/rke2.vue +330 -150
  66. package/edit/ui.cattle.io.navlink.vue +2 -1
  67. package/initialize/App.js +3 -13
  68. package/initialize/layouts.ts +26 -0
  69. package/list/provisioning.cattle.io.cluster.vue +8 -1
  70. package/middleware/authenticated.js +93 -5
  71. package/mixins/brand.js +39 -3
  72. package/mixins/child-hook.js +2 -2
  73. package/mixins/create-edit-view/impl.js +2 -2
  74. package/models/fleet.cattle.io.gitrepo.js +1 -0
  75. package/models/provisioning.cattle.io.cluster.js +9 -1
  76. package/package.json +3 -3
  77. package/pages/about.vue +8 -2
  78. package/pages/auth/login.vue +10 -0
  79. package/pages/auth/logout.vue +11 -3
  80. package/pages/auth/setup.vue +4 -0
  81. package/pages/c/_cluster/apps/charts/index.vue +5 -2
  82. package/pages/c/_cluster/apps/charts/install.vue +5 -0
  83. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  84. package/pages/c/_cluster/explorer/index.vue +1 -10
  85. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +177 -0
  86. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +19 -3
  87. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +90 -21
  88. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +107 -37
  89. package/pages/c/_cluster/uiplugins/index.vue +155 -44
  90. package/pages/docs/_doc.vue +9 -3
  91. package/pages/home.vue +10 -5
  92. package/pages/support/index.vue +10 -4
  93. package/pkg/auto-import.js +1 -1
  94. package/plugins/clean-tooltip-directive.js +1 -1
  95. package/plugins/dashboard-store/resource-class.js +35 -2
  96. package/plugins/plugin.js +9 -1
  97. package/plugins/steve/actions.js +22 -0
  98. package/rancher-components/BadgeState/BadgeState.vue +5 -1
  99. package/rancher-components/Banner/Banner.test.ts +51 -1
  100. package/rancher-components/Banner/Banner.vue +134 -53
  101. package/rancher-components/Card/Card.vue +24 -7
  102. package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
  103. package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
  104. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
  105. package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
  106. package/rancher-components/Form/Radio/RadioButton.vue +30 -13
  107. package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
  108. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
  109. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
  110. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
  111. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
  112. package/rancher-components/StringList/StringList.test.ts +453 -49
  113. package/rancher-components/StringList/StringList.vue +92 -58
  114. package/scripts/extension/publish +2 -2
  115. package/scripts/typegen.sh +1 -0
  116. package/server/server-middleware.js +4 -12
  117. package/store/index.js +13 -0
  118. package/store/prefs.js +0 -3
  119. package/store/type-map.js +17 -29
  120. package/types/shell/index.d.ts +243 -90
  121. package/utils/kube.js +9 -0
  122. package/utils/object.js +27 -0
  123. package/utils/settings.ts +2 -2
  124. package/vue.config.js +3 -2
  125. package/pages/safeMode.vue +0 -17
  126. package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
  127. package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
  128. package/rancher-components/components/BadgeState/index.ts +0 -1
  129. package/rancher-components/components/Banner/Banner.test.ts +0 -63
  130. package/rancher-components/components/Banner/Banner.vue +0 -244
  131. package/rancher-components/components/Banner/index.ts +0 -1
  132. package/rancher-components/components/Card/Card.vue +0 -167
  133. package/rancher-components/components/Card/index.ts +0 -1
  134. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
  135. package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -420
  136. package/rancher-components/components/Form/Checkbox/index.ts +0 -1
  137. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -23
  138. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -355
  139. package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
  140. package/rancher-components/components/Form/Radio/RadioButton.vue +0 -287
  141. package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -254
  142. package/rancher-components/components/Form/Radio/index.ts +0 -2
  143. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -170
  144. package/rancher-components/components/Form/TextArea/index.ts +0 -1
  145. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
  146. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -149
  147. package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
  148. package/rancher-components/components/Form/index.ts +0 -5
  149. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -151
  150. package/rancher-components/components/LabeledTooltip/index.ts +0 -1
  151. package/rancher-components/components/StringList/StringList.test.ts +0 -484
  152. package/rancher-components/components/StringList/StringList.vue +0 -611
  153. package/rancher-components/components/StringList/index.ts +0 -1
  154. /package/rancher-components/{components/Card → Card}/Card.test.ts +0 -0
  155. /package/rancher-components/{components/Form → Form}/Radio/RadioButton.test.ts +0 -0
@@ -30,9 +30,9 @@ const CLASS = {
30
30
  * Manage a list of strings
31
31
  */
32
32
  export default Vue.extend({
33
- components: { LabeledInput },
34
33
 
35
- name: 'StringList',
34
+ name: 'StringList',
35
+ components: { LabeledInput },
36
36
 
37
37
  props: {
38
38
  /**
@@ -85,11 +85,11 @@ export default Vue.extend({
85
85
  },
86
86
  data() {
87
87
  return {
88
- value: null as string | null,
89
- selected: null as string | null,
90
- isEditItem: null as string | null,
91
- isCreateItem: false,
92
- errors: { duplicate: false } as Record<Error, boolean>
88
+ value: null as string | null,
89
+ selected: null as string | null,
90
+ editedItem: null as string | null,
91
+ isCreateItem: false,
92
+ errors: { duplicate: false } as Record<Error, boolean>
93
93
  };
94
94
  },
95
95
 
@@ -100,8 +100,8 @@ export default Vue.extend({
100
100
  */
101
101
  errorMessagesArray(): string[] {
102
102
  return (Object.keys(this.errors) as Error[])
103
- .filter(f => !!(this.errors)[f])
104
- .map(k => this.errorMessages[k]);
103
+ .filter((f) => this.errors[f] && this.errorMessages[f])
104
+ .map((k) => this.errorMessages[k]);
105
105
  },
106
106
  },
107
107
 
@@ -113,23 +113,35 @@ export default Vue.extend({
113
113
  this.toggleEditMode(false);
114
114
  this.toggleCreateMode(false);
115
115
  },
116
+ value(val) {
117
+ this.$emit('type:item', val);
118
+ },
119
+ errors: {
120
+ handler(val) {
121
+ this.$emit('errors', val);
122
+ },
123
+ deep: true
124
+ }
116
125
  },
117
126
 
118
127
  methods: {
119
128
  onChange(value: string) {
120
129
  this.value = value;
121
- /**
122
- * Remove duplicate error when a new value is typed
123
- */
130
+
131
+ const items = [
132
+ ...this.items,
133
+ this.value
134
+ ];
135
+
124
136
  this.toggleError(
125
137
  'duplicate',
126
- false,
127
- this.isCreateItem ? INPUT.create : INPUT.edit,
138
+ hasDuplicatedStrings(items, this.caseSensitive),
139
+ this.isCreateItem ? INPUT.create : INPUT.edit
128
140
  );
129
141
  },
130
142
 
131
143
  onSelect(item: string) {
132
- if (this.isCreateItem || this.isEditItem === item) {
144
+ if (this.readonly || this.isCreateItem || this.editedItem === item) {
133
145
  return;
134
146
  }
135
147
  this.selected = item;
@@ -160,7 +172,7 @@ export default Vue.extend({
160
172
  },
161
173
 
162
174
  onClickEmptyBody() {
163
- if (!this.isCreateItem && !this.isEditItem) {
175
+ if (!this.isCreateItem && !this.editedItem) {
164
176
  this.toggleCreateMode(true);
165
177
  }
166
178
  },
@@ -176,38 +188,43 @@ export default Vue.extend({
176
188
 
177
189
  return;
178
190
  }
179
- if (this.isEditItem) {
191
+ if (this.editedItem) {
192
+ this.deleteAndSelectNext(this.editedItem);
180
193
  this.toggleEditMode(false);
181
194
 
182
195
  return;
183
196
  }
184
197
  if (this.selected) {
185
- const index = findStringIndex(this.items, this.selected, false);
198
+ this.deleteAndSelectNext(this.selected);
199
+ }
200
+ },
186
201
 
187
- if (index !== -1) {
188
- /**
189
- * Select the next item in the list when an item is to be deleted.
190
- */
191
- const item = (this.items[index + 1] || this.items[index - 1]);
202
+ deleteAndSelectNext(currItem: string) {
203
+ const index = findStringIndex(this.items, currItem, false);
204
+
205
+ if (index !== -1) {
206
+ /**
207
+ * Select the next item in the list.
208
+ */
209
+ const item = (this.items[index + 1] || this.items[index - 1]);
192
210
 
193
- this.onSelect(item);
194
- this.setFocus(item);
211
+ this.onSelect(item);
212
+ this.setFocus(item);
195
213
 
196
- this.deleteItem(this.items[index]);
197
- }
214
+ this.deleteItem(this.items[index]);
198
215
  }
199
216
  },
200
217
 
201
218
  setFocus(refId: string) {
202
- this.$nextTick(() => this.getElemByRef(refId)?.focus());
219
+ this.$nextTick(() => (this.getElemByRef(refId) as Vue & HTMLElement)?.focus());
203
220
  },
204
221
 
205
222
  /**
206
223
  * Move scrollbar when the selected item is over the top or bottom side of the box
207
224
  */
208
225
  moveScrollbar(arrow: Arrow, value?: number) {
209
- const box = this.getElemByRef(BOX);
210
- const item = this.getElemByRef(this.selected || '');
226
+ const box = this.getElemByRef(BOX) as HTMLElement;
227
+ const item = this.getElemByRef(this.selected || '') as HTMLElement;
211
228
 
212
229
  if (box && item && item.className.includes(CLASS.item)) {
213
230
  const boxRect = box.getClientRects()[0];
@@ -229,13 +246,14 @@ export default Vue.extend({
229
246
  */
230
247
  toggleError(type: Error, val: boolean, refId?: string) {
231
248
  this.errors[type] = val;
249
+
232
250
  if (refId) {
233
251
  this.toggleErrorClass(refId, val);
234
252
  }
235
253
  },
236
254
 
237
255
  toggleErrorClass(refId: string, val: boolean) {
238
- const input = this.getElemByRef(refId)?.$el;
256
+ const input = (this.getElemByRef(refId) as Vue)?.$el;
239
257
 
240
258
  if (input) {
241
259
  if (val) {
@@ -250,7 +268,11 @@ export default Vue.extend({
250
268
  * Show/Hide the input line to create new item
251
269
  */
252
270
  toggleCreateMode(show: boolean) {
271
+ if (this.readonly) {
272
+ return;
273
+ }
253
274
  if (show) {
275
+ this.toggleEditMode(false);
254
276
  this.value = '';
255
277
 
256
278
  this.isCreateItem = true;
@@ -268,31 +290,34 @@ export default Vue.extend({
268
290
  * Show/Hide the in-line editing to edit an existing item
269
291
  */
270
292
  toggleEditMode(show: boolean, item?: string) {
293
+ if (this.readonly) {
294
+ return;
295
+ }
271
296
  if (show) {
272
297
  this.toggleCreateMode(false);
273
- this.value = this.isEditItem;
298
+ this.value = this.editedItem;
274
299
 
275
- this.isEditItem = item || '';
300
+ this.editedItem = item || '';
276
301
  this.setFocus(INPUT.edit);
277
302
  } else {
278
303
  this.value = null;
279
304
  this.toggleError('duplicate', false);
280
305
  this.onSelectLeave();
281
306
 
282
- this.isEditItem = null;
307
+ this.editedItem = null;
283
308
  }
284
309
  },
285
310
 
286
311
  getElemByRef(id: string) {
287
312
  const ref = this.$refs[id];
288
313
 
289
- return (Array.isArray(ref) ? ref[0] : ref) as any;
314
+ return Array.isArray(ref) ? ref[0] : ref;
290
315
  },
291
316
 
292
317
  /**
293
318
  * Create a new item and insert in the items list
294
319
  */
295
- saveItem() {
320
+ saveItem(closeInput = true) {
296
321
  const value = this.value?.trim();
297
322
 
298
323
  if (value) {
@@ -301,21 +326,20 @@ export default Vue.extend({
301
326
  value,
302
327
  ];
303
328
 
304
- if (hasDuplicatedStrings(items, this.caseSensitive)) {
305
- this.toggleError('duplicate', true, INPUT.create);
306
-
307
- return;
329
+ if (!hasDuplicatedStrings(items, this.caseSensitive)) {
330
+ this.updateItems(items);
308
331
  }
332
+ }
309
333
 
310
- this.updateItems(items);
334
+ if (closeInput) {
335
+ this.toggleCreateMode(false);
311
336
  }
312
- this.toggleCreateMode(false);
313
337
  },
314
338
 
315
339
  /**
316
340
  * Update an existing item in the items list
317
341
  */
318
- updateItem(item: string) {
342
+ updateItem(item: string, closeInput = true) {
319
343
  const value = this.value?.trim();
320
344
 
321
345
  if (value) {
@@ -326,22 +350,21 @@ export default Vue.extend({
326
350
  items[index] = value;
327
351
  }
328
352
 
329
- if (hasDuplicatedStrings(items, this.caseSensitive)) {
330
- this.toggleError('duplicate', true, INPUT.edit);
331
-
332
- return;
353
+ if (!hasDuplicatedStrings(items, this.caseSensitive)) {
354
+ this.updateItems(items);
333
355
  }
356
+ }
334
357
 
335
- this.updateItems(items);
358
+ if (closeInput) {
359
+ this.toggleEditMode(false);
336
360
  }
337
- this.toggleEditMode(false);
338
361
  },
339
362
 
340
363
  /**
341
364
  * Remove an item from items list
342
365
  */
343
366
  deleteItem(item?: string) {
344
- const items = this.items.filter(f => f !== item);
367
+ const items = this.items.filter((f) => f !== item);
345
368
 
346
369
  this.updateItems(items);
347
370
  },
@@ -387,19 +410,20 @@ export default Vue.extend({
387
410
  @blur="onSelectLeave(item)"
388
411
  >
389
412
  <span
390
- v-if="!isEditItem || isEditItem !== item"
413
+ v-if="!editedItem || editedItem !== item"
391
414
  class="label static"
392
415
  >
393
416
  {{ item }}
394
417
  </span>
395
418
  <LabeledInput
396
- v-if="isEditItem && isEditItem === item"
419
+ v-if="editedItem && editedItem === item"
397
420
  ref="item-edit"
421
+ :data-testid="`item-edit-${item}`"
398
422
  class="edit-input static"
399
423
  :value="value != null ? value : item"
400
424
  @input="onChange($event)"
401
- @blur.prevent="toggleEditMode(false)"
402
- @keydown.native.enter="updateItem(item)"
425
+ @blur.prevent="updateItem(item)"
426
+ @keydown.native.enter="updateItem(item, !errors.duplicate)"
403
427
  />
404
428
  </div>
405
429
  <div
@@ -408,12 +432,14 @@ export default Vue.extend({
408
432
  >
409
433
  <LabeledInput
410
434
  ref="item-create"
435
+ data-testid="item-create"
411
436
  class="create-input static"
412
437
  type="text"
413
438
  :value="value"
414
439
  :placeholder="placeholder"
415
440
  @input="onChange($event)"
416
- @keydown.native.enter="saveItem"
441
+ @blur.prevent="saveItem"
442
+ @keydown.native.enter="saveItem(!errors.duplicate)"
417
443
  />
418
444
  </div>
419
445
  </div>
@@ -427,25 +453,32 @@ export default Vue.extend({
427
453
  class="action-buttons"
428
454
  >
429
455
  <button
456
+ data-testid="button-remove"
430
457
  class="btn btn-sm role-tertiary remove-button"
431
- :disabled="!selected && !isCreateItem && !isEditItem"
458
+ :disabled="!selected && !isCreateItem && !editedItem"
432
459
  @mousedown.prevent="onClickMinusButton"
433
460
  >
434
461
  <span class="icon icon-minus icon-sm" />
435
462
  </button>
436
463
  <button
464
+ data-testid="button-add"
437
465
  class="btn btn-sm role-tertiary add-button"
438
- :disabled="isCreateItem"
466
+ :disabled="isCreateItem || editedItem"
439
467
  @click.prevent="onClickPlusButton"
440
468
  >
441
469
  <span class="icon icon-plus icon-sm" />
442
470
  </button>
443
471
  </div>
444
472
  <div class="messages">
445
- <i v-if="errorMessagesArray.length > 0" class="icon icon-warning icon-lg" />
473
+ <i
474
+ v-if="errorMessagesArray.length > 0"
475
+ data-testid="i-warning-icon"
476
+ class="icon icon-warning icon-lg"
477
+ />
446
478
  <span
447
479
  v-for="(msg, idx) in errorMessagesArray"
448
480
  :key="idx"
481
+ :data-testid="`span-error-message-${msg}`"
449
482
  class="error"
450
483
  >
451
484
  {{ idx > 0 ? '; ' : '' }}
@@ -499,6 +532,7 @@ export default Vue.extend({
499
532
  width: auto;
500
533
  user-select: none;
501
534
  overflow: hidden;
535
+ white-space: no-wrap;
502
536
  text-overflow: ellipsis;
503
537
  padding-top: 1px;
504
538
  }
@@ -299,12 +299,12 @@ for d in pkg/*/ ; do
299
299
  fi
300
300
  done
301
301
 
302
- if [ -f ${ROOT_INDEX} ]; then
302
+ if [ -f ${ROOT_INDEX} ] && [ "${GITHUB_BUILD}" == "false" ]; then
303
303
  UPDATE="--merge ${ROOT_INDEX}"
304
304
  helm repo index ${ASSETS} ${UPDATE}
305
305
  fi
306
306
 
307
- if [ -f ${ASSETS}/index.yaml ]; then
307
+ if [ -f ${ASSETS}/index.yaml ] && ! [ -e "${ROOT_INDEX}" ]; then
308
308
  cp ${ASSETS}/index.yaml ${BASE_DIR}
309
309
  fi
310
310
 
@@ -18,6 +18,7 @@ ${BASE_DIR}/node_modules/.bin/tsc shell/utils/*.js --declaration --allowJs --emi
18
18
  ${BASE_DIR}/node_modules/.bin/tsc shell/config/query-params.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
19
19
  ${BASE_DIR}/node_modules/.bin/tsc shell/config/table-headers.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
20
20
  ${BASE_DIR}/node_modules/.bin/tsc shell/config/types.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
21
+ ${BASE_DIR}/node_modules/.bin/tsc shell/config/labels-annotations.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
21
22
 
22
23
  # store
23
24
  ${BASE_DIR}/node_modules/.bin/tsc shell/store/features.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/store > /dev/null
@@ -1,19 +1,11 @@
1
- import { URL } from 'url';
2
-
3
- export default function(req, res, next) {
4
- const parsed = new URL(req.url, 'https://localhost');
5
-
6
- if ( parsed.searchParams.has('spa') ) {
7
- res.spa = true;
8
- console.log('SPA mode enabled'); // eslint-disable-line no-console
9
- }
10
-
1
+ module.exports = function(req, res, next) {
11
2
  // We do this redirect so that /verify-auth can work with both standalone and
12
3
  // while dashboard is nested under ember.
13
4
  if (req.url.includes('/verify-auth') || req.url.includes('/verify-auth-azure')) {
14
5
  res.writeHead(301, { Location: req.url.replace(/verify-auth(-azure)?/, 'auth/verify') });
15
6
  res.end();
16
- }
17
7
 
8
+ return;
9
+ }
18
10
  next();
19
- }
11
+ };
package/store/index.js CHANGED
@@ -34,6 +34,7 @@ import { sortBy } from '@shell/utils/sort';
34
34
  import { addParam } from '@shell/utils/url';
35
35
  import semver from 'semver';
36
36
  import { STORE } from '@shell/store/store-types';
37
+ import { isDevBuild } from '@shell/utils/version';
37
38
 
38
39
  // Disables strict mode for all store instances to prevent warning about changing state outside of mutations
39
40
  // because it's more efficient to do that sometimes.
@@ -573,6 +574,18 @@ export const getters = {
573
574
  return state.targetRoute;
574
575
  },
575
576
 
577
+ releaseNotesUrl(state, getters) {
578
+ const version = getters['management/byId'](MANAGEMENT.SETTING, 'server-version')?.value;
579
+
580
+ const base = 'https://github.com/rancher/rancher/releases';
581
+
582
+ if (version && !isDevBuild(version)) {
583
+ return `${ base }/tag/${ version }`;
584
+ }
585
+
586
+ return `${ base }/latest`;
587
+ },
588
+
576
589
  ...gcGetters
577
590
  };
578
591
 
package/store/prefs.js CHANGED
@@ -111,9 +111,6 @@ export const _RKE1 = 'rke1';
111
111
  export const _RKE2 = 'rke2';
112
112
  export const PROVISIONER = create('provisioner', _RKE2, { options: [_RKE1, _RKE2] });
113
113
 
114
- // Promo for Cluster Tools feature on Cluster Dashboard page
115
- export const CLUSTER_TOOLS_TIP = create('hide-cluster-tools-tip', false, { parseJSON });
116
-
117
114
  // Promo for Pod Security Policies (PSPs) being deprecated on kube version 1.25 on Cluster Dashboard page
118
115
  export const PSP_DEPRECATION_BANNER = create('hide-psp-deprecation-banner', false, { parseJSON });
119
116
 
package/store/type-map.js CHANGED
@@ -151,8 +151,6 @@ import { sortBy } from '@shell/utils/sort';
151
151
  import { haveV1Monitoring, haveV2Monitoring } from '@shell/utils/monitoring';
152
152
  import { NEU_VECTOR_NAMESPACE } from '@shell/config/product/neuvector';
153
153
 
154
- import { ExtensionPoint, TableColumnLocation } from '@shell/core/types';
155
-
156
154
  export const NAMESPACED = 'namespaced';
157
155
  export const CLUSTER_LEVEL = 'cluster';
158
156
  export const BOTH = 'both';
@@ -229,33 +227,6 @@ export function DSL(store, product, module = 'type-map') {
229
227
  },
230
228
 
231
229
  headers(type, headers) {
232
- // gate it so that we prevent errors on older versions of dashboard
233
- if (store.$plugin?.getUIConfig) {
234
- const extensionCols = store.$plugin.getUIConfig(ExtensionPoint.TABLE_COL, TableColumnLocation.RESOURCE);
235
-
236
- // Try and insert the columns before the Age column, if that is the last column
237
- let insertPosition = headers.length;
238
-
239
- if (headers.length > 0) {
240
- const lastColumn = headers[headers.length - 1];
241
-
242
- if (lastColumn?.name === AGE.name) {
243
- insertPosition--;
244
- }
245
- }
246
-
247
- // adding extension defined cols to the correct header config
248
- extensionCols.forEach((col) => {
249
- if (col.locationConfig.resource) {
250
- col.locationConfig.resource.forEach((resource) => {
251
- if (resource && type === resource) {
252
- headers.splice(insertPosition, 0, col);
253
- }
254
- });
255
- }
256
- });
257
- }
258
-
259
230
  headers.forEach((header) => {
260
231
  // If on the client, then use the value getter if there is one
261
232
  if (header.getValue) {
@@ -782,6 +753,15 @@ export const getters = {
782
753
  };
783
754
  },
784
755
 
756
+ isVirtual(state, getters, rootState, rootGetters) {
757
+ return (name, product) => {
758
+ product = product || rootGetters['productId'];
759
+ const productVirtualTypes = state.virtualTypes[product] || [];
760
+
761
+ return productVirtualTypes.some((st) => st.name === name);
762
+ };
763
+ },
764
+
785
765
  getSpoofedInstances(state, getters, rootState, rootGetters) {
786
766
  return async(type, product) => {
787
767
  product = product || rootGetters['productId'];
@@ -1390,6 +1370,14 @@ export const getters = {
1390
1370
  return _rowValueGetter(col);
1391
1371
  };
1392
1372
  },
1373
+
1374
+ isProductRegistered(state) {
1375
+ return (productName) => {
1376
+ const prod = state.products.find((p) => p.name === productName);
1377
+
1378
+ return !!prod;
1379
+ };
1380
+ },
1393
1381
  };
1394
1382
 
1395
1383
  export const mutations = {