@rancher/shell 3.0.8 → 3.0.9-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/apis/intf/modal.ts +38 -0
  2. package/apis/intf/slide-in.ts +3 -1
  3. package/apis/shell/__tests__/slide-in.test.ts +36 -0
  4. package/apis/shell/slide-in.ts +5 -1
  5. package/assets/styles/base/_color.scss +1 -0
  6. package/assets/styles/base/_typography.scss +14 -5
  7. package/assets/styles/themes/_light.scss +1 -1
  8. package/assets/styles/themes/_modern.scss +1 -1
  9. package/assets/translations/en-us.yaml +94 -33
  10. package/assets/translations/zh-hans.yaml +0 -2
  11. package/components/ActionMenuShell.vue +4 -4
  12. package/components/CodeMirror.vue +4 -3
  13. package/components/DetailText.vue +54 -7
  14. package/components/Drawer/Chrome.vue +11 -4
  15. package/components/Drawer/DrawerCard.vue +19 -0
  16. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +3 -11
  17. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +2 -2
  18. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -20
  19. package/components/Drawer/types.ts +1 -0
  20. package/components/DynamicContent/DynamicContentCloseButton.vue +2 -2
  21. package/components/LocaleSelector.vue +1 -1
  22. package/components/Markdown.vue +1 -1
  23. package/components/PopoverCard.vue +3 -3
  24. package/components/Resource/Detail/Card/ExtrasCard.vue +39 -0
  25. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +142 -0
  26. package/components/Resource/Detail/Card/StateCard/composables.ts +41 -11
  27. package/components/Resource/Detail/Card/StateCard/index.vue +3 -9
  28. package/components/Resource/Detail/Card/StateCard/types.ts +6 -0
  29. package/components/Resource/Detail/Card/{PodsCard → StatusCard}/index.vue +11 -10
  30. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +24 -25
  31. package/components/Resource/Detail/Cards.vue +27 -0
  32. package/components/Resource/Detail/Masthead/__tests__/index.test.ts +70 -0
  33. package/components/Resource/Detail/Masthead/index.vue +5 -0
  34. package/components/Resource/Detail/Metadata/KeyValueRow.vue +4 -2
  35. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -2
  36. package/components/Resource/Detail/ResourceRow.types.ts +14 -0
  37. package/components/Resource/Detail/ResourceRow.vue +23 -35
  38. package/components/Resource/Detail/StatusRow.vue +5 -2
  39. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +38 -7
  40. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +106 -2
  41. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  42. package/components/Resource/Detail/TitleBar/index.vue +41 -6
  43. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +49 -1
  44. package/components/ResourceDetail/Masthead/__tests__/latest.test.ts +85 -0
  45. package/components/ResourceDetail/Masthead/index.vue +1 -0
  46. package/components/ResourceDetail/Masthead/latest.vue +8 -1
  47. package/components/ResourceDetail/Masthead/legacy.vue +1 -1
  48. package/components/Setting.vue +1 -1
  49. package/components/SortableTable/index.vue +25 -0
  50. package/components/SortableTable/selection.js +25 -12
  51. package/components/SortableTable/sorting.js +1 -1
  52. package/components/Tabbed/Tab.vue +1 -0
  53. package/components/Tabbed/index.vue +29 -6
  54. package/components/Window/ContainerShell.vue +10 -13
  55. package/components/fleet/FleetClusterTargets/TargetsList.vue +47 -29
  56. package/components/fleet/FleetClusterTargets/index.vue +82 -29
  57. package/components/fleet/FleetClusters.vue +26 -12
  58. package/components/fleet/FleetGitRepoPaths.vue +2 -2
  59. package/components/fleet/FleetResources.vue +14 -0
  60. package/components/fleet/FleetValuesFrom.vue +2 -2
  61. package/components/fleet/__tests__/FleetClusterTargets.test.ts +531 -0
  62. package/components/fleet/__tests__/FleetClusters.test.ts +576 -0
  63. package/components/fleet/dashboard/ResourceDetails.vue +96 -123
  64. package/components/form/Conditions.vue +1 -15
  65. package/components/form/HookOption.vue +5 -0
  66. package/components/form/LabeledSelect.vue +1 -1
  67. package/components/form/LifecycleHooks.vue +2 -6
  68. package/components/form/ResourceLabeledSelect.vue +12 -1
  69. package/components/form/SeccompProfile.vue +113 -0
  70. package/components/form/Security.vue +244 -133
  71. package/components/form/__tests__/LabeledSelect.test.ts +1 -1
  72. package/components/form/__tests__/SeccompProfile.test.js +124 -0
  73. package/components/form/__tests__/Security.test.ts +125 -37
  74. package/components/formatter/Autoscaler.vue +2 -2
  75. package/components/formatter/FleetSummaryGraph.vue +4 -1
  76. package/components/nav/Group.vue +5 -0
  77. package/components/nav/Header.vue +3 -3
  78. package/components/nav/HeaderPageActionMenu.vue +1 -1
  79. package/components/nav/NamespaceFilter.vue +6 -6
  80. package/components/nav/NotificationCenter/index.vue +1 -1
  81. package/components/nav/TopLevelMenu.helper.ts +41 -16
  82. package/components/nav/TopLevelMenu.vue +45 -25
  83. package/components/nav/WorkspaceSwitcher.vue +1 -1
  84. package/components/nav/__tests__/TopLevelMenu.helper.test.ts +277 -0
  85. package/components/nav/__tests__/TopLevelMenu.test.ts +160 -4
  86. package/components/templates/default.vue +0 -3
  87. package/components/templates/home.vue +0 -3
  88. package/components/templates/plain.vue +0 -3
  89. package/composables/useClickOutside.ts +1 -1
  90. package/config/product/explorer.js +1 -2
  91. package/config/types.js +41 -8
  92. package/detail/__tests__/workload.test.ts +8 -16
  93. package/detail/catalog.cattle.io.app.vue +6 -0
  94. package/detail/fleet.cattle.io.cluster.vue +6 -0
  95. package/detail/workload/index.vue +7 -109
  96. package/edit/__tests__/projectsecret.test.ts +42 -0
  97. package/edit/auth/__tests__/oidc.test.ts +50 -0
  98. package/edit/auth/oidc.vue +68 -44
  99. package/edit/autoscaling.horizontalpodautoscaler/index.vue +140 -59
  100. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +41 -5
  101. package/edit/projectsecret.vue +29 -0
  102. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +89 -200
  103. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +58 -17
  104. package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -0
  105. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +3 -63
  106. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +82 -14
  107. package/edit/workload/__tests__/index.test.ts +122 -85
  108. package/edit/workload/index.vue +48 -29
  109. package/edit/workload/mixins/workload.js +85 -32
  110. package/list/catalog.cattle.io.clusterrepo.vue +1 -1
  111. package/list/projectsecret.vue +2 -2
  112. package/machine-config/__tests__/vmwarevsphere.test.ts +64 -0
  113. package/machine-config/amazonec2.vue +2 -2
  114. package/machine-config/vmwarevsphere.vue +58 -4
  115. package/mixins/__tests__/brand.spec.ts +18 -13
  116. package/mixins/__tests__/chart.test.ts +63 -0
  117. package/mixins/chart.js +56 -51
  118. package/models/__tests__/catalog.cattle.io.app.test.ts +33 -0
  119. package/models/__tests__/workload.test.ts +333 -0
  120. package/models/catalog.cattle.io.app.js +8 -0
  121. package/models/pod.js +14 -0
  122. package/models/secret.js +1 -1
  123. package/models/workload.js +93 -27
  124. package/package.json +4 -4
  125. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +91 -0
  126. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  127. package/pages/c/_cluster/explorer/EventsTable.vue +2 -2
  128. package/pages/c/_cluster/fleet/index.vue +18 -12
  129. package/pages/c/_cluster/manager/hostedprovider/index.vue +1 -19
  130. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  131. package/pages/c/_cluster/uiplugins/index.vue +1 -1
  132. package/plugins/dashboard-store/__tests__/resource-class.test.ts +234 -0
  133. package/plugins/dashboard-store/actions.js +9 -8
  134. package/plugins/dashboard-store/resource-class.js +97 -1
  135. package/plugins/steve/__tests__/revision.test.ts +84 -0
  136. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +30 -0
  137. package/plugins/steve/__tests__/subscribe.spec.ts +134 -0
  138. package/plugins/steve/mutations.js +9 -0
  139. package/plugins/steve/revision.ts +26 -0
  140. package/plugins/steve/steve-pagination-utils.ts +6 -5
  141. package/plugins/steve/subscribe.js +211 -51
  142. package/plugins/subscribe-events.ts +2 -2
  143. package/rancher-components/Form/Checkbox/Checkbox.vue +13 -0
  144. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -1
  145. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +1 -1
  146. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +3 -1
  147. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -1
  148. package/rancher-components/Pill/RcTag/RcTag.vue +1 -1
  149. package/rancher-components/Pill/index.ts +4 -0
  150. package/rancher-components/RcButton/RcButton.test.ts +53 -9
  151. package/rancher-components/RcButton/RcButton.vue +217 -25
  152. package/rancher-components/RcButton/types.ts +27 -1
  153. package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -4
  154. package/rancher-components/RcDropdown/types.ts +3 -3
  155. package/rancher-components/RcIcon/RcIcon.test.ts +42 -0
  156. package/rancher-components/RcIcon/RcIcon.vue +9 -6
  157. package/rancher-components/RcIcon/types.ts +13 -9
  158. package/rancher-components/utils/status.test.ts +10 -15
  159. package/rancher-components/utils/status.ts +5 -6
  160. package/store/aws.js +18 -12
  161. package/store/index.js +4 -8
  162. package/store/type-map.utils.ts +1 -1
  163. package/types/kube/kube-api.ts +29 -3
  164. package/types/rancher/steve.api.ts +40 -0
  165. package/types/shell/index.d.ts +99 -0
  166. package/types/store/dashboard-store.types.ts +29 -7
  167. package/types/store/pagination.types.ts +1 -0
  168. package/types/store/subscribe-events.types.ts +1 -0
  169. package/utils/__tests__/azure.test.ts +56 -0
  170. package/utils/__tests__/back-off.test.ts +364 -245
  171. package/utils/__tests__/error.test.ts +44 -0
  172. package/utils/__tests__/fleet.test.ts +8 -1
  173. package/utils/__tests__/pagination-wrapper.test.ts +167 -0
  174. package/utils/__tests__/version.test.ts +55 -1
  175. package/utils/azure.js +12 -0
  176. package/utils/back-off.ts +302 -69
  177. package/utils/cspAdaptor.ts +32 -14
  178. package/utils/dynamic-content/__tests__/index.test.ts +1 -1
  179. package/utils/dynamic-content/__tests__/new-release.test.ts +48 -7
  180. package/utils/dynamic-content/__tests__/support-notice.test.ts +1 -4
  181. package/utils/dynamic-content/index.ts +1 -6
  182. package/utils/dynamic-content/new-release.ts +5 -3
  183. package/utils/dynamic-content/types.d.ts +0 -1
  184. package/utils/error.js +9 -0
  185. package/utils/fleet.ts +2 -2
  186. package/utils/inactivity.ts +2 -3
  187. package/utils/pagination-wrapper.ts +101 -17
  188. package/utils/validators/formRules/index.ts +3 -0
  189. package/utils/version.js +38 -0
  190. package/components/auth/AzureWarning.vue +0 -77
  191. /package/components/Resource/Detail/{Card/PodsCard/Bubble.vue → Bubble.vue} +0 -0
  192. /package/components/Resource/Detail/Card/{PodsCard → StatusCard}/composable.ts +0 -0
@@ -1,28 +1,53 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import CreateEditView from '@shell/mixins/create-edit-view';
3
3
 
4
- import CruResource from '@shell/components/CruResource';
4
+ import CruResource from '@shell/components/CruResource.vue';
5
5
  import { LabeledInput } from '@components/Form/LabeledInput';
6
- import LabeledSelect from '@shell/components/form/LabeledSelect';
7
- import Labels from '@shell/components/form/Labels';
8
- import Loading from '@shell/components/Loading';
9
- import NameNsDescription from '@shell/components/form/NameNsDescription';
10
- import Tab from '@shell/components/Tabbed/Tab';
6
+ import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
7
+ import ResourceLabeledSelect from '@shell/components/form/ResourceLabeledSelect.vue';
8
+ import Labels from '@shell/components/form/Labels.vue';
9
+ import Loading from '@shell/components/Loading.vue';
10
+ import NameNsDescription from '@shell/components/form/NameNsDescription.vue';
11
+ import Tab from '@shell/components/Tabbed/Tab.vue';
11
12
  import Tabbed from '@shell/components/Tabbed';
12
- import MetricsRow from '@shell/edit/autoscaling.horizontalpodautoscaler/metrics-row';
13
- import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
14
- import { DEFAULT_RESOURCE_METRIC } from '@shell/edit/autoscaling.horizontalpodautoscaler/resource-metric';
13
+ import MetricsRow from '@shell/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue';
14
+ import ArrayListGrouped from '@shell/components/form/ArrayListGrouped.vue';
15
+ import { DEFAULT_RESOURCE_METRIC } from '@shell/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue';
15
16
  import { Checkbox } from '@components/Form/Checkbox';
16
17
 
17
- import { API_SERVICE, SCALABLE_WORKLOAD_TYPES } from '@shell/config/types';
18
+ import { API_SERVICE, SCALABLE_WORKLOAD_TYPES, WORKLOAD_KIND_TO_TYPE_MAPPING } from '@shell/config/types';
18
19
  import isEmpty from 'lodash/isEmpty';
19
20
  import find from 'lodash/find';
20
21
  import endsWith from 'lodash/endsWith';
21
- import { findBy } from '@shell/utils/array';
22
22
  import HpaScalingRule from '@shell/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue';
23
+ import { ResourceLabeledSelectPaginateSettings, ResourceLabeledSelectSettings } from '@shell/types/components/resourceLabeledSelect';
24
+ import { PaginationParam, PaginationParamFilter } from '@shell/types/store/pagination.types';
25
+ import { LabelSelectPaginationFunctionOptions } from '@shell/components/form/labeled-select-utils/labeled-select.utils';
23
26
 
24
27
  const RESOURCE_METRICS_API_GROUP = 'metrics.k8s.io';
25
28
 
29
+ /**
30
+ * HPA spec.scaleTargetRef
31
+ */
32
+ interface OBJECT_REFERENCE {
33
+ apiVersion: string;
34
+ kind: string;
35
+ name: string;
36
+ }
37
+
38
+ type Workload = any;
39
+
40
+ /**
41
+ * Update to type OBJECT_REFERENCE which can be stored directly as scaleTargetRef
42
+ */
43
+ const mapWorkload = (workload: Workload | OBJECT_REFERENCE): OBJECT_REFERENCE => {
44
+ return {
45
+ kind: workload.kind,
46
+ name: workload.metadata?.name || workload.name,
47
+ apiVersion: workload.apiVersion,
48
+ };
49
+ };
50
+
26
51
  export default {
27
52
  name: 'CruHPA',
28
53
 
@@ -35,6 +60,7 @@ export default {
35
60
  CruResource,
36
61
  LabeledInput,
37
62
  LabeledSelect,
63
+ ResourceLabeledSelect,
38
64
  Labels,
39
65
  Loading,
40
66
  NameNsDescription,
@@ -57,41 +83,46 @@ export default {
57
83
  },
58
84
  },
59
85
 
60
- fetch() {
61
- const promises = [this.loadAPIServices(), this.loadWorkloads()];
62
-
63
- return Promise.all(promises);
86
+ async fetch() {
87
+ await this.loadAPIServices();
64
88
  },
65
89
 
66
90
  data() {
67
- return { defaultResourceMetric: DEFAULT_RESOURCE_METRIC };
91
+ const sharedSettings = {
92
+ labelSelectOptions: {
93
+ 'get-option-label': (opt: Workload) => opt?.name,
94
+ 'option-key': 'name',
95
+ },
96
+ };
97
+
98
+ const paginateSettings: ResourceLabeledSelectPaginateSettings = {
99
+ ...sharedSettings,
100
+ updateResources: (resources) => {
101
+ return resources.map(mapWorkload);
102
+ },
103
+ requestSettings: this.pageRequestSettings
104
+ };
105
+
106
+ const allSettings: ResourceLabeledSelectSettings = {
107
+ ...sharedSettings,
108
+ updateResources: this.mapWorkloads,
109
+ };
110
+
111
+ const scalableWorkloadType = WORKLOAD_KIND_TO_TYPE_MAPPING[this.value?.spec?.scaleTargetRef?.kind] || Object.values(SCALABLE_WORKLOAD_TYPES)[0];
112
+
113
+ return {
114
+ defaultResourceMetric: DEFAULT_RESOURCE_METRIC,
115
+ paginateSettings,
116
+ allSettings,
117
+ scalableWorkloadType,
118
+ scalableWorkloadTypes: Object.values(SCALABLE_WORKLOAD_TYPES).map((v) => ({ label: this.t(`typeLabel."${ v }"`, { count: 1 }), value: v })),
119
+ };
68
120
  },
69
121
 
70
122
  computed: {
71
123
  allMetrics() {
72
124
  return this.value?.spec?.metrics;
73
125
  },
74
- allWorkloadsFiltered() {
75
- return (
76
- Object.values(SCALABLE_WORKLOAD_TYPES)
77
- .flatMap((type) => this.$store.getters['cluster/all'](type))
78
- .filter(
79
- // Filter out anything that has an owner, which should probably be the one with the HPA
80
- // For example ReplicaSets can be associated with a HPA (https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#replicaset-as-a-horizontal-pod-autoscaler-target)
81
- // but wouldn't make sense if it's owned by a deployment
82
- (wl) => wl.metadata.namespace === this.value.metadata.namespace && !wl.ownedByWorkload
83
- )
84
- );
85
- },
86
- allWorkloadsMapped() {
87
- return this.allWorkloadsFiltered
88
- // Update to type OBJECT_REFERENCE which can be stored directly as scaleTargetRef
89
- .map((workload) => ({
90
- kind: workload.kind,
91
- name: workload.metadata.name,
92
- apiVersion: workload.apiVersion,
93
- }));
94
- },
95
126
  allServices() {
96
127
  return this.$store.getters['cluster/all'](API_SERVICE);
97
128
  },
@@ -107,17 +138,13 @@ export default {
107
138
  );
108
139
  },
109
140
  selectedTargetRef() {
110
- const { scaleTargetRef: { name } } = this.value.spec;
111
- const { allWorkloadsFiltered } = this;
112
- const match = findBy(allWorkloadsFiltered, 'metadata.name', name);
113
-
114
- return match ?? null;
141
+ return this.value?.spec?.scaleTargetRef;
115
142
  },
116
143
  hasScaleDownRules: {
117
144
  get() {
118
145
  return !!this.value.spec.behavior?.scaleDown;
119
146
  },
120
- set(hasScaleDownRules) {
147
+ set(hasScaleDownRules: boolean) {
121
148
  if (hasScaleDownRules) {
122
149
  if (!this.value.spec.behavior) {
123
150
  this.value.spec['behavior'] = {};
@@ -134,7 +161,7 @@ export default {
134
161
  get() {
135
162
  return !!this.value.spec.behavior?.scaleUp;
136
163
  },
137
- set(hasScaleUpRules) {
164
+ set(hasScaleUpRules: boolean) {
138
165
  if (hasScaleUpRules) {
139
166
  if (!this.value.spec.behavior) {
140
167
  this.value.spec['behavior'] = {};
@@ -147,6 +174,12 @@ export default {
147
174
  }
148
175
  }
149
176
  },
177
+ /**
178
+ * Unique id that when changes resets the state used to show candidate targets
179
+ */
180
+ targetResetKey() {
181
+ return `${ this.value.metadata.namespace }/${ this.scalableWorkloadType }`;
182
+ }
150
183
  },
151
184
 
152
185
  created() {
@@ -171,16 +204,56 @@ export default {
171
204
  metrics: [{ ...this.defaultResourceMetric }]
172
205
  };
173
206
  },
174
- async loadWorkloads() {
175
- await Promise.all(
176
- Object.values(SCALABLE_WORKLOAD_TYPES).map((type) => this.$store.dispatch('cluster/findAll', { type })
177
- )
178
- );
179
- },
180
207
  async loadAPIServices() {
181
208
  await this.$store.dispatch('cluster/findAll', { type: API_SERVICE });
182
209
  },
210
+
211
+ /**
212
+ * Fn of type @PaginateTypeOverridesFn
213
+ */
214
+ pageRequestSettings(opts: LabelSelectPaginationFunctionOptions): LabelSelectPaginationFunctionOptions {
215
+ const { opts: { filter } } = opts;
216
+
217
+ const filters: PaginationParam[] = [
218
+ PaginationParamFilter.createSingleField({
219
+ field: 'metadata.namespace', value: this.value.metadata.namespace, equals: true
220
+ }),
221
+ ];
222
+
223
+ if (!!filter) {
224
+ filters.push( PaginationParamFilter.createSingleField({
225
+ field: 'metadata.name', value: filter, equals: true, exact: false
226
+ }));
227
+ }
228
+
229
+ return {
230
+ ...opts,
231
+ classify: false,
232
+ groupByNamespace: false,
233
+ sort: [{ asc: true, field: 'metadata.name' }],
234
+ filters
235
+ };
236
+ },
237
+
238
+ /**
239
+ * Update to type OBJECT_REFERENCE which can be stored directly as scaleTargetRef
240
+ */
241
+ mapWorkload(workload: Workload | OBJECT_REFERENCE): OBJECT_REFERENCE {
242
+ return mapWorkload(workload);
243
+ },
244
+
245
+ mapWorkloads(workloads: Workload[]) {
246
+ return workloads
247
+ .filter((w) => w.metadata.namespace === this.value.metadata.namespace)
248
+ .map(mapWorkload);
249
+ }
183
250
  },
251
+
252
+ watch: {
253
+ targetResetKey() {
254
+ delete this.value.spec.scaleTargetRef;
255
+ },
256
+ }
184
257
  };
185
258
  </script>
186
259
 
@@ -196,7 +269,7 @@ export default {
196
269
  :resource="value"
197
270
  :validation-passed="true"
198
271
  :errors="errors"
199
- @error="(e) => (errors = e)"
272
+ @error="(e: any) => (errors = e)"
200
273
  @finish="save"
201
274
  @cancel="done"
202
275
  >
@@ -219,17 +292,24 @@ export default {
219
292
  <div class="row mb-20">
220
293
  <div class="col span-6">
221
294
  <LabeledSelect
295
+ v-model:value="scalableWorkloadType"
296
+ :options="scalableWorkloadTypes"
297
+ :mode="mode"
298
+ :label="t('hpa.workloadTab.targetReferenceType')"
299
+ :required="true"
300
+ />
301
+ </div>
302
+ <div class="col span-6">
303
+ <ResourceLabeledSelect
304
+ :key="targetResetKey"
222
305
  v-model:value="value.spec.scaleTargetRef"
223
- :get-option-label="(opt) => opt.name"
224
306
  :mode="mode"
225
307
  :label="t('hpa.workloadTab.targetReference')"
226
- :options="allWorkloadsMapped"
227
308
  :required="true"
228
- >
229
- <template v-slot:option="option">
230
- {{ option.name }}<span class="pull-right">{{ option.kind }}</span>
231
- </template>
232
- </LabeledSelect>
309
+ :resource-type="scalableWorkloadType"
310
+ :paginated-resource-settings="paginateSettings"
311
+ :all-resources-settings="allSettings"
312
+ />
233
313
  </div>
234
314
  </div>
235
315
  <div class="row">
@@ -282,6 +362,7 @@ export default {
282
362
  :mode="mode"
283
363
  :metrics-available="resourceMetricsAvailable"
284
364
  :referent="selectedTargetRef"
365
+ :namespace="value.metadata.namespace"
285
366
  />
286
367
  </template>
287
368
  </ArrayListGrouped>
@@ -8,6 +8,7 @@ import ObjectMetric, { DEFAULT_OBJECT_METRIC } from '@shell/edit/autoscaling.hor
8
8
  import PodMetric, { DEFAULT_POD_METRIC } from '@shell/edit/autoscaling.horizontalpodautoscaler/pod-metric';
9
9
  import ResourceMetric, { DEFAULT_RESOURCE_METRIC } from '@shell/edit/autoscaling.horizontalpodautoscaler/resource-metric';
10
10
  import { Banner } from '@components/Banner';
11
+ import { WORKLOAD_KIND_TO_TYPE_MAPPING } from '@shell/config/types';
11
12
 
12
13
  const METRIC_TYPES = {
13
14
  external: { label: 'External' },
@@ -28,9 +29,15 @@ export default {
28
29
 
29
30
  props: {
30
31
  referent: {
31
- type: Object,
32
- default: () => ({}),
32
+ type: String,
33
+ default: undefined,
34
+ },
35
+
36
+ namespace: {
37
+ type: String,
38
+ default: undefined,
33
39
  },
40
+
34
41
  value: {
35
42
  type: Object,
36
43
  default: () => ({}),
@@ -51,6 +58,7 @@ export default {
51
58
  return {
52
59
  metricOptions: values(METRIC_TYPES),
53
60
  metricTypes: METRIC_TYPES,
61
+ referentObj: null,
54
62
  };
55
63
  },
56
64
 
@@ -68,10 +76,10 @@ export default {
68
76
  return this.checkSpecType('external');
69
77
  },
70
78
  showReferentWarning() {
71
- const { referent } = this;
79
+ const { referentObj } = this;
72
80
 
73
- if (!isEmpty(referent)) {
74
- const containerRequests = referent.spec?.containers?.[0]?.resources?.requests;
81
+ if (!isEmpty(referentObj)) {
82
+ const containerRequests = referentObj.spec?.containers?.[0]?.resources?.requests;
75
83
 
76
84
  if (containerRequests && !containerRequests[this.value.name]) {
77
85
  return false;
@@ -117,6 +125,34 @@ export default {
117
125
  delete this.value[oldType.toLowerCase()];
118
126
  }
119
127
  },
128
+
129
+ referent: {
130
+ async handler() {
131
+ if (this.referent && this.namespace) {
132
+ const { name, kind } = this.referent;
133
+
134
+ if (name && kind) {
135
+ const type = WORKLOAD_KIND_TO_TYPE_MAPPING[kind];
136
+ const id = `${ this.namespace }/${ name }`;
137
+
138
+ if (type) {
139
+ // Use `find` in case the result we want is not in the drop down set of options... which means it won't initially be in the cache
140
+ // Use `transient` to not pollute the cache
141
+ const match = await this.$store.dispatch('cluster/find', {
142
+ type, id, transient: true
143
+ });
144
+
145
+ this.referentObj = match;
146
+
147
+ return;
148
+ }
149
+ }
150
+ }
151
+
152
+ this.referentObj = null;
153
+ },
154
+ immediate: true
155
+ }
120
156
  },
121
157
 
122
158
  methods: {
@@ -0,0 +1,29 @@
1
+ <script>
2
+ /**
3
+ * ProjectSecretProxy
4
+ *
5
+ * This component acts as a bridge to allow the "Project Secrets" sidebar item to be highlighted correctly
6
+ * while reusing the standard Secret creation/editing logic.
7
+ *
8
+ * How it works:
9
+ * 1. The Sidebar logic highlights items based on the current route's resource (e.g., /explorer/projectsecret/...).
10
+ * 2. The ResourceDetail loader looks for an edit component matching the resource name (shell/edit/projectsecret.vue).
11
+ * 3. Without this file, the loader falls back to the default YAML editor.
12
+ * 4. We cannot globally alias 'projectsecret' to 'secret' via `componentForType` because that would also
13
+ * redirect the List View to the generic Secret list, breaking the Project Secrets list logic.
14
+ *
15
+ * Therefore, this file exists solely to satisfy the component lookup for the Edit/Create view
16
+ * and pass control to the standard Secret component.
17
+ */
18
+ import Secret from '@shell/edit/secret/index.vue';
19
+
20
+ export default {
21
+ name: 'ProjectSecretProxy',
22
+ components: { Secret },
23
+ inheritAttrs: false,
24
+ };
25
+ </script>
26
+
27
+ <template>
28
+ <Secret v-bind="$attrs" />
29
+ </template>