@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
@@ -5,36 +5,82 @@
5
5
  *
6
6
  * Example:
7
7
  *
8
- * <rc-button primary @click="doAction">Perform an Action</rc-button>
8
+ * <rc-button variant="primary" @click="doAction">Perform an Action</rc-button>
9
9
  */
10
10
  import { computed, ref } from 'vue';
11
- import { ButtonRoleProps, ButtonSizeProps } from './types';
12
-
13
- const buttonRoles: { role: keyof ButtonRoleProps, className: string }[] = [
14
- { role: 'primary', className: 'role-primary' },
15
- { role: 'secondary', className: 'role-secondary' },
16
- { role: 'tertiary', className: 'role-tertiary' },
17
- { role: 'link', className: 'role-link' },
18
- { role: 'multiAction', className: 'role-multi-action' },
19
- { role: 'ghost', className: 'role-ghost' },
11
+ import {
12
+ ButtonVariantProps, ButtonSizeProps, ButtonVariantNewProps, ButtonSizeNewProps, ButtonSize,
13
+ IconProps
14
+ } from './types';
15
+ import RcIcon from '@components/RcIcon/RcIcon.vue';
16
+
17
+ const buttonVariants: { variant: keyof ButtonVariantProps, className: string }[] = [
18
+ { variant: 'primary', className: 'variant-primary' },
19
+ { variant: 'secondary', className: 'variant-secondary' },
20
+ { variant: 'tertiary', className: 'variant-tertiary' },
21
+ { variant: 'link', className: 'variant-link' },
22
+ { variant: 'multiAction', className: 'variant-multi-action' },
23
+ { variant: 'ghost', className: 'variant-ghost' },
20
24
  ];
21
25
 
22
26
  const buttonSizes: { size: keyof ButtonSizeProps, className: string }[] = [
23
27
  { size: 'small', className: 'btn-sm' },
24
28
  ];
25
29
 
26
- const props = defineProps<ButtonRoleProps & ButtonSizeProps>();
30
+ const buttonSizesNew: { size: ButtonSize, className: string }[] = [
31
+ { size: 'small', className: 'btn-small' },
32
+ { size: 'medium', className: 'btn-medium' },
33
+ { size: 'large', className: 'btn-large' },
34
+ ];
27
35
 
28
- const buttonClass = computed(() => {
29
- const activeRole = buttonRoles.find(({ role }) => props[role]);
30
- const isButtonSmall = buttonSizes.some(({ size }) => props[size]);
36
+ const props = withDefaults(defineProps<ButtonVariantProps & ButtonSizeProps & ButtonVariantNewProps & ButtonSizeNewProps & IconProps>(), { size: 'medium' });
31
37
 
32
- return {
33
- btn: true,
38
+ const activeVariantClassName = computed(() => {
39
+ if (props.variant === 'multiAction' || props.multiAction) {
40
+ console.warn('[RcButton] The "multiAction" variant is deprecated and will be removed in a future version.'); // eslint-disable-line no-console
41
+ }
42
+
43
+ const activeVariant = buttonVariants.find(({ variant }) => props[variant]);
44
+
45
+ if (activeVariant) {
46
+ console.warn( // eslint-disable-line no-console
47
+ `[RcButton] The "${ activeVariant.variant }" prop is deprecated and will be removed in a future version. ` +
48
+ `Please use variant="${ activeVariant.variant }" instead.`
49
+ );
50
+
51
+ return activeVariant.className;
52
+ } else {
53
+ const variantConfig = buttonVariants.find(({ variant }) => variant === props.variant);
54
+
55
+ return variantConfig?.className || 'variant-primary';
56
+ }
57
+ });
58
+
59
+ const activeSizeClassName = computed(() => {
60
+ const activeSize = buttonSizes.find(({ size }) => props[size]);
61
+
62
+ if (activeSize) {
63
+ /* eslint-disable no-console */
64
+ console.warn(
65
+ `[RcButton] The "${ activeSize.size }" prop is deprecated and will be removed in a future version. ` +
66
+ `Please use size="${ activeSize.size }" instead.`
67
+ );
68
+ /* eslint-enable no-console */
34
69
 
35
- [activeRole?.className || 'role-primary']: true,
70
+ return activeSize.className;
71
+ } else {
72
+ const sizeConfig = buttonSizesNew.find(({ size }) => size === props.size);
73
+
74
+ return sizeConfig?.className || '';
75
+ }
76
+ });
36
77
 
37
- 'btn-sm': isButtonSmall,
78
+ const buttonClass = computed(() => {
79
+ return {
80
+ 'rc-button': true,
81
+ btn: true,
82
+ [activeVariantClassName.value]: true,
83
+ [activeSizeClassName.value]: !!activeSizeClassName.value,
38
84
  };
39
85
  });
40
86
 
@@ -53,33 +99,142 @@ defineExpose({ focus });
53
99
  role="button"
54
100
  :class="{ ...buttonClass }"
55
101
  >
56
- <slot name="before">
57
- <!-- Empty Content -->
102
+ <slot
103
+ v-if="$slots.before || props.leftIcon"
104
+ name="before"
105
+ >
106
+ <RcIcon
107
+ v-if="props.leftIcon"
108
+ class="left-icon"
109
+ :type="props.leftIcon"
110
+ size="inherit"
111
+ />
58
112
  </slot>
59
113
  <slot>
60
114
  <!-- Empty Content -->
61
115
  </slot>
62
- <slot name="after">
63
- <!-- Empty Content -->
116
+ <slot
117
+ v-if="$slots.after || props.rightIcon"
118
+ name="after"
119
+ >
120
+ <RcIcon
121
+ v-if="props.rightIcon"
122
+ class="right-icon"
123
+ :type="props.rightIcon"
124
+ size="inherit"
125
+ />
64
126
  </slot>
65
127
  </button>
66
128
  </template>
67
129
 
68
130
  <style lang="scss" scoped>
69
131
  button {
70
- &.role-link {
132
+ display: inline-flex;
133
+ align-items: center;
134
+ justify-content: center;
135
+
136
+ // Much of the styling in here came from _button.scss. Because we're making changes from role to variant and we don't want to impact existing use cases we're pulling in some of these styles. We should in the long run deprecate that file.
137
+ // Variant styles
138
+ &.variant-primary {
139
+ background: var(--primary);
140
+ color: var(--primary-text);
141
+
142
+ &:hover, &._hover {
143
+ background-color: var(--primary-hover-bg);
144
+ color: var(--primary-text);
145
+ }
146
+
71
147
  &:focus, &.focused {
148
+ background-color: var(--primary-hover-bg);
149
+ color: var(--primary-text);
150
+ }
151
+
152
+ &:focus-visible {
72
153
  @include focus-outline;
73
- outline-offset: -2px;
154
+ outline-offset: 2px;
155
+ }
156
+
157
+ &:disabled {
158
+ background: var(--primary);
159
+ color: var(--primary-text);
160
+ opacity: 0.5;
161
+ }
162
+ }
163
+
164
+ &.variant-secondary {
165
+ background: var(--secondary, transparent);
166
+ color: var(--on-secondary, var(--primary));
167
+ border: solid 1px var(--secondary-border, var(--primary));
168
+
169
+ &:hover, &._hover {
170
+ background: var(--secondary-hover, transparent);
171
+ color: var(--on-secondary, var(--lightest));
172
+ }
173
+
174
+ &:focus, &.focused {
175
+ background-color: var(--secondary-hover, var(--primary-hover-bg));
176
+ color: var(--on-secondary, var(--primary-text));
177
+ }
178
+
179
+ &:focus-visible {
180
+ @include focus-outline;
181
+ outline-offset: 2px;
74
182
  }
183
+ }
184
+
185
+ &.variant-tertiary {
186
+ background: var(--tertiary, var(--accent-btn));
187
+ color: var(--on-tertiary, var(--primary));
188
+ border: solid 1px var(--tertiary-border, var(--primary));
75
189
 
76
190
  &:hover {
191
+ background: var(--tertiary-hover, var(--accent-btn));
192
+ color: var(--on-tertiary-hover, var(--lightest));
193
+ }
194
+
195
+ &:focus, &.focused {
196
+ background-color: var(--tertiary-hover, var(--primary-hover-bg));
197
+ color: var(--on-tertiary, var(--primary-text));
198
+ }
199
+
200
+ &:focus-visible {
201
+ @include focus-outline;
202
+ outline-offset: 2px;
203
+ }
204
+ }
205
+
206
+ &.variant-link {
207
+ background: transparent;
208
+ color: var(--link);
209
+
210
+ &:hover, &._hover {
211
+ color: var(--lightest);
77
212
  background-color: var(--accent-btn);
78
213
  box-shadow: none;
79
214
  }
215
+
216
+ &:focus, &.focused {
217
+ @include focus-outline;
218
+ outline-offset: -2px;
219
+ background: transparent;
220
+ color: var(--link);
221
+ box-shadow: none;
222
+ }
223
+
224
+ &:focus-visible {
225
+ @include focus-outline;
226
+ outline-offset: 2px;
227
+ }
80
228
  }
81
229
 
82
- &.role-ghost {
230
+ &.variant-multi-action {
231
+ background: var(--accent-btn);
232
+ border: solid thin var(--primary);
233
+ color: var(--primary);
234
+ border-radius: 2px;
235
+ }
236
+
237
+ &.variant-ghost {
83
238
  padding: 0;
84
239
  background-color: transparent;
85
240
 
@@ -93,4 +248,41 @@ button {
93
248
  outline-offset: 0;
94
249
  }
95
250
  }
251
+
252
+ // Size styles
253
+ &.btn-small {
254
+ //:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
255
+ &, &:not(.btn-sm) {
256
+ line-height: 15px;
257
+ font-size: 12px;
258
+ min-height: 24px;
259
+
260
+ padding: 0 8px;
261
+ gap: 8px;
262
+ }
263
+ }
264
+
265
+ &.btn-medium {
266
+ //:not(.btn-sm) is being used to make the style more specific to override global styles. We may want to get rid of those styles at some point.
267
+ &, &:not(.btn-sm) {
268
+ line-height: 18px;
269
+ font-size: 14px;
270
+ min-height: 32px;
271
+
272
+ padding: 0 12px;
273
+ gap: 8px;
274
+ }
275
+ }
276
+
277
+ &.btn-large {
278
+ // This is the default size brought by the global button styling
279
+ &, &:not(.btn-sm) {
280
+ line-height: 20px;
281
+ font-size: 16px;
282
+ min-height: 40px;
283
+
284
+ padding: 0 16px;
285
+ gap: 12px;
286
+ }
287
+ }
96
288
  }</style>
@@ -1,18 +1,44 @@
1
+ import { RcIconType } from '@components/RcIcon/types';
2
+
1
3
  // TODO: 13211 Investigate why `InstanceType<typeof RcButton>` fails prod builds
2
4
  // export type RcButtonType = InstanceType<typeof RcButton>
3
5
  export type RcButtonType = {
4
6
  focus: () => void;
5
7
  }
6
8
 
7
- export type ButtonRoleProps = {
9
+ export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'link' | 'multiAction' | 'ghost';
10
+
11
+ export type ButtonVariantNewProps = {
12
+ variant?: ButtonVariant;
13
+ }
14
+
15
+ /**
16
+ * @deprecated Use the `variant` property instead. These boolean props will be removed in a future version.
17
+ */
18
+ export type ButtonVariantProps = {
8
19
  primary?: boolean;
9
20
  secondary?: boolean;
10
21
  tertiary?: boolean;
11
22
  link?: boolean;
12
23
  multiAction?: boolean;
13
24
  ghost?: boolean;
25
+
14
26
  }
15
27
 
28
+ export type ButtonSize = 'small' | 'medium' | 'large';
29
+
30
+ export type ButtonSizeNewProps = {
31
+ size?: ButtonSize;
32
+ }
33
+
34
+ /**
35
+ * @deprecated Use the `size` property instead. The `small` boolean prop will be removed in a future version.
36
+ */
16
37
  export type ButtonSizeProps = {
17
38
  small?: boolean;
18
39
  }
40
+
41
+ export type IconProps = {
42
+ leftIcon?: RcIconType;
43
+ rightIcon?: RcIconType;
44
+ }
@@ -9,8 +9,8 @@ import { RcDropdownMenuComponentProps, DropdownOption } from './types';
9
9
  import IconOrSvg from '@shell/components/IconOrSvg';
10
10
 
11
11
  withDefaults(defineProps<RcDropdownMenuComponentProps>(), {
12
- buttonRole: 'primary',
13
- buttonSize: undefined,
12
+ buttonVariant: 'primary',
13
+ buttonSize: undefined,
14
14
  });
15
15
 
16
16
  const emit = defineEmits(['update:open', 'select']);
@@ -26,8 +26,8 @@ const hasOptions = (options: DropdownOption[]) => {
26
26
  @update:open="(e: boolean) => emit('update:open', e)"
27
27
  >
28
28
  <rc-dropdown-trigger
29
- :[buttonRole]="true"
30
- :[buttonSize]="true"
29
+ :variant="buttonVariant"
30
+ :size="buttonSize"
31
31
  :data-testid="dataTestid"
32
32
  :aria-label="buttonAriaLabel"
33
33
  >
@@ -1,6 +1,6 @@
1
1
  import { Ref, ref } from 'vue';
2
2
  import type { RcButtonType } from '@components/RcButton';
3
- import { ButtonRoleProps, ButtonSizeProps } from '@components/RcButton/types';
3
+ import { ButtonVariant, ButtonSize } from '@components/RcButton/types';
4
4
 
5
5
  export type DropdownContext = {
6
6
  handleKeydown: () => void;
@@ -41,8 +41,8 @@ export type DropdownOption = {
41
41
 
42
42
  export type RcDropdownMenuComponentProps = {
43
43
  options: DropdownOption[];
44
- buttonRole?: keyof ButtonRoleProps;
45
- buttonSize?: keyof ButtonSizeProps;
44
+ buttonVariant?: ButtonVariant;
45
+ buttonSize?: ButtonSize;
46
46
  buttonAriaLabel?: string;
47
47
  dropdownAriaLabel?: string;
48
48
  dataTestid?: string;
@@ -48,4 +48,46 @@ describe('rcIcon.vue', () => {
48
48
 
49
49
  expect(wrapper.attributes('aria-hidden')).toBe('true');
50
50
  });
51
+
52
+ it('defaults the color to "inherit" when the status prop is omitted', () => {
53
+ const wrapper = shallowMount(RcIcon, {
54
+ props: {
55
+ size: 'medium',
56
+ type: 'search',
57
+ },
58
+ });
59
+
60
+ const vm = wrapper.vm as unknown as { color: string };
61
+
62
+ expect(vm.color).toBe('inherit');
63
+ });
64
+
65
+ it('uses "inherit" color when status is explicitly set to "inherit"', () => {
66
+ const wrapper = shallowMount(RcIcon, {
67
+ props: {
68
+ size: 'medium',
69
+ type: 'search',
70
+ status: 'inherit'
71
+ },
72
+ });
73
+
74
+ const vm = wrapper.vm as unknown as { color: string };
75
+
76
+ expect(vm.color).toBe('inherit');
77
+ });
78
+
79
+ it('uses appropriate color when status is provided with a specific value', () => {
80
+ const wrapper = shallowMount(RcIcon, {
81
+ props: {
82
+ size: 'medium',
83
+ type: 'search',
84
+ status: 'success'
85
+ },
86
+ });
87
+
88
+ const vm = wrapper.vm as unknown as { color: string };
89
+
90
+ expect(vm.color).not.toBe('inherit');
91
+ expect(vm.color).toContain('--rc-success');
92
+ });
51
93
  });
@@ -1,14 +1,17 @@
1
1
  <script setup lang="ts">
2
- import { RcIconProps, RcIconType, RcIconSize } from '@components/RcIcon/types';
2
+ import { RcIconSizeToCSS, RcIconTypeToClass, RcIconProps } from './types';
3
3
  import { computed } from 'vue';
4
4
  import { useStatusColors } from '@components/utils/status';
5
- const props = withDefaults(defineProps<RcIconProps>(), { size: 'small', ariaHidden: true });
5
+
6
+ const props = withDefaults(defineProps<RcIconProps>(), {
7
+ size: 'small', ariaHidden: true, status: 'inherit'
8
+ });
6
9
  const fontSize = computed(() => {
7
- return RcIconSize[props.size];
10
+ return RcIconSizeToCSS[props.size];
8
11
  });
9
12
 
10
13
  const iconClass = computed(() => {
11
- return RcIconType[props.type];
14
+ return RcIconTypeToClass[props.type];
12
15
  });
13
16
 
14
17
  const status = computed(() => {
@@ -19,10 +22,10 @@ const status = computed(() => {
19
22
  return 'none';
20
23
  });
21
24
 
22
- const { textColor } = useStatusColors({ status: status.value }, 'outlined');
25
+ const { textColor } = useStatusColors(status, 'outlined');
23
26
 
24
27
  const color = computed(() => {
25
- if (props.status === 'inherit') {
28
+ if (props.status === undefined || props.status === 'inherit') {
26
29
  return 'inherit';
27
30
  }
28
31
 
@@ -1,6 +1,6 @@
1
- import { Status } from '../utils/status';
1
+ import { Status } from '@components/utils/status';
2
2
 
3
- export const RcIconType = {
3
+ export const RcIconTypeToClass = {
4
4
  actions: 'icon-actions',
5
5
  ai: 'icon-ai',
6
6
  'alert-alt': 'icon-alert-alt',
@@ -145,16 +145,20 @@ export const RcIconType = {
145
145
  windows: 'icon-windows',
146
146
  };
147
147
 
148
- export const RcIconSize = {
149
- large: '25px',
150
- medium: '18px',
151
- small: '14px',
152
- none: undefined
148
+ export const RcIconSizeToCSS = {
149
+ large: '25px',
150
+ medium: '18px',
151
+ small: '14px',
152
+ inherit: 'inherit'
153
153
  };
154
154
 
155
+ export type RcIconSize = keyof typeof RcIconSizeToCSS;
156
+
157
+ export type RcIconType = keyof typeof RcIconTypeToClass;
158
+
155
159
  export interface RcIconProps {
156
- size: keyof typeof RcIconSize;
157
- type: keyof typeof RcIconType;
160
+ type: RcIconType;
161
+ size?: RcIconSize;
158
162
  ariaHidden?: boolean;
159
163
  status?: Status | 'inherit';
160
164
  }
@@ -1,5 +1,5 @@
1
1
 
2
- import { reactive } from 'vue';
2
+ import { ref } from 'vue';
3
3
  import { wrapIfVar, useStatusColors, Status } from './status';
4
4
 
5
5
  describe('utils: status', () => {
@@ -18,20 +18,22 @@ describe('utils: status', () => {
18
18
  });
19
19
 
20
20
  describe('useStatusColors', () => {
21
- it.each([
21
+ const statuses: Status[] = [
22
22
  'info',
23
23
  'success',
24
24
  'warning',
25
25
  'error',
26
26
  'unknown',
27
27
  'none'
28
- ])('solid: should return the correct colors for status: %p', (status: Status) => {
29
- const props = reactive({ status });
28
+ ];
29
+
30
+ it.each(statuses)('solid: should return the correct colors for status: %p', (status) => {
31
+ const statusRef = ref(status as Status);
30
32
  const {
31
33
  borderColor,
32
34
  backgroundColor,
33
35
  textColor
34
- } = useStatusColors(props, 'solid');
36
+ } = useStatusColors(statusRef, 'solid');
35
37
 
36
38
  expect(borderColor.value).toBe(`var(--rc-${ status })`);
37
39
  if (status !== 'none') {
@@ -41,20 +43,13 @@ describe('utils: status', () => {
41
43
  expect(textColor.value).toBe(`var(--rc-${ status }-secondary)`);
42
44
  });
43
45
 
44
- it.each([
45
- 'info',
46
- 'success',
47
- 'warning',
48
- 'error',
49
- 'unknown',
50
- 'none'
51
- ])('outlined: should return the correct colors for status: %p', (status: Status) => {
52
- const props = reactive({ status });
46
+ it.each(statuses)('outlined: should return the correct colors for status: %p', (status) => {
47
+ const statusRef = ref(status as Status);
53
48
  const {
54
49
  borderColor,
55
50
  backgroundColor,
56
51
  textColor
57
- } = useStatusColors(props, 'outlined');
52
+ } = useStatusColors(statusRef, 'outlined');
58
53
 
59
54
  expect(borderColor.value).toBe(`var(--rc-${ status }-secondary)`);
60
55
  if (status !== 'none') {
@@ -1,4 +1,4 @@
1
- import { computed } from 'vue';
1
+ import { computed, Ref } from 'vue';
2
2
 
3
3
  export const StatusDefinitions = {
4
4
  info: {
@@ -28,7 +28,6 @@ export const StatusDefinitions = {
28
28
  };
29
29
 
30
30
  export type Status = keyof typeof StatusDefinitions;
31
- export type StatusObject = { status: Status };
32
31
  export type Style = 'solid' | 'outlined';
33
32
 
34
33
  export function wrapIfVar(colorVar: string) {
@@ -38,13 +37,13 @@ export function wrapIfVar(colorVar: string) {
38
37
  /**
39
38
  * A composable to make it easier to use status colors in multiple components
40
39
  *
41
- * @param propsWithStatus The props which contain a `status: Status` property. Ideally I'd prefer to just pass status but doing so either forces the consumer to wrap the values in a Ref or this code is no longer reactive.
40
+ * @param status A Ref containing the status value
42
41
  * @param style {@link Style} Will the block of code being using the solid or outlined styling
43
42
  * @returns An object containing the relevant style colors
44
43
  */
45
- export function useStatusColors(propsWithStatus: StatusObject, style: Style) {
44
+ export function useStatusColors(status: Ref<Status>, style: Style) {
46
45
  const statusColors = computed(() => {
47
- return StatusDefinitions[propsWithStatus.status];
46
+ return StatusDefinitions[status.value];
48
47
  });
49
48
  const isOutlined = style === 'outlined';
50
49
 
@@ -55,7 +54,7 @@ export function useStatusColors(propsWithStatus: StatusObject, style: Style) {
55
54
  });
56
55
 
57
56
  const backgroundColor = computed(() => {
58
- if (propsWithStatus.status === 'none') {
57
+ if (status.value === 'none') {
59
58
  return 'none';
60
59
  }
61
60
  const colorVar = isOutlined ? statusColors.value.secondary : statusColors.value.primary;
package/store/aws.js CHANGED
@@ -2,6 +2,7 @@ import { sortBy } from '@shell/utils/sort';
2
2
  import { randomStr } from '@shell/utils/string';
3
3
  import { FetchHttpHandler } from '@smithy/fetch-http-handler';
4
4
  import { isArray, addObjects } from '@shell/utils/array';
5
+ import { formatAWSError } from '@shell/utils/error';
5
6
 
6
7
  export const state = () => {
7
8
  return {
@@ -247,21 +248,26 @@ export const actions = {
247
248
  opt = opt || {};
248
249
 
249
250
  while ( hasNext ) {
250
- const res = await client[cmd](opt);
251
+ try {
252
+ const res = await client[cmd](opt);
251
253
 
252
- if ( !key ) {
253
- key = Object.keys(res).find((x) => isArray(res[x]));
254
- }
254
+ if ( !key ) {
255
+ key = Object.keys(res).find((x) => isArray(res[x]));
256
+ }
255
257
 
256
- addObjects(out, res[key]);
257
- if (res.NextToken) {
258
- opt.NextToken = res.NextToken;
259
- hasNext = true;
260
- } else if (res.Marker) {
261
- opt.Marker = res.Marker;
262
- hasNext = true;
263
- } else {
258
+ addObjects(out, res[key]);
259
+ if (res.NextToken) {
260
+ opt.NextToken = res.NextToken;
261
+ hasNext = true;
262
+ } else if (res.Marker) {
263
+ opt.Marker = res.Marker;
264
+ hasNext = true;
265
+ } else {
266
+ hasNext = false;
267
+ }
268
+ } catch (err) {
264
269
  hasNext = false;
270
+ throw formatAWSError(err);
265
271
  }
266
272
  }
267
273
 
package/store/index.js CHANGED
@@ -36,7 +36,8 @@ import { sortBy } from '@shell/utils/sort';
36
36
  import { addParam } from '@shell/utils/url';
37
37
  import semver from 'semver';
38
38
  import { STORE, BLANK_CLUSTER } from '@shell/store/store-types';
39
- import { isDevBuild } from '@shell/utils/version';
39
+ import { getReleaseNotesURL } from '@shell/utils/version';
40
+ import { getVersionData } from '@shell/config/version';
40
41
  import { markRaw } from 'vue';
41
42
  import paginationUtils from '@shell/utils/pagination-utils';
42
43
  import { addReleaseNotesNotification } from '@shell/utils/release-notes';
@@ -628,14 +629,9 @@ export const getters = {
628
629
 
629
630
  releaseNotesUrl(state, getters) {
630
631
  const version = getters['management/byId'](MANAGEMENT.SETTING, SETTING.VERSION_RANCHER)?.value;
632
+ const isPrime = getVersionData().RancherPrime === 'true';
631
633
 
632
- const base = 'https://github.com/rancher/rancher/releases';
633
-
634
- if (version && !isDevBuild(version)) {
635
- return `${ base }/tag/${ version }`;
636
- }
637
-
638
- return `${ base }/latest`;
634
+ return getReleaseNotesURL(isPrime, version);
639
635
  },
640
636
 
641
637
  ...gcGetters
@@ -142,7 +142,7 @@ export function headerFromSchemaColString(colName: string, schema: Schema, rootG
142
142
  export function headerFromSchemaCol(col: SchemaAttributeColumn, rootGetters: VuexStoreGetters, pagination: boolean, ageColumn: TableColumn): TableColumn {
143
143
  let formatter, width, formatterOpts;
144
144
 
145
- if ( (col.format === '' || col.format === 'date') && col.name === 'Age' && ageColumn ) {
145
+ if ( (col.format === '' || col.format === 'date' || col.type === 'date') && col.name.toLowerCase() === 'age' && ageColumn ) {
146
146
  return ageColumn;
147
147
  }
148
148