@rancher/shell 3.0.2-rc.5 → 3.0.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 (219) hide show
  1. package/assets/images/providers/nutanix.svg +12 -1
  2. package/assets/styles/base/_basic.scss +2 -1
  3. package/assets/styles/base/_helpers.scss +4 -0
  4. package/assets/styles/base/_variables.scss +2 -0
  5. package/assets/styles/global/_labeled-input.scss +5 -13
  6. package/assets/styles/global/_layout.scss +4 -1
  7. package/assets/styles/global/_select.scss +5 -0
  8. package/assets/styles/themes/_dark.scss +1 -3
  9. package/assets/styles/themes/_light.scss +5 -1
  10. package/assets/translations/en-us.yaml +130 -23
  11. package/assets/translations/zh-hans.yaml +0 -3
  12. package/cloud-credential/azure.vue +1 -1
  13. package/components/ActionMenuShell.vue +105 -0
  14. package/components/AppModal.vue +2 -2
  15. package/components/AsyncButton.vue +2 -0
  16. package/components/ButtonGroup.vue +9 -2
  17. package/components/ClusterBadge.vue +1 -0
  18. package/components/ClusterIconMenu.vue +3 -0
  19. package/components/ClusterProviderIcon.vue +14 -1
  20. package/components/CodeMirror.vue +96 -5
  21. package/components/Collapse.vue +16 -3
  22. package/components/CruResource.vue +9 -0
  23. package/components/CruResourceFooter.vue +1 -1
  24. package/components/ExplorerMembers.vue +2 -1
  25. package/components/FixedBanner.vue +19 -12
  26. package/components/Import.vue +14 -1
  27. package/components/LandingPagePreference.vue +4 -2
  28. package/components/PodSecurityAdmission.vue +8 -6
  29. package/components/PromptChangePassword.vue +1 -0
  30. package/components/PromptRemove.vue +23 -21
  31. package/components/ResourceDetail/Masthead.vue +30 -11
  32. package/components/ResourceDetail/__tests__/Masthead.test.ts +61 -0
  33. package/components/ResourceDetail/index.vue +6 -0
  34. package/components/ResourceTable.vue +6 -1
  35. package/components/ResourceYaml.vue +1 -0
  36. package/components/Setting.vue +115 -0
  37. package/components/SortableTable/THead.vue +2 -0
  38. package/components/SortableTable/index.vue +7 -12
  39. package/components/StatusBadge.vue +71 -0
  40. package/components/Tabbed/index.vue +16 -15
  41. package/components/Wizard.vue +108 -104
  42. package/components/YamlEditor.vue +12 -2
  43. package/components/__tests__/Collapse.test.ts +2 -2
  44. package/components/__tests__/FixedBanner.test.ts +3 -3
  45. package/components/auth/Principal.vue +29 -17
  46. package/components/auth/__tests__/Principal.test.ts +40 -0
  47. package/components/auth/login/ldap.vue +7 -0
  48. package/components/fleet/FleetBundles.vue +1 -1
  49. package/components/fleet/FleetRepos.vue +1 -1
  50. package/components/fleet/FleetResources.vue +0 -2
  51. package/components/fleet/FleetSummary.vue +60 -65
  52. package/components/fleet/ForceDirectedTreeChart/index.vue +5 -1
  53. package/components/fleet/__tests__/FleetSummary.test.ts +49 -9
  54. package/components/form/ArrayList.vue +6 -2
  55. package/components/form/ColorInput.vue +1 -0
  56. package/components/form/KeyValue.vue +11 -12
  57. package/components/form/LabeledSelect.vue +15 -3
  58. package/components/form/Labels.vue +8 -1
  59. package/components/form/Members/MembershipEditor.vue +230 -222
  60. package/components/form/Members/__tests__/MembershipEditor.test.ts +62 -0
  61. package/components/form/Password.vue +3 -0
  62. package/components/form/ProjectMemberEditor.vue +6 -3
  63. package/components/form/ResourceTabs/index.vue +15 -13
  64. package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +5 -4
  65. package/components/form/SchedulingCustomization.vue +85 -0
  66. package/components/form/Select.vue +3 -2
  67. package/components/form/SelectOrCreateAuthSecret.vue +2 -1
  68. package/components/form/UnitInput.vue +3 -4
  69. package/components/form/__tests__/ArrayList.test.ts +9 -6
  70. package/components/form/__tests__/LabeledSelect.test.ts +37 -0
  71. package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +34 -0
  72. package/components/form/__tests__/UnitInput.test.ts +4 -5
  73. package/components/formatter/LiveDate.vue +3 -1
  74. package/components/formatter/ServiceType.vue +12 -4
  75. package/components/formatter/WorkloadHealthScale.vue +2 -1
  76. package/components/nav/Header.vue +35 -2
  77. package/components/nav/HeaderPageActionMenu.vue +11 -40
  78. package/components/nav/Jump.vue +8 -2
  79. package/components/nav/NamespaceFilter.vue +5 -4
  80. package/components/nav/Pinned.vue +1 -1
  81. package/components/nav/TopLevelMenu.helper.ts +5 -5
  82. package/components/nav/TopLevelMenu.vue +1 -12
  83. package/components/nav/WindowManager/ContainerLogs.vue +96 -58
  84. package/components/nav/WindowManager/ContainerShell.vue +99 -18
  85. package/components/nav/WindowManager/index.vue +74 -6
  86. package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
  87. package/components/templates/default.vue +2 -47
  88. package/config/features.js +1 -0
  89. package/config/labels-annotations.js +11 -1
  90. package/config/router/navigation-guards/index.js +2 -1
  91. package/config/router/navigation-guards/record-last-route.js +24 -0
  92. package/config/settings.ts +66 -98
  93. package/config/version.js +1 -1
  94. package/core/types-provisioning.ts +7 -0
  95. package/detail/fleet.cattle.io.bundle.vue +7 -0
  96. package/detail/fleet.cattle.io.cluster.vue +0 -3
  97. package/detail/fleet.cattle.io.gitrepo.vue +8 -15
  98. package/detail/provisioning.cattle.io.cluster.vue +8 -2
  99. package/dialog/DeactivateDriverDialog.vue +5 -5
  100. package/dialog/GitRepoForceUpdateDialog.vue +132 -0
  101. package/directives/strip-html-aria-label.js +19 -0
  102. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +87 -0
  103. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +217 -37
  104. package/edit/auth/__tests__/oidc.test.ts +60 -12
  105. package/edit/auth/ldap/__tests__/config.test.ts +40 -0
  106. package/edit/auth/ldap/config.vue +67 -89
  107. package/edit/auth/oidc.vue +16 -2
  108. package/edit/catalog.cattle.io.clusterrepo.vue +12 -8
  109. package/edit/cis.cattle.io.clusterscan.vue +13 -1
  110. package/edit/fleet.cattle.io.gitrepo.vue +198 -72
  111. package/edit/logging-flow/Match.vue +0 -21
  112. package/edit/management.cattle.io.project.vue +1 -1
  113. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +10 -3
  114. package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +5 -1
  115. package/edit/monitoring.coreos.com.prometheusrule/index.vue +5 -2
  116. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +8 -1
  117. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +2 -0
  118. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -2
  119. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +55 -15
  120. package/edit/provisioning.cattle.io.cluster/index.vue +28 -30
  121. package/edit/provisioning.cattle.io.cluster/rke2.vue +64 -13
  122. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +37 -2
  123. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +3 -2
  124. package/edit/resources.cattle.io.backup.vue +150 -15
  125. package/edit/secret/__tests__/ssh.test.ts +79 -0
  126. package/edit/secret/ssh.vue +7 -1
  127. package/edit/service.vue +0 -3
  128. package/edit/workload/Job.vue +8 -8
  129. package/edit/workload/__tests__/Job.test.ts +0 -1
  130. package/edit/workload/index.vue +3 -1
  131. package/initialize/install-directives.js +2 -0
  132. package/initialize/install-plugins.js +6 -1
  133. package/list/catalog.cattle.io.app.vue +21 -4
  134. package/list/fleet.cattle.io.bundle.vue +1 -1
  135. package/list/management.cattle.io.setting.vue +34 -132
  136. package/list/provisioning.cattle.io.cluster.vue +11 -3
  137. package/machine-config/vmwarevsphere.vue +15 -8
  138. package/mixins/__tests__/auth-config.test.ts +74 -0
  139. package/mixins/__tests__/chart.test.ts +5 -4
  140. package/mixins/__tests__/create-edit-view.test.ts +38 -0
  141. package/mixins/auth-config.js +8 -0
  142. package/mixins/chart.js +2 -2
  143. package/mixins/create-edit-view/impl.js +4 -1
  144. package/mixins/vue-select-overrides.js +10 -0
  145. package/models/__tests__/catalog.cattle.io.app.test.ts +148 -0
  146. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +157 -0
  147. package/models/__tests__/secret.test.ts +56 -13
  148. package/models/catalog.cattle.io.app.js +112 -37
  149. package/models/cluster.js +11 -0
  150. package/models/fleet.cattle.io.bundle.js +40 -2
  151. package/models/fleet.cattle.io.gitrepo.js +169 -109
  152. package/models/management.cattle.io.fleetworkspace.js +4 -0
  153. package/models/management.cattle.io.kontainerdriver.js +7 -0
  154. package/models/nodedriver.js +4 -1
  155. package/models/provisioning.cattle.io.cluster.js +24 -0
  156. package/models/secret.js +1 -1
  157. package/package.json +5 -5
  158. package/pages/auth/login.vue +5 -11
  159. package/pages/auth/verify.vue +11 -1
  160. package/pages/c/_cluster/apps/charts/index.vue +6 -4
  161. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  162. package/pages/c/_cluster/explorer/ConfigBadge.vue +3 -5
  163. package/pages/c/_cluster/explorer/EventsTable.vue +3 -2
  164. package/pages/c/_cluster/explorer/__tests__/index.test.ts +9 -9
  165. package/pages/c/_cluster/explorer/index.vue +33 -35
  166. package/pages/c/_cluster/explorer/tools/index.vue +3 -3
  167. package/pages/c/_cluster/fleet/index.vue +0 -5
  168. package/pages/c/_cluster/legacy/project/index.vue +1 -1
  169. package/pages/c/_cluster/settings/performance.vue +52 -53
  170. package/pages/c/_cluster/uiplugins/index.vue +19 -22
  171. package/pages/home.vue +17 -12
  172. package/pages/prefs.vue +5 -1
  173. package/plugins/shortkey.js +10 -1
  174. package/plugins/steve/steve-pagination-utils.ts +58 -8
  175. package/promptRemove/management.cattle.io.fleetworkspace.vue +98 -0
  176. package/promptRemove/management.cattle.io.globalrole.vue +1 -1
  177. package/promptRemove/management.cattle.io.project.vue +2 -8
  178. package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
  179. package/promptRemove/mixin/roleDeletionCheck.js +1 -7
  180. package/promptRemove/pod.vue +7 -28
  181. package/rancher-components/Card/Card.vue +9 -1
  182. package/rancher-components/Form/Checkbox/Checkbox.vue +42 -6
  183. package/rancher-components/Form/LabeledInput/LabeledInput.vue +30 -3
  184. package/rancher-components/Form/Radio/RadioButton.vue +18 -3
  185. package/rancher-components/Form/Radio/RadioGroup.vue +39 -5
  186. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +13 -1
  187. package/rancher-components/RcButton/RcButton.test.ts +97 -0
  188. package/rancher-components/RcButton/RcButton.vue +14 -9
  189. package/rancher-components/RcDropdown/RcDropdown.vue +3 -1
  190. package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -2
  191. package/rancher-components/RcDropdown/RcDropdownMenu.vue +66 -0
  192. package/rancher-components/RcDropdown/index.ts +1 -0
  193. package/rancher-components/RcDropdown/types.ts +27 -0
  194. package/rancher-components/RcDropdown/useDropdownContext.ts +5 -2
  195. package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +2 -2
  196. package/scripts/typegen.sh +1 -0
  197. package/store/__tests__/auth.test.ts +120 -0
  198. package/store/action-menu.js +13 -3
  199. package/store/auth.js +14 -9
  200. package/store/aws.js +9 -2
  201. package/store/catalog.js +14 -7
  202. package/store/features.js +1 -0
  203. package/store/prefs.js +9 -28
  204. package/store/type-map.utils.ts +4 -0
  205. package/types/resources/settings.d.ts +27 -20
  206. package/types/shell/index.d.ts +18 -12
  207. package/utils/__tests__/array.test.ts +13 -1
  208. package/utils/__tests__/string.test.ts +80 -1
  209. package/utils/array.ts +13 -0
  210. package/utils/auth.js +4 -0
  211. package/utils/banners.js +0 -45
  212. package/utils/cluster.js +1 -1
  213. package/{edit/monitoring.coreos.com.prometheusrule → utils}/duration.js +5 -3
  214. package/utils/object.js +0 -3
  215. package/utils/pagination-utils.ts +15 -2
  216. package/utils/string.js +31 -7
  217. package/utils/validators/formRules/__tests__/index.test.ts +27 -0
  218. package/utils/validators/formRules/index.ts +16 -0
  219. package/edit/provisioning.cattle.io.cluster/import.vue +0 -198
package/store/auth.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { GITHUB_NONCE, GITHUB_REDIRECT, GITHUB_SCOPE } from '@shell/config/query-params';
2
2
  import { NORMAN } from '@shell/config/types';
3
3
  import { _MULTI } from '@shell/plugins/dashboard-store/actions';
4
- import { addObjects, findBy } from '@shell/utils/array';
4
+ import { addObjects, findBy, joinStringList } from '@shell/utils/array';
5
5
  import { openAuthPopup, returnTo } from '@shell/utils/auth';
6
6
  import { base64Encode } from '@shell/utils/crypto';
7
7
  import { removeEmberPage } from '@shell/utils/ember-page';
@@ -18,12 +18,12 @@ export const BASE_SCOPES = {
18
18
 
19
19
  const KEY = 'rc_nonce';
20
20
 
21
- const ERR_NONCE = 'nonce';
22
-
23
21
  export const LOGIN_ERRORS = {
24
22
  CLIENT: 'client',
25
23
  CLIENT_UNAUTHORIZED: 'client_unauthorized',
26
- SERVER: 'server'
24
+ SERVER: 'server',
25
+ NONCE: 'nonce',
26
+ USER_UNAUTHORIZED: 'user_unauthorized',
27
27
  };
28
28
 
29
29
  export const state = function() {
@@ -230,18 +230,22 @@ export const actions = {
230
230
  const encodedNonce = await dispatch('encodeNonce', baseNonce);
231
231
 
232
232
  const fromQuery = unescape(parseUrl(redirectUrl).query?.[GITHUB_SCOPE] || '');
233
- const scopes = fromQuery.split(/[, ]+/).filter((x) => !!x);
233
+ let scopes = fromQuery.split(/[, ]+/).filter((x) => !!x);
234
234
 
235
235
  if (BASE_SCOPES[provider]) {
236
236
  addObjects(scopes, BASE_SCOPES[provider]);
237
237
  }
238
238
 
239
- if ( opt.scopes ) {
240
- addObjects(scopes, opt.scopes);
239
+ // Need to merge these 2 formats preventing duplicates between code and UI, e.g.
240
+ // [ 'openid profile email' ] from BASE_SCOPES
241
+ // 'openid profile email customScope' from the UI
242
+ if (opt.scopes) {
243
+ scopes = [joinStringList(scopes[0], opt.scopes)];
241
244
  }
242
245
 
243
246
  let url = removeParam(redirectUrl, GITHUB_SCOPE);
244
247
 
248
+ // TODO: #13457 - Verify use case of scopesJoinChar anywhere outside this repository
245
249
  const params = {
246
250
  [GITHUB_SCOPE]: scopes.join(opt.scopesJoinChar || ','), // Some providers won't accept comma separated scopes
247
251
  [GITHUB_NONCE]: encodedNonce
@@ -267,13 +271,13 @@ export const actions = {
267
271
  try {
268
272
  parsed = JSON.parse(expectJSON);
269
273
  } catch {
270
- return ERR_NONCE;
274
+ return LOGIN_ERRORS.NONCE;
271
275
  }
272
276
 
273
277
  const expect = parsed.nonce;
274
278
 
275
279
  if ( !expect || expect !== nonce ) {
276
- return ERR_NONCE;
280
+ return LOGIN_ERRORS.NONCE;
277
281
  }
278
282
 
279
283
  const body = { code };
@@ -310,6 +314,7 @@ export const actions = {
310
314
  const url = await dispatch('redirectTo', {
311
315
  provider,
312
316
  redirectUrl,
317
+ scopes: body.scope,
313
318
  test: true,
314
319
  redirect: false
315
320
  });
package/store/aws.js CHANGED
@@ -241,8 +241,15 @@ export const actions = {
241
241
  }
242
242
 
243
243
  addObjects(out, res[key]);
244
- opt.NextToken = res.NextToken;
245
- hasNext = !!res.NextToken;
244
+ if (res.NextToken) {
245
+ opt.NextToken = res.NextToken;
246
+ hasNext = true;
247
+ } else if (res.Marker) {
248
+ opt.Marker = res.Marker;
249
+ hasNext = true;
250
+ } else {
251
+ hasNext = false;
252
+ }
246
253
  }
247
254
 
248
255
  return out;
package/store/catalog.js CHANGED
@@ -31,6 +31,13 @@ const CERTIFIED_SORTS = {
31
31
  other: 3,
32
32
  };
33
33
 
34
+ export const APP_UPGRADE_STATUS = {
35
+ NOT_APPLICABLE: 'not_applicable', // managed by fleet
36
+ NO_UPGRADE: 'no_upgrade', // no upgrade found
37
+ SINGLE_UPGRADE: 'single_upgrade', // a version available to upgrade to
38
+ MULTIPLE_UPGRADES: 'multiple_upgrades' // more than one match found
39
+ };
40
+
34
41
  export const WINDOWS = 'windows';
35
42
  export const LINUX = 'linux';
36
43
 
@@ -101,7 +108,7 @@ export const getters = {
101
108
 
102
109
  chart(state, getters) {
103
110
  return ({
104
- key, repoType, repoName, chartName, preferRepoType, preferRepoName, includeHidden, showDeprecated
111
+ key, repoType, repoName, chartName, includeHidden, showDeprecated, multiple
105
112
  }) => {
106
113
  if ( key && !repoType && !repoName && !chartName) {
107
114
  const parsed = parseKey(key);
@@ -111,7 +118,7 @@ export const getters = {
111
118
  chartName = parsed.chartName;
112
119
  }
113
120
 
114
- let matching = filterBy(getters.charts, {
121
+ let matchingCharts = filterBy(getters.charts, {
115
122
  repoType,
116
123
  repoName,
117
124
  chartName,
@@ -119,18 +126,18 @@ export const getters = {
119
126
  });
120
127
 
121
128
  if ( includeHidden === false ) {
122
- matching = matching.filter((x) => !x.hidden);
129
+ matchingCharts = matchingCharts.filter((x) => !x.hidden);
123
130
  }
124
131
 
125
- if ( !matching.length ) {
132
+ if ( !matchingCharts.length ) {
126
133
  return;
127
134
  }
128
135
 
129
- if ( preferRepoType && preferRepoName ) {
130
- preferSameRepo(matching, preferRepoType, preferRepoName);
136
+ if (multiple) {
137
+ return matchingCharts;
131
138
  }
132
139
 
133
- return matching[0];
140
+ return matchingCharts[0];
134
141
  };
135
142
  },
136
143
 
package/store/features.js CHANGED
@@ -36,6 +36,7 @@ export const FLEET_WORKSPACE_BACK = create('provisioningv2-fleet-workspace-back-
36
36
  export const STEVE_CACHE = create('ui-sql-cache', false);
37
37
  export const UIEXTENSION = create('uiextension', true);
38
38
  export const PROVISIONING_PRE_BOOTSTRAP = create('provisioningprebootstrap', false);
39
+ export const SCHEDULING_CUSTOMIZATION = create('cluster-agent-scheduling-customization', false);
39
40
 
40
41
  // Not currently used.. no point defining ones we don't use
41
42
  // export const EMBEDDED_CLUSTER_API = create('embedded-cluster-api', true);
package/store/prefs.js CHANGED
@@ -130,6 +130,7 @@ export const state = function() {
130
130
  cookiesLoaded: false,
131
131
  data: {},
132
132
  definitions,
133
+ authRedirect: null
133
134
  };
134
135
  };
135
136
 
@@ -215,6 +216,9 @@ export const getters = {
215
216
  case (afterLoginRoutePref === 'home'):
216
217
  return { name: 'home' };
217
218
  case (afterLoginRoutePref === 'last-visited'): {
219
+ if (state.authRedirect) {
220
+ return state.authRedirect;
221
+ }
218
222
  const lastVisitedPref = getters['get'](LAST_VISITED);
219
223
 
220
224
  if (lastVisitedPref) {
@@ -265,6 +269,10 @@ export const mutations = {
265
269
  setDefinition(state, { name, definition = {} }) {
266
270
  state.definitions[name] = definition;
267
271
  },
272
+
273
+ setAuthRedirect(state, route) {
274
+ state.authRedirect = route;
275
+ }
268
276
  };
269
277
 
270
278
  export const actions = {
@@ -491,9 +499,7 @@ export const actions = {
491
499
  return;
492
500
  }
493
501
 
494
- const toSave = getLoginRoute(route);
495
-
496
- return dispatch('set', { key: LAST_VISITED, value: toSave });
502
+ return dispatch('set', { key: LAST_VISITED, value: route });
497
503
  },
498
504
 
499
505
  toggleTheme({ getters, dispatch }) {
@@ -523,28 +529,3 @@ export const actions = {
523
529
  }
524
530
  }
525
531
  };
526
-
527
- function getLoginRoute(route) {
528
- let parts = route.name?.split('-') || [];
529
- const params = {};
530
- const routeParams = route.params || {};
531
-
532
- // Find the 'resource' part of the route, if it is there
533
- const index = parts.findIndex((p) => p === 'resource');
534
-
535
- if (index >= 0) {
536
- parts = parts.slice(0, index);
537
- }
538
-
539
- // Just keep the params that are needed
540
- parts.forEach((param) => {
541
- if (routeParams[param]) {
542
- params[param] = routeParams[param];
543
- }
544
- });
545
-
546
- return {
547
- name: parts.join('-'),
548
- params
549
- };
550
- }
@@ -123,6 +123,10 @@ export function createHeaders(
123
123
  * Given a schema's attribute.column value create a header
124
124
  */
125
125
  export function headerFromSchemaColString(colName: string, schema: Schema, rootGetters: VuexStoreGetters, pagination: boolean, ageColumn: TableColumn): TableColumn {
126
+ if (!schema) {
127
+ throw new Error(`Unable to create header for column '${ colName }' from schema: schema is missing`);
128
+ }
129
+
126
130
  const col = schema.attributes.columns.find((c) => c.name === colName);
127
131
 
128
132
  if (!col) {
@@ -1,3 +1,25 @@
1
+
2
+ export interface PaginationSettingsStore {
3
+ [name: string]: {
4
+ resources: {
5
+ /**
6
+ * Enable for all resources in this store
7
+ */
8
+ enableAll: boolean,
9
+ enableSome: {
10
+ /**
11
+ * Specific resource type to enable
12
+ */
13
+ enabled: (string | { resource: string, context: string[]})[],
14
+ /**
15
+ * There's no hardcoded headers or custom list for the resource type, headers will be generated from schema attributes.columns
16
+ */
17
+ generic: boolean,
18
+ },
19
+ }
20
+ }
21
+ }
22
+
1
23
  /**
2
24
  * Settings to handle server side pagination
3
25
  */
@@ -6,29 +28,14 @@ export interface PaginationSettings {
6
28
  * Global setting to enable or disable
7
29
  */
8
30
  enabled: boolean,
31
+ /**
32
+ * Override `stores` and apply pagination to a set of default resource types that can change between versions
33
+ */
34
+ useDefaultStores: boolean,
9
35
  /**
10
36
  * Should pagination be enabled for resources in a store
11
37
  */
12
- stores: {
13
- [name: string]: {
14
- resources: {
15
- /**
16
- * Enable for all resources in this store
17
- */
18
- enableAll: boolean,
19
- enableSome: {
20
- /**
21
- * Specific resource type to enable
22
- */
23
- enabled: (string | { resource: string, context: string[]})[],
24
- /**
25
- * There's no hardcoded headers or custom list for the resource type, headers will be generated from schema attributes.columns
26
- */
27
- generic: boolean,
28
- },
29
- }
30
- }
31
- }
38
+ stores: PaginationSettingsStore | undefined
32
39
  }
33
40
 
34
41
  type Links = {
@@ -42,6 +42,7 @@ export const RESOURCE_QUOTA: "field.cattle.io/resourceQuota";
42
42
  export const AZURE_MIGRATED: "auth.cattle.io/azuread-endpoint-migrated";
43
43
  export const WORKSPACE_ANNOTATION: "objectset.rio.cattle.io/id";
44
44
  export const NODE_ARCHITECTURE: "kubernetes.io/arch";
45
+ export const IMPORTED_CLUSTER_VERSION_MANAGEMENT: "rancher.io/imported-cluster-version-management";
45
46
  export namespace KUBERNETES {
46
47
  let SERVICE_ACCOUNT_UID: string;
47
48
  let SERVICE_ACCOUNT_NAME: string;
@@ -81,6 +82,7 @@ export namespace CAPI {
81
82
  let MACHINE_NAME: string;
82
83
  let DELETE_MACHINE: string;
83
84
  let PROVIDER: string;
85
+ let HUMAN_NAME: string;
84
86
  let SECRET_AUTH: string;
85
87
  let SECRET_WILL_DELETE: string;
86
88
  let UI_CUSTOM_PROVIDER: string;
@@ -122,6 +124,7 @@ export namespace CATALOG {
122
124
  let HIDDEN_REPO: string;
123
125
  }
124
126
  export namespace FLEET {
127
+ export let REPO_NAME: string;
125
128
  export let CLUSTER_DISPLAY_NAME: string;
126
129
  export let CLUSTER_NAME: string;
127
130
  export let BUNDLE_ID: string;
@@ -132,6 +135,8 @@ export namespace FLEET {
132
135
  let CLUSTER_NAMESPACE_1: string;
133
136
  export { CLUSTER_NAMESPACE_1 as CLUSTER_NAMESPACE };
134
137
  export let CLUSTER: string;
138
+ export let CREATED_BY_USER_ID: string;
139
+ export let CREATED_BY_USER_NAME: string;
135
140
  }
136
141
  export namespace RBAC {
137
142
  let PRODUCT: string;
@@ -2220,7 +2225,7 @@ export function getVersionData(): {
2220
2225
  export function setVersionData(v: any): void;
2221
2226
  export function getKubeVersionData(): {};
2222
2227
  export function setKubeVersionData(v: any): void;
2223
- export const CURRENT_RANCHER_VERSION: "2.10";
2228
+ export const CURRENT_RANCHER_VERSION: "2.11";
2224
2229
  }
2225
2230
 
2226
2231
  // @shell/mixins/create-edit-view/impl
@@ -3172,6 +3177,7 @@ export const FLEET_WORKSPACE_BACK: any;
3172
3177
  export const STEVE_CACHE: any;
3173
3178
  export const UIEXTENSION: any;
3174
3179
  export const PROVISIONING_PRE_BOOTSTRAP: any;
3180
+ export const SCHEDULING_CUSTOMIZATION: any;
3175
3181
  export namespace getters {
3176
3182
  function get(state: any, getters: any, rootState: any, rootGetters: any): (name: any) => any;
3177
3183
  }
@@ -3260,6 +3266,7 @@ export function state(): {
3260
3266
  cookiesLoaded: boolean;
3261
3267
  data: {};
3262
3268
  definitions: {};
3269
+ authRedirect: any;
3263
3270
  };
3264
3271
  export namespace getters {
3265
3272
  function get(state: any): (key: any) => any;
@@ -3280,6 +3287,7 @@ export namespace mutations {
3280
3287
  name: any;
3281
3288
  definition?: {};
3282
3289
  }): void;
3290
+ function setAuthRedirect(state: any, route: any): void;
3283
3291
  }
3284
3292
  export namespace actions {
3285
3293
  function set({ dispatch, commit, rootGetters, state }: {
@@ -3438,13 +3446,6 @@ export function getIndividualBanners(store: any): {};
3438
3446
  * Overlay settings from the individual banner settings onto the single banner setting
3439
3447
  */
3440
3448
  export function overlayIndividualBanners(parsedBanner: any, banners: any): void;
3441
- /**
3442
- * Get banner font sizes - used to add margins when header and footer banners are present
3443
- **/
3444
- export function getGlobalBannerFontSizes(store: any): {
3445
- headerFont: string;
3446
- footerFont: string;
3447
- };
3448
3449
  }
3449
3450
 
3450
3451
  // @shell/utils/clipboard
@@ -3785,6 +3786,13 @@ export function generateZip(files: any): any;
3785
3786
  export function downloadUrl(url: any, id?: string): void;
3786
3787
  }
3787
3788
 
3789
+ // @shell/utils/duration
3790
+
3791
+ declare module '@shell/utils/duration' {
3792
+ export function toMilliseconds(input: any): number;
3793
+ export function toSeconds(input: any): number;
3794
+ }
3795
+
3788
3796
  // @shell/utils/dynamic-importer
3789
3797
 
3790
3798
  declare module '@shell/utils/dynamic-importer' {
@@ -3986,9 +3994,6 @@ export function deepToRaw(obj: any, cache?: any): any;
3986
3994
  * More info: https://github.com/lodash/lodash/issues/1313
3987
3995
  *
3988
3996
  * This helper function addresses the issue by always replacing the old array with the new array during the merge process.
3989
- *
3990
- * This helper is used for another case in rke2.vue to handle merging addon chart default values with the user's current values.
3991
- * It fixed https://github.com/rancher/dashboard/issues/12418
3992
3997
  */
3993
3998
  export function mergeWithReplaceArrays(obj1?: {}, obj2?: {}): any;
3994
3999
  export { isEqualBasic as isEqual };
@@ -4356,7 +4361,7 @@ export function random32(count: any): number | number[];
4356
4361
  export function randomStr(length?: number, chars?: string): any;
4357
4362
  export function formatPercent(value: any, maxPrecision?: number): string;
4358
4363
  export function pluralize(str: any): any;
4359
- export function resourceNames(names: any, plusMore: any, t: any): any;
4364
+ export function resourceNames(names: any, t: any, options?: {}): any;
4360
4365
  export function indent(lines: any, count?: number, token?: string, afterRegex?: any): any;
4361
4366
  export function decamelize(str: any): any;
4362
4367
  export function dasherize(str: any): any;
@@ -4379,6 +4384,7 @@ export function sanitizeIP(v: any): any;
4379
4384
  */
4380
4385
  export function xOfy(x: any, y: any): string;
4381
4386
  export function isBase64(value: any): boolean;
4387
+ export function generateRandomAlphaString(length: any): string;
4382
4388
  export namespace CHARSET {
4383
4389
  export { num as NUMERIC };
4384
4390
  export let NO_VOWELS: string;
@@ -1,5 +1,5 @@
1
1
  import {
2
- addObject, addObjects, clear, filterBy, findBy, getUniqueLabelKeys, insertAt, isArray, removeAt, removeObject, removeObjects, replaceWith, sameContents, uniq
2
+ addObject, addObjects, clear, filterBy, findBy, getUniqueLabelKeys, insertAt, isArray, joinStringList, removeAt, removeObject, removeObjects, replaceWith, sameContents, uniq
3
3
  } from '@shell/utils/array';
4
4
 
5
5
  interface Obj {
@@ -500,3 +500,15 @@ describe('fx: getUniqueLabelKeys', () => {
500
500
  expect(result).toStrictEqual(expected);
501
501
  });
502
502
  });
503
+
504
+ describe('fx: joinStringList', () => {
505
+ it('should join two lists of strings', () => {
506
+ const a = 'a b c';
507
+ const b = 'b c d';
508
+ const separator = ' ';
509
+
510
+ const result = joinStringList(a, b, separator);
511
+
512
+ expect(result).toBe('a b c d');
513
+ });
514
+ });
@@ -1,4 +1,4 @@
1
- import { decodeHtml } from '@shell/utils/string';
1
+ import { decodeHtml, resourceNames } from '@shell/utils/string';
2
2
 
3
3
  describe('fx: decodeHtml', () => {
4
4
  it('should decode HTML values from escaped string into valid markup', () => {
@@ -10,3 +10,82 @@ describe('fx: decodeHtml', () => {
10
10
  expect(result).toStrictEqual(expectation);
11
11
  });
12
12
  });
13
+
14
+ describe('fx: resourceNames', () => {
15
+ // default plusMore function
16
+ const t = (key: string, options: { count: number }) => {
17
+ switch (key) {
18
+ case 'generic.and':
19
+ return ' and ';
20
+ case 'generic.comma':
21
+ return ', ';
22
+ case 'promptRemove.andOthers': {
23
+ if (options.count === 0) {
24
+ return '.';
25
+ }
26
+ if (options.count === 1) {
27
+ return 'and <b>one other</b>.';
28
+ }
29
+
30
+ return `and <b>${ options.count } others</b>.`;
31
+ }
32
+ }
33
+ };
34
+
35
+ describe.each([
36
+ ['no options',
37
+ [
38
+ [[], '', {}],
39
+ [['item1'], '<b>item1</b>.', {}],
40
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b>.', {}],
41
+ [['item1', 'item2', 'item3'], '<b>item1</b>, <b>item2</b> and <b>item3</b>.', {}],
42
+ [['item1', 'item2', 'item3', 'item4', 'item5'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b> and <b>item5</b>.', {}],
43
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>and <b>one other</b>.', {}],
44
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>and <b>2 others</b>.', {}],
45
+ ]
46
+ ],
47
+ ['plusMore option',
48
+ [
49
+ [[], '', { plusMore: 'foo' }],
50
+ [['item1'], '<b>item1</b>.', { plusMore: 'foo' }],
51
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b>.', { plusMore: 'foo' }],
52
+ [['item1', 'item2', 'item3'], '<b>item1</b>, <b>item2</b> and <b>item3</b>.', { plusMore: 'foo' }],
53
+ [['item1', 'item2', 'item3', 'item4', 'item5'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b> and <b>item5</b>.', { plusMore: 'foo' }],
54
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo' }],
55
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo' }],
56
+ ]
57
+ ],
58
+ ['endString option',
59
+ [
60
+ [[], '', { endString: false }],
61
+ [['item1'], '<b>item1</b> ', { endString: false }],
62
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b> ', { endString: false }],
63
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b>.', { endString: '' }],
64
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b>foo', { endString: 'foo' }],
65
+ ]
66
+ ],
67
+ [
68
+ 'plusMore & endString options', [
69
+ [[], '', { plusMore: '', endString: false }],
70
+ [[], '', { plusMore: 'foo', endString: 'foo' }],
71
+ [['item1'], '<b>item1</b>foo', { plusMore: 'foo', endString: 'foo' }],
72
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b>foo', { plusMore: 'foo', endString: 'foo' }],
73
+ [['item1', 'item2'], '<b>item1</b> and <b>item2</b> ', { plusMore: 'foo', endString: false }],
74
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo', endString: 'foo' }],
75
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo', endString: 'foo' }],
76
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo', endString: false }],
77
+ [['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7'], '<b>item1</b>, <b>item2</b>, <b>item3</b>, <b>item4</b>, <b>item5</b>foo', { plusMore: 'foo', endString: false }],
78
+ ]
79
+ ]
80
+ ])('should build a single message from a list of names, with: %p', (_, args) => {
81
+ it.each(args)(`having: %p`, (
82
+ names,
83
+ expectation,
84
+ options,
85
+ ) => {
86
+ const result = resourceNames(names, t, options);
87
+
88
+ expect(result).toStrictEqual(expectation);
89
+ });
90
+ });
91
+ });
package/utils/array.ts CHANGED
@@ -241,3 +241,16 @@ export function getUniqueLabelKeys<T extends KubeResource>(aryResources: T[]): s
241
241
 
242
242
  return Object.keys(uniqueObj).sort();
243
243
  }
244
+
245
+ /**
246
+ * Join list as string into a new string without duplicates
247
+ * @param {string} a 'a b c'
248
+ * @param {string} b 'b c d'
249
+ * @param {string} [separator=' ']
250
+ * @return {string} 'a b c d'
251
+ */
252
+ export const joinStringList = (a: string, b: string, separator = ' '): string => {
253
+ const all = a.split(separator).concat(b.split(separator));
254
+
255
+ return [...new Set(all)].join(separator);
256
+ };
package/utils/auth.js CHANGED
@@ -315,6 +315,10 @@ export function isLoggedIn(store, me) {
315
315
  export function notLoggedIn(store, redirect, route) {
316
316
  store.commit('auth/hasAuth', true);
317
317
 
318
+ if (!route.name.includes('auth')) {
319
+ store.commit('prefs/setAuthRedirect', route);
320
+ }
321
+
318
322
  if ( route.name === 'index' ) {
319
323
  return redirect('/auth/login');
320
324
  } else {
package/utils/banners.js CHANGED
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import { MANAGEMENT } from '@shell/config/types';
8
- import { SETTING } from '@shell/config/settings';
9
8
 
10
9
  const BANNER_HEADER = 'bannerHeader';
11
10
  const BANNER_FOOTER = 'bannerFooter';
@@ -57,47 +56,3 @@ export function overlayIndividualBanners(parsedBanner, banners) {
57
56
  } catch {}
58
57
  });
59
58
  }
60
-
61
- /**
62
- * Converts a pixel value to an em value based on the default font size.
63
- * @param {number} elementFontSize - The font size of the element in pixels.
64
- * @param {number} [defaultFontSize=14] - The default font size in pixels.
65
- * @returns {string} The converted value in em units.
66
- */
67
- function pxToEm(elementFontSize, defaultFontSize = 14) {
68
- const lineHeightInPx = 2 * parseInt(elementFontSize);
69
- const lineHeightInEm = lineHeightInPx / defaultFontSize;
70
-
71
- return `${ lineHeightInEm }em`;
72
- }
73
-
74
- /**
75
- * Get banner font sizes - used to add margins when header and footer banners are present
76
- **/
77
- export function getGlobalBannerFontSizes(store) {
78
- const settings = store.getters['management/all'](MANAGEMENT.SETTING);
79
- const bannerSettings = settings?.find((s) => s.id === SETTING.BANNERS);
80
- const individualBannerSettings = getIndividualBanners(store);
81
-
82
- if (bannerSettings) {
83
- const parsed = JSON.parse(bannerSettings.value);
84
-
85
- overlayIndividualBanners(parsed, individualBannerSettings);
86
-
87
- const {
88
- showFooter, showHeader, bannerFooter, bannerHeader, banner
89
- } = parsed;
90
-
91
- // add defaults to accommodate older JSON structures for banner definitions without breaking the UI
92
- // https://github.com/rancher/dashboard/issues/10140
93
- const bannerHeaderFontSize = bannerHeader?.fontSize || banner?.fontSize || '14px';
94
- const bannerFooterFontSize = bannerFooter?.fontSize || banner?.fontSize || '14px';
95
-
96
- return {
97
- headerFont: showHeader === 'true' ? pxToEm(bannerHeaderFontSize) : '0px',
98
- footerFont: showFooter === 'true' ? pxToEm(bannerFooterFontSize) : '0px'
99
- };
100
- }
101
-
102
- return undefined;
103
- }
package/utils/cluster.js CHANGED
@@ -81,7 +81,7 @@ export function paginationFilterOnlyKubernetesClusters(store) {
81
81
 
82
82
  return PaginationParamFilter.createMultipleFields([
83
83
  new PaginationFilterField({
84
- field: `metadata.labels."${ CAPI.PROVIDER }"`,
84
+ field: `metadata.labels[${ CAPI.PROVIDER }]`,
85
85
  equals: false,
86
86
  value: VIRTUAL_HARVESTER_PROVIDER,
87
87
  exact: true
@@ -8,9 +8,7 @@ const UNIT_TO_MS =
8
8
  w: 7 * 24 * 60 * 60 * 1000,
9
9
  y: 365 * 24 * 60 * 60 * 1000
10
10
  };
11
- // see:
12
- // https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/#rule
13
- // https://prometheus.io/docs/prometheus/latest/configuration/configuration/#duration
11
+
14
12
  const DURATION_REGEX = /^(?:([0-9]+)y)?(?:([0-9]+)w)?(?:([0-9]+)d)?(?:([0-9]+)h)?(?:([0-9]+)m)?(?:([0-9]+)s)?(?:([0-9]+)ms)?$/;
15
13
 
16
14
  export function toMilliseconds(input) {
@@ -39,3 +37,7 @@ export function toMilliseconds(input) {
39
37
 
40
38
  return 0;
41
39
  }
40
+
41
+ export function toSeconds(input) {
42
+ return Math.floor(toMilliseconds(input) / 1000);
43
+ }
package/utils/object.js CHANGED
@@ -488,9 +488,6 @@ export function deepToRaw(obj, cache = new WeakSet()) {
488
488
  * More info: https://github.com/lodash/lodash/issues/1313
489
489
  *
490
490
  * This helper function addresses the issue by always replacing the old array with the new array during the merge process.
491
- *
492
- * This helper is used for another case in rke2.vue to handle merging addon chart default values with the user's current values.
493
- * It fixed https://github.com/rancher/dashboard/issues/12418
494
491
  */
495
492
  export function mergeWithReplaceArrays(obj1 = {}, obj2 = {}) {
496
493
  return mergeWith(obj1, obj2, (obj1Value, obj2Value) => {