@rancher/shell 3.0.9-rc.1 → 3.0.9-rc.3

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 (208) hide show
  1. package/assets/styles/base/_color.scss +1 -0
  2. package/assets/styles/base/_typography.scss +14 -5
  3. package/assets/styles/themes/_light.scss +1 -1
  4. package/assets/styles/themes/_modern.scss +1 -1
  5. package/assets/translations/en-us.yaml +104 -33
  6. package/assets/translations/zh-hans.yaml +13 -2
  7. package/components/ActionMenu.vue +7 -8
  8. package/components/ActionMenuShell.vue +23 -24
  9. package/components/CodeMirror.vue +4 -3
  10. package/components/DetailText.vue +54 -7
  11. package/components/Drawer/Chrome.vue +11 -4
  12. package/components/Drawer/DrawerCard.vue +19 -0
  13. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +3 -11
  14. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +2 -2
  15. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -20
  16. package/components/Drawer/types.ts +1 -0
  17. package/components/DynamicContent/DynamicContentCloseButton.vue +2 -2
  18. package/components/LocaleSelector.vue +1 -1
  19. package/components/Markdown.vue +1 -1
  20. package/components/PopoverCard.vue +3 -3
  21. package/components/Resource/Detail/Card/ExtrasCard.vue +39 -0
  22. package/components/Resource/Detail/Card/Scaler.vue +10 -2
  23. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +142 -0
  24. package/components/Resource/Detail/Card/StateCard/composables.ts +41 -11
  25. package/components/Resource/Detail/Card/StateCard/index.vue +3 -9
  26. package/components/Resource/Detail/Card/StateCard/types.ts +6 -0
  27. package/components/Resource/Detail/Card/{PodsCard → StatusCard}/index.vue +14 -10
  28. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +24 -25
  29. package/components/Resource/Detail/Cards.vue +27 -0
  30. package/components/Resource/Detail/Masthead/__tests__/index.test.ts +70 -0
  31. package/components/Resource/Detail/Masthead/index.vue +5 -0
  32. package/components/Resource/Detail/Metadata/KeyValueRow.vue +4 -2
  33. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -2
  34. package/components/Resource/Detail/ResourceRow.types.ts +14 -0
  35. package/components/Resource/Detail/ResourceRow.vue +23 -35
  36. package/components/Resource/Detail/StatusRow.vue +5 -2
  37. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +38 -7
  38. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +106 -2
  39. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  40. package/components/Resource/Detail/TitleBar/index.vue +41 -6
  41. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +49 -1
  42. package/components/ResourceDetail/Masthead/__tests__/latest.test.ts +85 -0
  43. package/components/ResourceDetail/Masthead/index.vue +1 -0
  44. package/components/ResourceDetail/Masthead/latest.vue +8 -1
  45. package/components/ResourceDetail/Masthead/legacy.vue +1 -1
  46. package/components/ResourceTable.vue +1 -1
  47. package/components/Setting.vue +1 -1
  48. package/components/SortableTable/index.vue +25 -0
  49. package/components/SortableTable/selection.js +25 -12
  50. package/components/SortableTable/sorting.js +1 -1
  51. package/components/Tabbed/Tab.vue +5 -0
  52. package/components/Tabbed/index.vue +40 -9
  53. package/components/Window/ContainerShell.vue +10 -13
  54. package/components/__tests__/ProjectRow.test.ts +102 -15
  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/ResourceQuota/Project.vue +59 -8
  70. package/components/form/ResourceQuota/ProjectRow.vue +116 -21
  71. package/components/form/ResourceQuota/shared.js +42 -18
  72. package/components/form/SeccompProfile.vue +113 -0
  73. package/components/form/Security.vue +244 -133
  74. package/components/form/__tests__/LabeledSelect.test.ts +1 -1
  75. package/components/form/__tests__/SeccompProfile.test.js +124 -0
  76. package/components/form/__tests__/Security.test.ts +125 -37
  77. package/components/formatter/Autoscaler.vue +2 -2
  78. package/components/formatter/FleetSummaryGraph.vue +4 -1
  79. package/components/formatter/LinkName.vue +3 -2
  80. package/components/nav/Group.vue +5 -0
  81. package/components/nav/Header.vue +3 -3
  82. package/components/nav/HeaderPageActionMenu.vue +1 -1
  83. package/components/nav/NamespaceFilter.vue +6 -6
  84. package/components/nav/NotificationCenter/index.vue +1 -1
  85. package/components/nav/TopLevelMenu.helper.ts +41 -16
  86. package/components/nav/TopLevelMenu.vue +45 -25
  87. package/components/nav/WorkspaceSwitcher.vue +1 -1
  88. package/components/nav/__tests__/TopLevelMenu.helper.test.ts +277 -0
  89. package/components/nav/__tests__/TopLevelMenu.test.ts +160 -4
  90. package/components/templates/default.vue +0 -3
  91. package/components/templates/home.vue +0 -3
  92. package/components/templates/plain.vue +0 -3
  93. package/composables/useClickOutside.ts +1 -1
  94. package/config/product/explorer.js +2 -3
  95. package/config/table-headers.js +9 -7
  96. package/config/types.js +45 -9
  97. package/detail/__tests__/workload.test.ts +8 -16
  98. package/detail/catalog.cattle.io.app.vue +5 -0
  99. package/detail/fleet.cattle.io.cluster.vue +6 -0
  100. package/detail/management.cattle.io.oidcclient.vue +15 -4
  101. package/detail/workload/index.vue +7 -109
  102. package/edit/__tests__/management.cattle.io.project.test.js +137 -0
  103. package/edit/__tests__/projectsecret.test.ts +42 -0
  104. package/edit/auth/__tests__/oidc.test.ts +50 -0
  105. package/edit/auth/oidc.vue +68 -44
  106. package/edit/autoscaling.horizontalpodautoscaler/index.vue +140 -59
  107. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +41 -5
  108. package/edit/management.cattle.io.project.vue +36 -6
  109. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +16 -3
  110. package/edit/projectsecret.vue +29 -0
  111. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +89 -200
  112. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +58 -17
  113. package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -0
  114. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +3 -63
  115. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +82 -14
  116. package/edit/workload/__tests__/index.test.ts +3 -4
  117. package/edit/workload/index.vue +47 -28
  118. package/edit/workload/mixins/workload.js +66 -31
  119. package/initialize/install-plugins.js +0 -2
  120. package/list/catalog.cattle.io.clusterrepo.vue +1 -1
  121. package/list/projectsecret.vue +2 -2
  122. package/machine-config/__tests__/vmwarevsphere.test.ts +64 -0
  123. package/machine-config/amazonec2.vue +2 -2
  124. package/machine-config/vmwarevsphere.vue +58 -4
  125. package/mixins/__tests__/chart.test.ts +63 -0
  126. package/mixins/chart.js +56 -51
  127. package/models/__tests__/catalog.cattle.io.app.test.ts +33 -0
  128. package/models/__tests__/workload.test.ts +333 -0
  129. package/models/catalog.cattle.io.app.js +8 -0
  130. package/models/management.cattle.io.cluster.js +22 -30
  131. package/models/pod.js +14 -0
  132. package/models/provisioning.cattle.io.cluster.js +2 -2
  133. package/models/secret.js +1 -1
  134. package/models/workload.js +93 -27
  135. package/package.json +4 -4
  136. package/pages/__tests__/diagnostic.test.ts +71 -0
  137. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +91 -0
  138. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  139. package/pages/c/_cluster/explorer/EventsTable.vue +2 -2
  140. package/pages/c/_cluster/explorer/tools/index.vue +23 -5
  141. package/pages/c/_cluster/fleet/index.vue +14 -8
  142. package/pages/c/_cluster/manager/hostedprovider/index.vue +1 -19
  143. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +18 -5
  144. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  145. package/pages/c/_cluster/uiplugins/index.vue +41 -9
  146. package/pages/diagnostic.vue +17 -3
  147. package/plugins/dashboard-store/__tests__/resource-class.test.ts +234 -0
  148. package/plugins/dashboard-store/actions.js +9 -8
  149. package/plugins/dashboard-store/resource-class.js +97 -1
  150. package/plugins/steve/__tests__/revision.test.ts +84 -0
  151. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +30 -0
  152. package/plugins/steve/__tests__/subscribe.spec.ts +134 -0
  153. package/plugins/steve/revision.ts +26 -0
  154. package/plugins/steve/steve-pagination-utils.ts +6 -5
  155. package/plugins/steve/subscribe.js +188 -49
  156. package/plugins/subscribe-events.ts +2 -2
  157. package/rancher-components/Form/Checkbox/Checkbox.vue +13 -0
  158. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -1
  159. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +2 -1
  160. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +3 -1
  161. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -1
  162. package/rancher-components/Pill/RcTag/RcTag.vue +1 -1
  163. package/rancher-components/Pill/index.ts +4 -0
  164. package/rancher-components/RcButton/RcButton.test.ts +53 -9
  165. package/rancher-components/RcButton/RcButton.vue +217 -25
  166. package/rancher-components/RcButton/types.ts +27 -1
  167. package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -4
  168. package/rancher-components/RcDropdown/types.ts +3 -3
  169. package/rancher-components/RcIcon/RcIcon.test.ts +42 -0
  170. package/rancher-components/RcIcon/RcIcon.vue +9 -6
  171. package/rancher-components/RcIcon/types.ts +13 -9
  172. package/rancher-components/RcItemCard/RcItemCard.test.ts +16 -6
  173. package/rancher-components/RcItemCard/RcItemCard.vue +13 -23
  174. package/rancher-components/utils/status.test.ts +10 -15
  175. package/rancher-components/utils/status.ts +5 -6
  176. package/store/__tests__/auth.test.ts +21 -5
  177. package/store/auth.js +6 -3
  178. package/store/aws.js +18 -12
  179. package/store/index.js +4 -8
  180. package/store/type-map.utils.ts +1 -1
  181. package/types/kube/kube-api.ts +29 -3
  182. package/types/rancher/steve.api.ts +40 -0
  183. package/types/shell/index.d.ts +262 -156
  184. package/types/store/pagination.types.ts +1 -0
  185. package/types/store/subscribe-events.types.ts +1 -0
  186. package/utils/__tests__/azure.test.ts +56 -0
  187. package/utils/__tests__/back-off.test.ts +364 -245
  188. package/utils/__tests__/error.test.ts +44 -0
  189. package/utils/__tests__/fleet.test.ts +8 -1
  190. package/utils/__tests__/pagination-wrapper.test.ts +167 -0
  191. package/utils/__tests__/version.test.ts +55 -1
  192. package/utils/azure.js +12 -0
  193. package/utils/back-off.ts +302 -69
  194. package/utils/dynamic-content/__tests__/index.test.ts +1 -1
  195. package/utils/dynamic-content/__tests__/new-release.test.ts +48 -7
  196. package/utils/dynamic-content/__tests__/support-notice.test.ts +1 -4
  197. package/utils/dynamic-content/index.ts +1 -6
  198. package/utils/dynamic-content/new-release.ts +5 -3
  199. package/utils/dynamic-content/types.d.ts +0 -1
  200. package/utils/error.js +9 -0
  201. package/utils/fleet.ts +2 -2
  202. package/utils/inactivity.ts +2 -3
  203. package/utils/pagination-wrapper.ts +99 -15
  204. package/utils/validators/formRules/index.ts +3 -0
  205. package/utils/version.js +38 -0
  206. package/components/auth/AzureWarning.vue +0 -77
  207. /package/components/Resource/Detail/{Card/PodsCard/Bubble.vue → Bubble.vue} +0 -0
  208. /package/components/Resource/Detail/Card/{PodsCard → StatusCard}/composable.ts +0 -0
@@ -18,49 +18,67 @@ export default {
18
18
  },
19
19
 
20
20
  computed: {
21
- names() {
22
- const names = this.clusters.map(({ nameDisplay, name }) => nameDisplay || name);
23
- const max = 10;
21
+ clustersRenderList() {
22
+ const clustersRenderList = this.clusters.map(({ nameDisplay, name, detailLocation }) => ({
23
+ name: nameDisplay || name,
24
+ detailLocation,
25
+ }));
24
26
 
25
- const remaining = names.length - max;
26
-
27
- if (remaining > 0) {
28
- return [
29
- ...names.filter((_, i) => i < max),
30
- this.t('fleet.clusterTargets.rules.matching.plusMore', { n: remaining }, true),
31
- ];
32
- }
33
-
34
- return names;
27
+ return clustersRenderList;
35
28
  }
36
29
  }
37
30
  };
38
31
  </script>
39
32
 
40
33
  <template>
41
- <div class="targets-list">
42
- <h3>{{ t('fleet.clusterTargets.rules.matching.title') }}</h3>
43
- <span
44
- v-for="(name, i) in names"
45
- :key="i"
46
- class="row mt-5"
47
- >
48
- {{ name }}
49
- </span>
50
- <span
51
- v-if="!names.length"
52
- class="text-label"
53
- >
54
- {{ emptyLabel || t('fleet.clusterTargets.rules.matching.empty') }}
55
- </span>
34
+ <div class="targets-list-main">
35
+ <h3>{{ t('fleet.clusterTargets.rules.matching.title', { n: clustersRenderList.length }) }}</h3>
36
+ <div class="targets-list-list">
37
+ <span
38
+ v-for="(cluster, i) in clustersRenderList"
39
+ :key="i"
40
+ class="row mt-5"
41
+ >
42
+ <router-link
43
+ :to="cluster.detailLocation"
44
+ target="_blank"
45
+ class="link-main"
46
+ >
47
+ {{ cluster.name }}&nbsp;<i class="link-icon icon icon-external-link" />
48
+ </router-link>
49
+ </span>
50
+ <span
51
+ v-if="!clustersRenderList.length"
52
+ class="text-label"
53
+ >
54
+ {{ emptyLabel || t('fleet.clusterTargets.rules.matching.empty') }}
55
+ </span>
56
+ </div>
56
57
  </div>
57
58
  </template>
58
59
 
59
60
  <style lang="scss" scoped>
60
- .targets-list {
61
+ .targets-list-main {
61
62
  height: 100%;
62
63
  border-radius: 4px;
63
64
  padding: 16px;
64
65
  background-color: var(--tabbed-sidebar-bg);
66
+ display: flex;
67
+ flex-direction: column;
68
+ }
69
+ .targets-list-list {
70
+ overflow-y: scroll;
71
+ }
72
+ .link-main{
73
+ word-spacing: 22px;
74
+ }
75
+ .link-icon {
76
+ position: absolute;
77
+ margin-left: -14px; // Remove the space of the icon to make it float to accomodate the underline
78
+ display: none; // Make the icon disappear by default
79
+ }
80
+
81
+ .link-main:hover .link-icon {
82
+ display: inline; // Only appear when hovered
65
83
  }
66
84
  </style>
@@ -16,13 +16,16 @@ import TargetsList from '@shell/components/fleet/FleetClusterTargets/TargetsList
16
16
 
17
17
  export interface Cluster {
18
18
  name: string,
19
- nameDisplay: string
19
+ nameDisplay: string,
20
+ detailLocation: object,
20
21
  }
21
22
 
22
23
  interface DataType {
23
24
  targetMode: TargetMode,
24
25
  allClusters: any[],
26
+ allClusterGroups: any[],
25
27
  selectedClusters: string[],
28
+ selectedClusterGroups: string[],
26
29
  clusterSelectors: Selector[],
27
30
  key: number,
28
31
  }
@@ -76,19 +79,26 @@ export default {
76
79
  allClusters: {
77
80
  inStoreType: 'management',
78
81
  type: FLEET.CLUSTER
79
- }
80
- }, this.$store) as { allClusters: any[] };
82
+ },
83
+ allClusterGroups: {
84
+ inStoreType: 'management',
85
+ type: FLEET.CLUSTER_GROUP
86
+ },
87
+ }, this.$store) as { allClusters: any[], allClusterGroups: any[] };
81
88
 
82
89
  this.allClusters = hash.allClusters || [];
90
+ this.allClusterGroups = hash.allClusterGroups || [];
83
91
  },
84
92
 
85
93
  data(): DataType {
86
94
  return {
87
- targetMode: 'all',
88
- allClusters: [],
89
- selectedClusters: [],
90
- clusterSelectors: [],
91
- key: 0 // Generates a unique key to handle Targets
95
+ targetMode: 'all',
96
+ allClusters: [],
97
+ allClusterGroups: [],
98
+ selectedClusters: [],
99
+ selectedClusterGroups: [],
100
+ clusterSelectors: [],
101
+ key: 0 // Generates a unique key to handle Targets
92
102
  };
93
103
  },
94
104
 
@@ -96,10 +106,9 @@ export default {
96
106
  this.fromTargets();
97
107
 
98
108
  if (this.mode === _CREATE) {
99
- this.update();
100
-
101
109
  // Restore the targetMode from parent component; this is the case of edit targets in CREATE mode, go to YAML editor and come back to the form
102
110
  this.targetMode = this.created || 'all';
111
+ this.update();
103
112
  } else {
104
113
  this.targetMode = FleetUtils.Application.getTargetMode(this.targets || [], this.namespace);
105
114
  }
@@ -153,6 +162,14 @@ export default {
153
162
  .map((x) => ({ label: x.nameDisplay, value: x.metadata.name }));
154
163
  },
155
164
 
165
+ clusterGroupsOptions() {
166
+ return this.allClusterGroups
167
+ .filter((x) => x.metadata.namespace === this.namespace)
168
+ .map((x) => {
169
+ return { label: x.nameDisplay, value: x.metadata.name };
170
+ });
171
+ },
172
+
156
173
  isLocal() {
157
174
  return this.namespace === 'fleet-local';
158
175
  },
@@ -178,6 +195,12 @@ export default {
178
195
  this.update();
179
196
  },
180
197
 
198
+ selectClusterGroups(list: string[]) {
199
+ this.selectedClusterGroups = list;
200
+
201
+ this.update();
202
+ },
203
+
181
204
  addMatchExpressions() {
182
205
  const neu = { key: this.key++ };
183
206
 
@@ -224,11 +247,15 @@ export default {
224
247
  clusterGroupSelector,
225
248
  } = target;
226
249
 
227
- // If clusterGroup or clusterGroupSelector are defined, targets are marked as complex and won't handle by the UI
228
- if (clusterGroup || clusterGroupSelector) {
250
+ // If clusterGroupSelector are defined, targets are marked as complex and won't handle by the UI
251
+ if (clusterGroupSelector) {
229
252
  return;
230
253
  }
231
254
 
255
+ if (clusterGroup) {
256
+ this.selectedClusterGroups.push(clusterGroup);
257
+ }
258
+
232
259
  if (clusterName) {
233
260
  this.selectedClusters.push(clusterName);
234
261
  }
@@ -254,20 +281,22 @@ export default {
254
281
  case 'all':
255
282
  return [excludeHarvesterRule];
256
283
  case 'clusters':
257
- return this.normalizeTargets(this.selectedClusters, this.clusterSelectors);
284
+ return this.normalizeTargets(this.selectedClusters, this.clusterSelectors, this.selectedClusterGroups);
258
285
  case 'advanced':
259
286
  case 'local':
260
287
  return this.targets;
261
288
  }
262
289
  },
263
290
 
264
- normalizeTargets(selected: string[], clusterMatchExpressions: Selector[]) {
291
+ normalizeTargets(selected: string[], clusterMatchExpressions: Selector[], selectedClusterGroups: string[]): Target[] | undefined {
265
292
  const targets: Target[] = [];
266
293
 
294
+ // Select by name
267
295
  selected.forEach((clusterName) => {
268
296
  targets.push({ clusterName });
269
297
  });
270
298
 
299
+ // Select by labels
271
300
  clusterMatchExpressions.forEach((elem) => {
272
301
  const { matchLabels: labels, matchExpressions: expressions } = elem || {};
273
302
 
@@ -311,6 +340,11 @@ export default {
311
340
  }
312
341
  });
313
342
 
343
+ // Select by cluster group
344
+ selectedClusterGroups.forEach((clusterGroup) => {
345
+ targets.push({ clusterGroup });
346
+ });
347
+
314
348
  if (targets.length) {
315
349
  return targets;
316
350
  }
@@ -321,6 +355,7 @@ export default {
321
355
  reset() {
322
356
  this.targetMode = 'all';
323
357
  this.selectedClusters = [];
358
+ this.selectedClusterGroups = [];
324
359
  this.clusterSelectors = [];
325
360
  }
326
361
  },
@@ -356,25 +391,25 @@ export default {
356
391
  >
357
392
  <div class="col span-9">
358
393
  <h3 class="m-0">
359
- {{ t('fleet.clusterTargets.title') }}
394
+ {{ t('fleet.clusterTargets.clusters.title') }}
360
395
  </h3>
361
396
  <LabeledSelect
362
397
  data-testid="fleet-target-cluster-name-selector"
363
398
  class="mmt-4"
364
399
  :value="selectedClusters"
365
- :label="t('fleet.clusterTargets.label')"
400
+ :label="t('fleet.clusterTargets.clusters.byName.label')"
366
401
  :options="clustersOptions"
367
402
  :taggable="true"
368
403
  :close-on-select="false"
369
404
  :mode="mode"
370
405
  :multiple="true"
371
- :placeholder="t('fleet.clusterTargets.placeholders.selectMultiple')"
406
+ :placeholder="t('fleet.clusterTargets.clusters.byName.placeholder')"
372
407
  @update:value="selectClusters"
373
408
  />
374
- <div class="mmt-8">
375
- <h3 class="m-0">
376
- {{ t('fleet.clusterTargets.rules.title') }}
377
- </h3>
409
+ <div class="mmt-6">
410
+ <h4 class="m-0">
411
+ {{ t('fleet.clusterTargets.clusters.byLabel.title') }}
412
+ </h4>
378
413
  <div
379
414
  v-for="(selector, i) in clusterSelectors"
380
415
  :key="selector.key"
@@ -386,29 +421,47 @@ export default {
386
421
  :value="selector"
387
422
  :mode="mode"
388
423
  :initial-empty-row="true"
389
- :label-key="t('fleet.clusterTargets.rules.labelKey')"
424
+ :label-key="t('fleet.clusterTargets.clusters.byLabel.labelKey')"
390
425
  :add-icon="'icon-plus'"
391
426
  :add-class="'btn-sm'"
392
427
  @update:value="updateMatchExpressions(i, $event, selector.key)"
393
428
  />
394
429
  <RcButton
395
- small
396
- link
430
+ size="small"
431
+ variant="link"
397
432
  @click="removeMatchExpressions(selector.key)"
398
433
  >
399
434
  <i class="icon icon-x" />
400
435
  </RcButton>
401
436
  </div>
402
437
  <RcButton
403
- small
404
- secondary
405
- class="mmt-6"
438
+ size="small"
439
+ variant="secondary"
440
+ class="mmt-4"
406
441
  @click="addMatchExpressions"
407
442
  >
408
443
  <i class="icon icon-plus" />
409
- <span>{{ t('fleet.clusterTargets.rules.addSelector') }}</span>
444
+ <span>{{ t('fleet.clusterTargets.clusters.byLabel.addSelector') }}</span>
410
445
  </RcButton>
411
446
  </div>
447
+ <div class="mmt-8">
448
+ <h3 class="m-0">
449
+ {{ t('fleet.clusterTargets.clusterGroups.title') }}
450
+ </h3>
451
+ <LabeledSelect
452
+ data-testid="fleet-target-cluster-group-selector"
453
+ class="mmt-4"
454
+ :value="selectedClusterGroups"
455
+ :label="t('fleet.clusterTargets.clusterGroups.byName.label')"
456
+ :options="clusterGroupsOptions"
457
+ :taggable="true"
458
+ :close-on-select="false"
459
+ :mode="mode"
460
+ :multiple="true"
461
+ :placeholder="t('fleet.clusterTargets.clusterGroups.byName.placeholder')"
462
+ @update:value="selectClusterGroups"
463
+ />
464
+ </div>
412
465
  </div>
413
466
  <div class="col span-3">
414
467
  <TargetsList
@@ -450,6 +503,6 @@ export default {
450
503
  }
451
504
 
452
505
  .target-list {
453
- max-height: 250px;
506
+ max-height: 320px;
454
507
  }
455
508
  </style>
@@ -25,6 +25,14 @@ export default {
25
25
  useQueryParamsForSimpleFiltering: {
26
26
  type: Boolean,
27
27
  default: false
28
+ },
29
+ removeSubRows: {
30
+ type: Boolean,
31
+ default: false,
32
+ },
33
+ ignoreFilter: {
34
+ type: Boolean,
35
+ default: false,
28
36
  }
29
37
  },
30
38
 
@@ -99,9 +107,9 @@ export default {
99
107
  :schema="schema"
100
108
  :headers="headers"
101
109
  :rows="rows"
102
- :sub-rows="true"
103
110
  :loading="loading"
104
111
  :use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
112
+ :ignore-filter="ignoreFilter"
105
113
  key-field="_key"
106
114
  >
107
115
  <template #cell:workspace="{row}">
@@ -151,18 +159,22 @@ export default {
151
159
  >{{ row.bundleInfo.total }}</span>
152
160
  </template>
153
161
 
154
- <template #sub-row="{fullColspan, row, onRowMouseEnter, onRowMouseLeave}">
162
+ <template
163
+ v-if="!removeSubRows"
164
+ #additional-sub-row="{fullColspan, row, onRowMouseEnter, onRowMouseLeave, showSubRow}"
165
+ >
155
166
  <tr
156
- class="labels-row sub-row"
167
+ class="labels-row additional-sub-row"
168
+ :class="{ 'has-sub-row': showSubRow}"
157
169
  @mouseenter="onRowMouseEnter"
158
170
  @mouseleave="onRowMouseLeave"
159
171
  >
160
- <template v-if="row.customLabels.length">
172
+ <template v-if="row.customLabels && row.customLabels.length">
161
173
  <td>&nbsp;</td>
162
174
  <td>&nbsp;</td>
163
175
  <td :colspan="fullColspan-2">
164
176
  <span
165
- v-if="row.customLabels.length"
177
+ v-if="row.customLabels && row.customLabels.length"
166
178
  class="mt-5"
167
179
  > {{ t('fleet.cluster.labels') }}:
168
180
  <span
@@ -184,7 +196,7 @@ export default {
184
196
  </Tag>
185
197
  </span>
186
198
  <a
187
- v-if="row.customLabels.length > 7"
199
+ v-if="row.customLabels && row.customLabels.length > 7"
188
200
  href="#"
189
201
  @click.prevent="toggleCustomLabels(row)"
190
202
  >
@@ -193,14 +205,16 @@ export default {
193
205
  </span>
194
206
  </td>
195
207
  </template>
196
- <td
197
- v-else
198
- :colspan="fullColspan"
199
- >
200
- &nbsp;
201
- </td>
202
208
  </tr>
203
209
  </template>
210
+ <template
211
+ v-else
212
+ #sub-row
213
+ >
214
+ <tr
215
+ class="sub-row"
216
+ />
217
+ </template>
204
218
  </ResourceTable>
205
219
  </template>
206
220
 
@@ -335,8 +335,8 @@ export default {
335
335
  </h4>
336
336
  <RcButton
337
337
  v-if="!isView"
338
- small
339
- link
338
+ size="small"
339
+ variant="link"
340
340
  @click="removePaths(i)"
341
341
  >
342
342
  <i class="icon icon-x" />
@@ -35,6 +35,19 @@ export default {
35
35
  },
36
36
 
37
37
  computed: {
38
+ groupOptions() {
39
+ return [{
40
+ tooltipKey: 'resourceTable.groupBy.none',
41
+ icon: 'icon-list-flat',
42
+ value: 'none',
43
+ }, {
44
+ tooltipKey: 'resourceTable.groupBy.cluster',
45
+ hideColumn: 'provider',
46
+ icon: 'icon-folder',
47
+ value: 'clusterId',
48
+ field: 'clusterId',
49
+ }];
50
+ },
38
51
  computedResources() {
39
52
  const resources = (this.rows || []).map((r) => ({
40
53
  tableKey: r.key,
@@ -107,6 +120,7 @@ export default {
107
120
  :table-actions="false"
108
121
  :row-actions="false"
109
122
  :search="search"
123
+ :group-options="groupOptions"
110
124
  key-field="tableKey"
111
125
  default-sort-by="state"
112
126
  >
@@ -276,8 +276,8 @@ export default {
276
276
  <RcButton
277
277
  v-if="!isView"
278
278
  ref="add-button"
279
- small
280
- secondary
279
+ size="small"
280
+ variant="secondary"
281
281
  class="mmt-6"
282
282
  data-testid="fleet-values-from-add"
283
283
  @click="addValueFrom"