@rancher/shell 3.0.1-rc.4 → 3.0.1

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 (64) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/styles/base/_basic.scss +5 -0
  3. package/assets/styles/base/_mixins.scss +8 -0
  4. package/assets/styles/global/_button.scss +5 -0
  5. package/assets/styles/themes/_dark.scss +2 -0
  6. package/assets/styles/themes/_light.scss +2 -0
  7. package/assets/translations/en-us.yaml +27 -11
  8. package/assets/translations/zh-hans.yaml +1 -1
  9. package/chart/monitoring/StorageClassSelector.vue +1 -1
  10. package/components/AssignTo.vue +1 -0
  11. package/components/AsyncButton.vue +1 -0
  12. package/components/BackLink.vue +8 -2
  13. package/components/PaginatedResourceTable.vue +135 -0
  14. package/components/ResourceList/index.vue +0 -1
  15. package/components/ResourceTable.vue +6 -1
  16. package/components/SortableTable/index.vue +8 -6
  17. package/components/Tabbed/index.vue +35 -2
  18. package/components/form/ResourceLabeledSelect.vue +2 -2
  19. package/components/form/ResourceTabs/index.vue +0 -23
  20. package/components/form/Taints.vue +1 -1
  21. package/components/nav/TopLevelMenu.helper.ts +546 -0
  22. package/components/nav/TopLevelMenu.vue +124 -159
  23. package/components/nav/__tests__/TopLevelMenu.test.ts +338 -326
  24. package/config/pagination-table-headers.js +4 -4
  25. package/config/product/explorer.js +2 -0
  26. package/config/router/routes.js +1 -1
  27. package/config/settings.ts +13 -1
  28. package/core/plugin.ts +8 -1
  29. package/core/types-provisioning.ts +5 -0
  30. package/core/types.ts +26 -1
  31. package/dialog/DrainNode.vue +6 -6
  32. package/edit/catalog.cattle.io.clusterrepo.vue +95 -52
  33. package/edit/provisioning.cattle.io.cluster/index.vue +8 -3
  34. package/list/node.vue +8 -5
  35. package/mixins/resource-fetch-api-pagination.js +40 -5
  36. package/mixins/resource-fetch.js +48 -5
  37. package/models/management.cattle.io.nodepool.js +5 -4
  38. package/models/provisioning.cattle.io.cluster.js +2 -10
  39. package/package.json +6 -6
  40. package/pages/about.vue +22 -0
  41. package/pages/c/_cluster/explorer/__tests__/index.test.ts +36 -24
  42. package/pages/c/_cluster/explorer/index.vue +100 -59
  43. package/pages/home.vue +308 -123
  44. package/plugins/dashboard-store/__tests__/mutations.test.ts +2 -0
  45. package/plugins/dashboard-store/actions.js +29 -19
  46. package/plugins/dashboard-store/getters.js +5 -2
  47. package/plugins/dashboard-store/mutations.js +4 -2
  48. package/plugins/steve/__tests__/mutations.test.ts +2 -1
  49. package/plugins/steve/steve-pagination-utils.ts +25 -2
  50. package/plugins/steve/subscribe.js +22 -8
  51. package/scripts/extension/parse-tag-name +2 -0
  52. package/scripts/test-plugins-build.sh +1 -0
  53. package/store/index.js +31 -9
  54. package/tsconfig.json +7 -1
  55. package/types/resources/settings.d.ts +1 -1
  56. package/types/shell/index.d.ts +1107 -1276
  57. package/types/store/dashboard-store.types.ts +4 -0
  58. package/types/store/pagination.types.ts +13 -0
  59. package/types/store/vuex.d.ts +8 -0
  60. package/types/vue-shim.d.ts +6 -31
  61. package/utils/cluster.js +92 -1
  62. package/utils/pagination-utils.ts +17 -8
  63. package/utils/pagination-wrapper.ts +70 -0
  64. package/utils/uiplugins.ts +18 -4
@@ -445,9 +445,12 @@ export default {
445
445
  return undefined;
446
446
  },
447
447
 
448
- paginationEnabled: (state, getters, rootState, rootGetters) => (type = null) => {
448
+ paginationEnabled: (state, getters, rootState, rootGetters) => (args) => {
449
+ const id = typeof args === 'object' ? args.id : args;
450
+ const context = typeof args === 'object' ? args.context : undefined;
451
+
449
452
  const store = state.config.namespace;
450
- const resource = type ? { id: type } : null;
453
+ const resource = id || context ? { id, context } : null;
451
454
 
452
455
  return paginationUtils.isEnabled({ rootGetters }, { store, resource });
453
456
  }
@@ -1,4 +1,4 @@
1
- import { markRaw, reactive } from 'vue';
1
+ import { reactive } from 'vue';
2
2
  import { addObject, addObjects, clear, removeObject } from '@shell/utils/array';
3
3
  import { SCHEMA, COUNT } from '@shell/config/types';
4
4
  import { normalizeType, keyFieldFor } from '@shell/plugins/dashboard-store/normalize';
@@ -36,7 +36,7 @@ function registerType(state, type) {
36
36
  loadCounter: 0,
37
37
 
38
38
  // Not enumerable so they don't get sent back to the client for SSR
39
- map: markRaw(new Map()),
39
+ map: new Map(),
40
40
  };
41
41
 
42
42
  state.types[type] = cache;
@@ -164,6 +164,8 @@ export function load(state, {
164
164
  }
165
165
  }
166
166
 
167
+ cache.havePage = false;
168
+
167
169
  return entry;
168
170
  }
169
171
 
@@ -15,9 +15,10 @@ describe('steve-store: mutations', () => {
15
15
  list: [new Resource(pod)],
16
16
  map: new Map([
17
17
  [pod.id, new Resource(pod)]
18
- ])
18
+ ]),
19
19
  }
20
20
  };
21
+ res.expected.types[POD].havePage = false;
21
22
 
22
23
  return res;
23
24
  };
@@ -4,8 +4,10 @@ import { NAMESPACE_FILTER_ALL_SYSTEM, NAMESPACE_FILTER_ALL_USER, NAMESPACE_FILTE
4
4
  import Namespace from '@shell/models/namespace';
5
5
  import { uniq } from '@shell/utils/array';
6
6
  import {
7
+ CAPI,
7
8
  CONFIG_MAP, MANAGEMENT, NAMESPACE, NODE, POD
8
9
  } from '@shell/config/types';
10
+ import { CAPI as CAPI_LABELS } from '@shell/config/labels-annotations';
9
11
  import { Schema } from '@shell/plugins/steve/schema';
10
12
 
11
13
  class NamespaceProjectFilters {
@@ -107,8 +109,8 @@ class StevePaginationUtils extends NamespaceProjectFilters {
107
109
  '': [// all types
108
110
  { field: 'metadata.name' },
109
111
  { field: 'metadata.namespace' },
110
- // { field: 'id' }, // Pending API support
111
- // { field: 'metadata.state.name' }, // Pending API support
112
+ { field: 'id' },
113
+ { field: 'metadata.state.name' },
112
114
  { field: 'metadata.creationTimestamp' },
113
115
  ],
114
116
  [NODE]: [
@@ -122,11 +124,32 @@ class StevePaginationUtils extends NamespaceProjectFilters {
122
124
  [MANAGEMENT.NODE]: [
123
125
  { field: 'status.nodeName' },
124
126
  ],
127
+ [MANAGEMENT.NODE_POOL]: [
128
+ { field: 'spec.clusterName' },
129
+ ],
130
+ [MANAGEMENT.NODE_TEMPLATE]: [
131
+ { field: 'spec.clusterName' },
132
+ ],
133
+ [MANAGEMENT.CLUSTER]: [
134
+ { field: 'spec.internal' },
135
+ { field: 'spec.displayName' },
136
+ // { field: `status.provider` }, // Pending API Support - https://github.com/rancher/rancher/issues/48256
137
+ // { field: `metadata.labels."${ CAPI_LABELS.PROVIDER }"` }, // Pending API Support - https://github.com/rancher/rancher/issues/48256
138
+
139
+ ],
125
140
  [CONFIG_MAP]: [
126
141
  { field: 'metadata.labels[harvesterhci.io/cloud-init-template]' }
127
142
  ],
128
143
  [NAMESPACE]: [
129
144
  { field: 'metadata.labels[field.cattle.io/projectId]' }
145
+ ],
146
+ [CAPI.MACHINE]: [
147
+ { field: 'spec.clusterName' }
148
+ ],
149
+ [CAPI.RANCHER_CLUSTER]: [
150
+ { field: `metadata.labels."${ CAPI_LABELS.PROVIDER }"` },
151
+ { field: `status.provider` },
152
+ { field: 'status.clusterName' },
130
153
  ]
131
154
  }
132
155
 
@@ -452,7 +452,7 @@ const sharedActions = {
452
452
  },
453
453
 
454
454
  unwatch(ctx, {
455
- type, id, namespace, selector
455
+ type, id, namespace, selector, all
456
456
  }) {
457
457
  const { commit, getters, dispatch } = ctx;
458
458
 
@@ -467,16 +467,26 @@ const sharedActions = {
467
467
  stop: true, // Stops the watch on a type
468
468
  };
469
469
 
470
+ const unwatch = (obj) => {
471
+ if (getters['watchStarted'](obj)) {
472
+ // Set that we don't want to watch this type
473
+ // Otherwise, the dispatch to unwatch below will just cause a re-watch when we
474
+ // detect the stop message from the backend over the web socket
475
+ commit('setWatchStopped', obj);
476
+ dispatch('watch', obj); // Ask the backend to stop watching the type
477
+ // Make sure anything in the pending queue for the type is removed, since we've now removed the type
478
+ commit('clearFromQueue', type);
479
+ }
480
+ };
481
+
470
482
  if (isAdvancedWorker(ctx)) {
471
483
  dispatch('watch', obj); // Ask the backend to stop watching the type
484
+ } else if (all) {
485
+ getters['watchesOfType'](type).forEach((obj) => {
486
+ unwatch(obj);
487
+ });
472
488
  } else if (getters['watchStarted'](obj)) {
473
- // Set that we don't want to watch this type
474
- // Otherwise, the dispatch to unwatch below will just cause a re-watch when we
475
- // detect the stop message from the backend over the web socket
476
- commit('setWatchStopped', obj);
477
- dispatch('watch', obj); // Ask the backend to stop watching the type
478
- // Make sure anything in the pending queue for the type is removed, since we've now removed the type
479
- commit('clearFromQueue', type);
489
+ unwatch(obj);
480
490
  }
481
491
  }
482
492
  },
@@ -1025,6 +1035,10 @@ const defaultGetters = {
1025
1035
  return state.inError[keyForSubscribe(obj)];
1026
1036
  },
1027
1037
 
1038
+ watchesOfType: (state) => (type) => {
1039
+ return state.started.filter((entry) => type === (entry.resourceType || entry.type));
1040
+ },
1041
+
1028
1042
  watchStarted: (state) => (obj) => {
1029
1043
  return !!state.started.find((entry) => equivalentWatch(obj, entry));
1030
1044
  },
@@ -14,6 +14,7 @@ if [[ "${GITHUB_WORKFLOW_TYPE}" == "catalog" ]]; then
14
14
  if [[ "${GITHUB_RELEASE_TAG}" != "${BASE_EXT}-${EXT_VERSION}" ]]; then
15
15
  echo -e "release tag doesn't match catalog tag: release tag -> ${GITHUB_RELEASE_TAG} ::: curr catalog tag -> ${BASE_EXT}-${EXT_VERSION}"
16
16
  gh run cancel ${GITHUB_RUN_ID}
17
+ exit 1
17
18
  fi
18
19
  # Ensure "chart" workflow release tag name matches some pkg/<pkg-name>
19
20
  else
@@ -33,5 +34,6 @@ else
33
34
  if [[ "${NO_MATCHES}" == "true" ]]; then
34
35
  echo -e "release tag doesn't match any chart tag: ${GITHUB_RELEASE_TAG}. Check your pkg/<!-YOUR-EXT-> folders and corresponding versions to complete the match"
35
36
  gh run cancel ${GITHUB_RUN_ID}
37
+ exit 1
36
38
  fi
37
39
  fi
@@ -226,5 +226,6 @@ clone_repo_test_extension_build "rancher" "elemental-ui" "elemental"
226
226
  clone_repo_test_extension_build "neuvector" "manager-ext" "neuvector-ui-ext"
227
227
  clone_repo_test_extension_build "rancher" "capi-ui-extension" "capi"
228
228
  clone_repo_test_extension_build "StackVista" "rancher-extension-stackstate" "observability"
229
+ clone_repo_test_extension_build "harvester" "harvester-ui-extension" "harvester"
229
230
 
230
231
  echo "All done"
package/store/index.js CHANGED
@@ -38,6 +38,7 @@ import semver from 'semver';
38
38
  import { STORE, BLANK_CLUSTER } from '@shell/store/store-types';
39
39
  import { isDevBuild } from '@shell/utils/version';
40
40
  import { markRaw } from 'vue';
41
+ import paginationUtils from '@shell/utils/pagination-utils';
41
42
 
42
43
  // Disables strict mode for all store instances to prevent warning about changing state outside of mutations
43
44
  // because it's more efficient to do that sometimes.
@@ -225,6 +226,13 @@ const updateActiveNamespaceCache = (state, activeNamespaceCache) => {
225
226
  }
226
227
  };
227
228
 
229
+ /**
230
+ * Are we in the vai enabled world where mgmt clusters are paginated?
231
+ */
232
+ const paginateClusters = (rootGetters) => {
233
+ return paginationUtils.isEnabled({ rootGetters }, { store: 'management', resource: { id: MANAGEMENT.CLUSTER, context: 'side-bar' } });
234
+ };
235
+
228
236
  export const state = () => {
229
237
  return {
230
238
  managementReady: false,
@@ -780,15 +788,11 @@ export const actions = {
780
788
  // The alternative is simpler (fetch features up front) but would add another blocking request in
781
789
 
782
790
  const promises = {
783
- // Clusters guaranteed always available or your money back
784
- clusters: dispatch('management/findAll', { type: MANAGEMENT.CLUSTER, opt: { watch: false } }),
785
-
786
791
  // Features checks on its own if they are available
787
792
  features: dispatch('features/loadServer'),
788
793
  };
789
794
 
790
795
  const toWatch = [
791
- MANAGEMENT.CLUSTER,
792
796
  MANAGEMENT.FEATURE,
793
797
  ];
794
798
 
@@ -823,6 +827,13 @@ export const actions = {
823
827
 
824
828
  res = await allHash(promises);
825
829
 
830
+ if (!res.settings || !paginateClusters(rootGetters)) {
831
+ // This introduces a synchronous request, however we need settings to determine if SSP is enabled
832
+ // Eventually it will be removed when SSP is always on
833
+ res.clusters = await dispatch('management/findAll', { type: MANAGEMENT.CLUSTER, opt: { watch: false } });
834
+ toWatch.push(MANAGEMENT.CLUSTER);
835
+ }
836
+
826
837
  // See comment above. Now that we have feature flags we can watch resources
827
838
  toWatch.forEach((type) => {
828
839
  dispatch('management/watch', { type });
@@ -879,7 +890,7 @@ export const actions = {
879
890
  // - state.clusterId is the old cluster id (or undefined)
880
891
  // - id is the new cluster id (or undefined)
881
892
  async loadCluster({
882
- state, commit, dispatch, getters
893
+ state, commit, dispatch, getters, rootGetters
883
894
  }, {
884
895
  id, product, oldProduct, oldPkg, newPkg, targetRoute
885
896
  }) {
@@ -983,9 +994,10 @@ export const actions = {
983
994
  // Try and wait until the schema exists before proceeding
984
995
  await dispatch('management/waitForSchema', { type: MANAGEMENT.CLUSTER });
985
996
 
986
- // Similar to above, we're still waiting on loadManagement to fetch required resources
987
- // If we don't have all mgmt clusters yet a request to fetch this cluster and then all clusters (in cleanNamespaces) is kicked off
988
- await dispatch('management/waitForHaveAll', { type: MANAGEMENT.CLUSTER });
997
+ // If SSP is on we won't have requested all clusters
998
+ if (!paginateClusters(rootGetters)) {
999
+ await dispatch('management/waitForHaveAll', { type: MANAGEMENT.CLUSTER });
1000
+ }
989
1001
 
990
1002
  // See if it really exists
991
1003
  try {
@@ -1082,7 +1094,17 @@ export const actions = {
1082
1094
  commit('updateNamespaces', { filters: ids, getters });
1083
1095
  },
1084
1096
 
1085
- async cleanNamespaces({ getters, dispatch }) {
1097
+ async cleanNamespaces({ getters, dispatch, rootGetters }) {
1098
+ if (paginateClusters(rootGetters)) {
1099
+ // See https://github.com/rancher/dashboard/issues/12864
1100
+ // old world...
1101
+ // - loadManagement makes a request to fetch all mgmt clusters
1102
+ // - we would block on that that request above before getting here (otherwise x2 requests for all clusters were made)
1103
+ // new world...
1104
+ // - we won't have all mgmt clusters, so this whole function needs updating (see issue)
1105
+ return;
1106
+ }
1107
+
1086
1108
  // Initialise / Remove any filters that the user no-longer has access to
1087
1109
  await dispatch('management/findAll', { type: MANAGEMENT.CLUSTER }); // So they can be got byId below
1088
1110
 
package/tsconfig.json CHANGED
@@ -25,6 +25,12 @@
25
25
  "../node_modules/@types"
26
26
  ],
27
27
  },
28
+ "include": [
29
+ "./**/*.ts",
30
+ "./**/*.d.ts",
31
+ "./**/*.tsx",
32
+ "./**/*.vue"
33
+ ],
28
34
  "exclude": [
29
35
  "node_modules",
30
36
  "dist",
@@ -38,4 +44,4 @@
38
44
  "../docusaurus",
39
45
  "../**/*.spec.ts"
40
46
  ]
41
- }
47
+ }
@@ -20,7 +20,7 @@ export interface PaginationSettings {
20
20
  /**
21
21
  * Specific resource type to enable
22
22
  */
23
- enabled: string[],
23
+ enabled: (string | { resource: string, context: string[]})[],
24
24
  /**
25
25
  * There's no hardcoded headers or custom list for the resource type, headers will be generated from schema attributes.columns
26
26
  */