@rancher/shell 0.3.0 → 0.3.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 (322) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_layout.scss +1 -2
  4. package/assets/styles/global/_select.scss +1 -4
  5. package/assets/styles/themes/_dark.scss +4 -4
  6. package/assets/styles/themes/_light.scss +4 -3
  7. package/assets/styles/themes/_suse.scss +1 -1
  8. package/assets/styles/vendor/vue-select.scss +4 -3
  9. package/assets/translations/en-us.yaml +669 -73
  10. package/assets/translations/zh-hans.yaml +547 -165
  11. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  12. package/cloud-credential/azure.vue +23 -0
  13. package/cloud-credential/harvester.vue +25 -62
  14. package/cloud-credential/pnap.vue +80 -0
  15. package/components/.DS_Store +0 -0
  16. package/components/AdvancedSection.vue +9 -2
  17. package/components/Alert.vue +2 -2
  18. package/components/ButtonDropdown.vue +0 -2
  19. package/components/ButtonGroup.vue +1 -0
  20. package/components/CollapsibleCard.vue +0 -1
  21. package/components/CruResource.vue +41 -4
  22. package/components/DetailTop.vue +58 -3
  23. package/components/DisableAuthProviderModal.vue +106 -0
  24. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  25. package/components/ExplorerMembers.vue +253 -30
  26. package/components/ExplorerProjectsNamespaces.vue +77 -33
  27. package/components/GrowlManager.vue +3 -3
  28. package/components/IconOrSvg.vue +149 -0
  29. package/components/LogItem.vue +69 -0
  30. package/components/PodSecurityAdmission.vue +302 -0
  31. package/components/PromptModal.vue +1 -0
  32. package/components/ResourceDetail/Masthead.vue +54 -2
  33. package/components/ResourceDetail/index.vue +12 -5
  34. package/components/ResourceList/Masthead.vue +11 -1
  35. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  36. package/components/ResourceList/index.vue +53 -12
  37. package/components/ResourceList/resource-list.config.js +7 -0
  38. package/components/ResourceTable.vue +31 -6
  39. package/components/SimpleBox.vue +1 -1
  40. package/components/SortableTable/THead.vue +15 -5
  41. package/components/SortableTable/index.vue +21 -10
  42. package/components/Tabbed/index.vue +20 -15
  43. package/components/__tests__/.DS_Store +0 -0
  44. package/components/__tests__/AsyncButton.test.ts +140 -0
  45. package/components/__tests__/BackLink.test.ts +33 -0
  46. package/components/__tests__/ButtonGroup.test.ts +124 -0
  47. package/components/__tests__/ClusterBadge.test.ts +32 -0
  48. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  49. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  50. package/components/__tests__/CruResource.test.ts +3 -2
  51. package/components/__tests__/FixedBanner.test.ts +129 -0
  52. package/components/__tests__/GrowlManager.test.ts +147 -0
  53. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  54. package/components/__tests__/PercentageBar.test.ts +32 -0
  55. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  56. package/components/auth/AuthBanner.vue +20 -10
  57. package/components/auth/RoleDetailEdit.vue +26 -17
  58. package/components/auth/SelectPrincipal.vue +36 -5
  59. package/components/form/ArrayList.vue +3 -35
  60. package/components/form/ArrayListGrouped.vue +13 -4
  61. package/components/form/ArrayListSelect.vue +5 -5
  62. package/components/form/Error.vue +8 -0
  63. package/components/form/KeyValue.vue +39 -7
  64. package/components/form/LabeledSelect.vue +5 -2
  65. package/components/form/Labels.vue +46 -16
  66. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  67. package/components/form/Members/MembershipEditor.vue +12 -12
  68. package/components/form/NameNsDescription.vue +1 -1
  69. package/components/form/NodeScheduling.vue +1 -1
  70. package/components/form/Probe.vue +3 -3
  71. package/components/form/ResourceQuota/Project.vue +6 -6
  72. package/components/form/ResourceTabs/index.vue +1 -6
  73. package/components/form/Security.vue +7 -6
  74. package/components/form/Select.vue +3 -2
  75. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  76. package/components/form/ServicePorts.vue +8 -0
  77. package/components/form/WorkloadPorts.vue +7 -1
  78. package/components/form/__tests__/ArrayList.test.ts +74 -0
  79. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  80. package/components/formatter/Checked.vue +1 -1
  81. package/components/formatter/ClusterLink.vue +5 -0
  82. package/components/formatter/IconIsDefault.vue +2 -2
  83. package/components/formatter/InternalExternalIP.vue +11 -8
  84. package/components/formatter/LiveDuration.vue +78 -0
  85. package/components/formatter/WorkloadHealthScale.vue +5 -3
  86. package/components/nav/Header.vue +6 -3
  87. package/components/nav/NamespaceFilter.vue +146 -63
  88. package/components/nav/TopLevelMenu.vue +22 -19
  89. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  90. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  91. package/components/nav/WindowManager/Window.vue +2 -0
  92. package/components/nav/WindowManager/index.vue +10 -0
  93. package/config/elemental-types.js +9 -0
  94. package/config/features.js +2 -0
  95. package/config/home-links.js +4 -1
  96. package/config/pod-security-admission.ts +82 -0
  97. package/config/product/apps.js +1 -1
  98. package/config/product/auth.js +6 -5
  99. package/config/product/explorer.js +6 -6
  100. package/config/product/fleet.js +1 -1
  101. package/config/product/manager.js +6 -2
  102. package/config/secret.js +0 -1
  103. package/config/settings.ts +26 -9
  104. package/config/table-headers.js +22 -11
  105. package/config/types.js +4 -1
  106. package/content/docs/zh-hans/getting-started.md +113 -137
  107. package/content/docs/zh-hans/whats-new.md +8 -46
  108. package/creators/pkg/package-lock.json +37 -0
  109. package/creators/pkg/package.json +1 -1
  110. package/detail/catalog.cattle.io.app.vue +1 -1
  111. package/detail/pod.vue +1 -1
  112. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  113. package/detail/service.vue +2 -9
  114. package/detail/workload/index.vue +0 -1
  115. package/dialog/AddClusterMemberDialog.vue +22 -28
  116. package/dialog/AddProjectMemberDialog.vue +53 -9
  117. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  118. package/dialog/DrainNode.vue +44 -48
  119. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  120. package/dialog/GenericPrompt.vue +15 -20
  121. package/dialog/RollbackWorkloadDialog.vue +15 -46
  122. package/dialog/RotateCertificatesDialog.vue +5 -7
  123. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  124. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  125. package/dialog/ScaleMachineDownDialog.vue +1 -1
  126. package/dialog/ScalePoolDownDialog.vue +121 -0
  127. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  128. package/edit/auth/azuread.vue +16 -16
  129. package/edit/auth/github.vue +8 -0
  130. package/edit/auth/googleoauth.vue +10 -1
  131. package/edit/auth/ldap/index.vue +10 -0
  132. package/edit/auth/oidc.vue +10 -0
  133. package/edit/auth/saml.vue +10 -0
  134. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  135. package/edit/cloudcredential.vue +3 -7
  136. package/edit/logging-flow/Match.vue +39 -8
  137. package/edit/logging-flow/index.vue +27 -4
  138. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  139. package/edit/management.cattle.io.project.vue +8 -1
  140. package/edit/management.cattle.io.setting.vue +5 -2
  141. package/edit/management.cattle.io.user.vue +7 -1
  142. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +23 -7
  143. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  144. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  145. package/edit/namespace.vue +18 -4
  146. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  147. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  148. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  149. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  150. package/edit/persistentvolume/index.vue +30 -27
  151. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  152. package/edit/persistentvolume/plugins/csi.vue +102 -62
  153. package/edit/persistentvolume/plugins/fc.vue +19 -19
  154. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  155. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  156. package/edit/persistentvolumeclaim.vue +78 -75
  157. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  158. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  159. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  160. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  161. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +93 -0
  162. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  164. package/edit/provisioning.cattle.io.cluster/rke2.vue +440 -152
  165. package/edit/secret/index.vue +3 -7
  166. package/edit/service.vue +3 -1
  167. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  168. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  169. package/edit/workload/__tests__/index.test.ts +98 -0
  170. package/edit/workload/index.vue +58 -8
  171. package/edit/workload/mixins/workload.js +107 -70
  172. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  173. package/edit/workload/storage/emptyDir.vue +88 -0
  174. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  175. package/edit/workload/storage/index.vue +8 -0
  176. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  177. package/layouts/default.vue +57 -44
  178. package/list/__tests__/workload.test.ts +5 -2
  179. package/list/catalog.cattle.io.app.vue +1 -0
  180. package/list/cis.cattle.io.clusterscan.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +5 -6
  182. package/list/fleet.cattle.io.cluster.vue +6 -3
  183. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  184. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  185. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  186. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  187. package/list/logging.banzaicloud.io.flow.vue +6 -5
  188. package/list/management.cattle.io.cluster.vue +1 -0
  189. package/list/management.cattle.io.feature.vue +3 -4
  190. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  191. package/list/management.cattle.io.setting.vue +2 -2
  192. package/list/management.cattle.io.user.vue +4 -10
  193. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  194. package/list/node.vue +8 -5
  195. package/list/persistentvolume.vue +3 -3
  196. package/list/persistentvolumeclaim.vue +3 -4
  197. package/list/provisioning.cattle.io.cluster.vue +18 -19
  198. package/list/service.vue +6 -14
  199. package/list/workload.vue +43 -38
  200. package/machine-config/azure.vue +429 -60
  201. package/machine-config/pnap.vue +288 -0
  202. package/mixins/auth-config.js +1 -3
  203. package/mixins/browser-tab-visibility.js +8 -14
  204. package/mixins/chart.js +1 -1
  205. package/mixins/create-edit-view/impl.js +4 -0
  206. package/mixins/create-edit-view/index.js +4 -2
  207. package/mixins/resource-fetch-namespaced.js +98 -0
  208. package/mixins/resource-fetch.js +79 -45
  209. package/mixins/resource-manager.js +1 -23
  210. package/models/apps.controllerrevision.js +7 -0
  211. package/models/apps.daemonset.js +18 -0
  212. package/models/apps.deployment.js +44 -0
  213. package/models/apps.replicaset.js +7 -0
  214. package/models/apps.statefulset.js +18 -0
  215. package/models/batch.job.js +7 -14
  216. package/models/cluster/node.js +10 -2
  217. package/models/cluster.x-k8s.io.machine.js +26 -4
  218. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  219. package/models/event.js +7 -0
  220. package/models/logging.banzaicloud.io.flow.js +4 -0
  221. package/models/management.cattle.io.cluster.js +1 -1
  222. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  223. package/models/management.cattle.io.globalrole.js +2 -2
  224. package/models/management.cattle.io.node.js +37 -2
  225. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  226. package/models/management.cattle.io.project.js +30 -11
  227. package/models/management.cattle.io.setting.js +1 -1
  228. package/models/management.cattle.io.user.js +37 -1
  229. package/models/namespace.js +42 -5
  230. package/models/persistentvolume.js +14 -2
  231. package/models/pod.js +15 -0
  232. package/models/projectroletemplatebinding.js +7 -0
  233. package/models/provisioning.cattle.io.cluster.js +61 -10
  234. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  235. package/models/service.js +14 -13
  236. package/models/storage.k8s.io.storageclass.js +33 -18
  237. package/models/workload.js +38 -7
  238. package/nuxt.config.js +27 -17
  239. package/package.json +7 -7
  240. package/pages/about.vue +14 -2
  241. package/pages/c/_cluster/apps/charts/index.vue +4 -3
  242. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  243. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  244. package/pages/c/_cluster/auth/config/index.vue +8 -6
  245. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  246. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  247. package/pages/c/_cluster/explorer/index.vue +12 -6
  248. package/pages/c/_cluster/longhorn/index.vue +1 -1
  249. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  250. package/pages/c/_cluster/monitoring/index.vue +1 -1
  251. package/pages/c/_cluster/neuvector/index.vue +1 -1
  252. package/pages/c/_cluster/settings/performance.vue +48 -2
  253. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +34 -1
  254. package/pages/c/_cluster/uiplugins/index.vue +28 -2
  255. package/pages/diagnostic.vue +5 -4
  256. package/pages/home.vue +105 -30
  257. package/pages/prefs.vue +23 -12
  258. package/pages/rio/mesh.vue +1 -1
  259. package/pkg/dynamic-importer.lib.js +8 -0
  260. package/pkg/vue.config.js +4 -0
  261. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  262. package/plugins/dashboard-store/actions.js +32 -25
  263. package/plugins/dashboard-store/getters.js +50 -33
  264. package/plugins/dashboard-store/mutations.js +134 -28
  265. package/plugins/dashboard-store/resource-class.js +21 -41
  266. package/plugins/steve/actions.js +30 -0
  267. package/plugins/steve/caches/resourceCache.js +60 -0
  268. package/plugins/steve/getters.js +44 -1
  269. package/plugins/steve/mutations.js +97 -36
  270. package/plugins/steve/resourceWatcher.js +277 -0
  271. package/plugins/steve/schema.utils.js +25 -0
  272. package/plugins/steve/subscribe.js +288 -115
  273. package/plugins/steve/worker/index.js +17 -0
  274. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  275. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  276. package/rancher-components/Card/Card.vue +3 -3
  277. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  278. package/rancher-components/StringList/StringList.test.ts +45 -420
  279. package/rancher-components/StringList/StringList.vue +1 -10
  280. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  281. package/rancher-components/components/Banner/Banner.vue +129 -61
  282. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  283. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  284. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  285. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  286. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  287. package/rancher-components/components/StringList/StringList.vue +21 -15
  288. package/scripts/test-plugins-build.sh +8 -0
  289. package/static/loading-indicator.html +1 -1
  290. package/store/index.js +54 -3
  291. package/store/plugins.js +0 -17
  292. package/store/pnap.js +128 -0
  293. package/store/prefs.js +4 -2
  294. package/store/type-map.js +55 -13
  295. package/types/pod-security-admission.ts +36 -0
  296. package/types/shell/index.d.ts +496 -396
  297. package/utils/__tests__/object.test.ts +17 -1
  298. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  299. package/utils/async.ts +36 -0
  300. package/utils/color.js +45 -0
  301. package/utils/crypto/browserHashUtils.js +18 -0
  302. package/utils/dynamic-importer.js +8 -0
  303. package/utils/install-redirect.js +1 -1
  304. package/utils/object.js +24 -0
  305. package/utils/pod-security-admission.ts +39 -0
  306. package/utils/socket.js +61 -24
  307. package/utils/string.js +2 -0
  308. package/utils/svg-filter.js +301 -0
  309. package/utils/time.js +49 -0
  310. package/utils/validators/cidr.js +4 -0
  311. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  312. package/utils/validators/formRules/index.ts +14 -0
  313. package/config/product/harvester-manager.js +0 -162
  314. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  315. package/list/harvesterhci.io.management.cluster.vue +0 -241
  316. package/machine-config/harvester.vue +0 -693
  317. package/models/harvesterhci.io.management.cluster.js +0 -228
  318. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  319. package/rancher-components/Card/Card.test.ts +0 -39
  320. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  321. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  322. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -0,0 +1,406 @@
1
+ import { batchChanges } from '@shell/plugins/dashboard-store/mutations';
2
+ import { POD, WORKLOAD_TYPES } from '@shell/config/types';
3
+ import Resource from '@shell/plugins/dashboard-store/resource-class';
4
+
5
+ describe('dashboard-store: mutations', () => {
6
+ const ctx = {
7
+ rootGetters: { 'type-map/optionsFor': type => ({}) },
8
+ getters: {
9
+ classify: resource => Resource,
10
+ cleanResource: (existing, resource) => resource
11
+ }
12
+ };
13
+
14
+ const create = type => ({
15
+ id: '1',
16
+ type
17
+ });
18
+
19
+ const createResource = (type, props = {}) => new Resource({
20
+ ...create(type),
21
+ ...props
22
+ });
23
+
24
+ const createPod = () => create(POD);
25
+
26
+ const createPodResource = (props = {}) => createResource(POD, props);
27
+
28
+ const createCache = props => ({
29
+ generation: 0,
30
+ haveAll: false,
31
+ haveNamespace: undefined,
32
+ haveSelector: {},
33
+ list: [],
34
+ loadCounter: 0,
35
+ revision: 0,
36
+ map: new Map(),
37
+ ...props
38
+ });
39
+
40
+ const createNoOp = () => {
41
+ const emptyState = { types: {} };
42
+
43
+ return {
44
+ params: [emptyState, {
45
+ ctx,
46
+ batch: { }
47
+ }],
48
+ expected: { state: emptyState }
49
+ };
50
+ };
51
+
52
+ const createRegister = () => {
53
+ return {
54
+ params: [{ types: {} }, {
55
+ ctx,
56
+ batch: { [POD]: {} }
57
+ }],
58
+ expected: { types: { [POD]: createCache({ generation: 1 }) } }
59
+ };
60
+ };
61
+
62
+ const createNewEntry = () => {
63
+ const pod = createPod();
64
+
65
+ return {
66
+ params: [
67
+ { types: {} },
68
+ {
69
+ ctx,
70
+ batch: { [POD]: { [pod.id]: pod } }
71
+ }
72
+ ],
73
+ expected: {
74
+ types: {
75
+ [POD]: createCache({
76
+ generation: 1,
77
+ list: [new Resource(pod)],
78
+ map: new Map([
79
+ [pod.id, new Resource(pod)]
80
+ ])
81
+ })
82
+ }
83
+ }
84
+ };
85
+ };
86
+
87
+ const createExisting = () => {
88
+ const existingPod = createPodResource();
89
+ const newPod = createPodResource({ change: true });
90
+
91
+ return {
92
+ params: [
93
+ {
94
+ types: {
95
+ [POD]: createCache({
96
+ list: [existingPod],
97
+ map: new Map([
98
+ [existingPod.id, existingPod]
99
+ ])
100
+ })
101
+ }
102
+ },
103
+ {
104
+ ctx,
105
+ batch: { [POD]: { [newPod.id]: createPodResource({ change: true }) } }
106
+ }
107
+ ],
108
+ expected: {
109
+ types: {
110
+ [POD]: createCache({
111
+ generation: 1,
112
+ list: [newPod],
113
+ map: new Map([
114
+ [newPod.id, newPod]
115
+ ])
116
+ })
117
+
118
+ },
119
+ }
120
+ };
121
+ };
122
+
123
+ const createRemove = () => {
124
+ const existingPod = createPodResource();
125
+
126
+ return {
127
+ params: [
128
+ {
129
+ types: {
130
+ [POD]: createCache({
131
+ list: [existingPod],
132
+ map: new Map([
133
+ [existingPod.id, existingPod]
134
+ ])
135
+ })
136
+ }
137
+ },
138
+ {
139
+ ctx,
140
+ batch: { [POD]: { [existingPod.id]: {} } }
141
+ }
142
+ ],
143
+ expected: {
144
+ types: {
145
+ [POD]: createCache({
146
+ generation: 1,
147
+ list: [],
148
+ map: new Map()
149
+ })
150
+ },
151
+ }
152
+ };
153
+ };
154
+
155
+ const createAddRemove = () => {
156
+ const existingPod1 = createPodResource({ id: '1' });
157
+ // const newPod1 = createPodResource({ id: '1', new: true });
158
+ const existingPod2 = createPodResource({ id: '2' });
159
+
160
+ return {
161
+ params: [
162
+ {
163
+ types: {
164
+ [POD]: createCache({
165
+ list: [existingPod2],
166
+ map: new Map([
167
+ [existingPod2.id, existingPod2]
168
+ ])
169
+ })
170
+
171
+ }
172
+ },
173
+ {
174
+ ctx,
175
+ batch: {
176
+ [POD]: {
177
+ [existingPod1.id]: existingPod1,
178
+ [existingPod2.id]: {}
179
+ }
180
+ }
181
+ }
182
+ ],
183
+ expected: {
184
+ types: {
185
+ [POD]: createCache({
186
+ generation: 1,
187
+ list: [existingPod1],
188
+ map: new Map([
189
+ [existingPod1.id, existingPod1]
190
+ ])
191
+ })
192
+ },
193
+ }
194
+ };
195
+ };
196
+
197
+ const createRemoveAdd = () => {
198
+ const existingPod1 = createPodResource({ id: '1' });
199
+ // const newPod1 = createPodResource({ id: '1', new: true });
200
+ const existingPod2 = createPodResource({ id: '2' });
201
+
202
+ return {
203
+ params: [
204
+ {
205
+ types: {
206
+ [POD]: createCache({
207
+ list: [existingPod2],
208
+ map: new Map([
209
+ [existingPod2.id, existingPod2]
210
+ ])
211
+ })
212
+ }
213
+ },
214
+ {
215
+ ctx,
216
+ batch: {
217
+ [POD]: {
218
+ [existingPod2.id]: {},
219
+ [existingPod1.id]: existingPod1,
220
+ }
221
+ }
222
+ }
223
+ ],
224
+ expected: {
225
+ types: {
226
+ [POD]: createCache({
227
+ generation: 1,
228
+ list: [existingPod1],
229
+ map: new Map([
230
+ [existingPod1.id, existingPod1]
231
+ ])
232
+ })
233
+ },
234
+ }
235
+ };
236
+ };
237
+
238
+ const createAddMultipleTypes = () => {
239
+ const pod = createPodResource({ id: '1' });
240
+ const deployment = createResource({ id: '2', type: WORKLOAD_TYPES.DEPLOYMENT });
241
+
242
+ return {
243
+ params: [
244
+ {
245
+ types: {
246
+ [POD]: createCache({
247
+ list: [],
248
+ map: new Map()
249
+ }),
250
+ [WORKLOAD_TYPES.DEPLOYMENT]: createCache({
251
+ list: [],
252
+ map: new Map()
253
+ })
254
+ }
255
+ },
256
+ {
257
+ ctx,
258
+ batch: {
259
+ [POD]: { [pod.id]: pod },
260
+ [ WORKLOAD_TYPES.DEPLOYMENT]: { [deployment.id]: deployment }
261
+ }
262
+ }
263
+ ],
264
+ expected: {
265
+ types: {
266
+ [POD]: createCache({
267
+ generation: 1,
268
+ list: [pod],
269
+ map: new Map([
270
+ [pod.id, pod]
271
+ ])
272
+ }),
273
+ [WORKLOAD_TYPES.DEPLOYMENT]: createCache({
274
+ generation: 1,
275
+ list: [deployment],
276
+ map: new Map([[deployment.id, deployment]])
277
+ })
278
+ },
279
+ }
280
+ };
281
+ };
282
+
283
+ const removeNonExisting = () => {
284
+ const pod1 = createPodResource({ id: '1' });
285
+ const pod2 = createPodResource({ id: '2' });
286
+
287
+ return {
288
+ params: [
289
+ {
290
+ types: {
291
+ [POD]: createCache({
292
+ list: [pod1],
293
+ map: new Map([[pod1.id, pod1]])
294
+ }),
295
+ }
296
+ },
297
+ {
298
+ ctx,
299
+ batch: { [POD]: { [pod2.id]: {} } }
300
+ }
301
+ ],
302
+ expected: {
303
+ types: {
304
+ [POD]: createCache({
305
+ generation: 1,
306
+ list: [pod1],
307
+ map: new Map([[pod1.id, pod1]])
308
+ }),
309
+ },
310
+ }
311
+ };
312
+ };
313
+
314
+ const muchMuchChange = () => {
315
+ const pod1NoChange = createPodResource({ id: '1' });
316
+
317
+ const pod2Add = createPodResource({ id: '2' });
318
+ const pod3Remove = createPodResource({ id: '3' });
319
+ const pod4RemoveNoneExistant = createPodResource({ id: '4' });
320
+ const pod5Add = createPodResource({ id: '5' });
321
+ const pod6Original = createPodResource({ id: '6' });
322
+ const pod6WithChange = createPodResource({ id: '6', change: true }); // Cannot be same reference
323
+ const pod6WithChangeRef = createPodResource({ id: '6', change: true });
324
+
325
+ expect(pod6Original.id).toBe('6');
326
+ expect(pod6WithChange.id).toBe('6');
327
+ expect(pod6WithChangeRef.id).toBe('6');
328
+
329
+ return {
330
+ params: [
331
+ {
332
+ types: {
333
+ [POD]: createCache({
334
+ list: [pod1NoChange, pod3Remove, pod6Original],
335
+ map: new Map([
336
+ [pod1NoChange.id, pod1NoChange],
337
+ [pod3Remove.id, pod3Remove],
338
+ [pod6Original.id, pod6Original],
339
+ ])
340
+ }),
341
+ }
342
+ },
343
+ {
344
+ ctx,
345
+ batch: {
346
+ [POD]: {
347
+ [pod2Add.id]: pod2Add,
348
+ [pod3Remove.id]: {},
349
+ [pod4RemoveNoneExistant.id]: {},
350
+ [pod5Add.id]: pod5Add,
351
+ [pod6WithChangeRef.id]: pod6WithChange // Cannot be same reference,
352
+ },
353
+ }
354
+ }
355
+ ],
356
+ expected: {
357
+ types: {
358
+ [POD]: createCache({
359
+ generation: 1,
360
+ list: [pod1NoChange, pod6WithChangeRef, pod2Add, pod5Add], // Order important
361
+ map: new Map([
362
+ [pod1NoChange.id, pod1NoChange],
363
+ [pod2Add.id, pod2Add],
364
+ [pod5Add.id, pod5Add],
365
+ [pod6WithChangeRef.id, pod6WithChangeRef],
366
+
367
+ ])
368
+ }),
369
+ },
370
+ }
371
+ };
372
+ };
373
+
374
+ describe('batchChanges', () => {
375
+ it.each([['No change', createNoOp()]])('%s', (_, run) => {
376
+ batchChanges(...run.params);
377
+
378
+ expect(run.params[0]).toStrictEqual(run.expected.state);
379
+ });
380
+
381
+ it.each([
382
+ ['Register the type', createRegister()],
383
+ ['Add a new pod', createNewEntry()],
384
+ ['Change a pod', createExisting()],
385
+ ['Remove a pod', createRemove()],
386
+ ['Create one pod, remove another', createAddRemove()],
387
+ ['Remove one pod, create another', createRemoveAdd()],
388
+ ['Add multiple types', createAddMultipleTypes()],
389
+ ['Remove a non-existing pod', removeNonExisting()],
390
+ ['Much much change', muchMuchChange()],
391
+ ])('%s', (_, run) => { // eslint-disable-line jest/no-identical-title
392
+ batchChanges(...run.params);
393
+ // Don't do straight up run.params[0] vs run.expected.... map doesn't get 'provided' so check fails
394
+ Object.entries(run.params[0].types).forEach(([type, cache]) => {
395
+ const { map: cacheMap, ...cacheState } = cache;
396
+ const { map: expectedMap, ...expected } = run.expected.types[type];
397
+
398
+ expect(cacheMap).toBeDefined();
399
+ expect(expectedMap).toBeDefined();
400
+
401
+ expect(cacheState).toStrictEqual(expected);
402
+ expect(cacheMap).toStrictEqual(expectedMap);
403
+ });
404
+ });
405
+ });
406
+ });
@@ -6,6 +6,7 @@ import { createYaml } from '@shell/utils/create-yaml';
6
6
  import { classify } from '@shell/plugins/dashboard-store/classify';
7
7
  import { normalizeType } from './normalize';
8
8
  import garbageCollect from '@shell/utils/gc/gc';
9
+ import { addSchemaIndexFields } from '@shell/plugins/steve/schema.utils';
9
10
 
10
11
  export const _ALL = 'all';
11
12
  export const _MERGE = 'merge';
@@ -48,10 +49,7 @@ export async function loadSchemas(ctx, watch = true) {
48
49
  res.data = res.concat(spoofedTypes);
49
50
  }
50
51
 
51
- res.data.forEach((schema) => {
52
- schema._id = normalizeType(schema.id);
53
- schema._group = normalizeType(schema.attributes?.group);
54
- });
52
+ res.data.forEach(addSchemaIndexFields);
55
53
 
56
54
  commit('loadAll', {
57
55
  ctx,
@@ -85,6 +83,12 @@ export default {
85
83
 
86
84
  type = getters.normalizeType(type);
87
85
 
86
+ // if there's no registered type, then register it so
87
+ // that we don't have issues on 'loadAdd' mutation
88
+ if ( !getters.typeRegistered(type) ) {
89
+ commit('registerType', type);
90
+ }
91
+
88
92
  const loadCount = getters['loadCounter'](type);
89
93
 
90
94
  try {
@@ -117,7 +121,11 @@ export default {
117
121
  if (opt.hasManualRefresh) {
118
122
  dispatch('resource-fetch/updateManualRefreshIsLoading', false, { root: true });
119
123
  }
120
- commit('setHaveAll', { type });
124
+ if (opt.namespaced) {
125
+ commit('setHaveNamespace', { type, namespace: opt.namespaced });
126
+ } else {
127
+ commit('setHaveAll', { type });
128
+ }
121
129
  }
122
130
  } catch (e) {
123
131
  if (opt.hasManualRefresh) {
@@ -140,16 +148,14 @@ export default {
140
148
  commit('registerType', type);
141
149
  }
142
150
 
143
- if ( opt.force !== true && getters['haveAll'](type) ) {
151
+ if ( opt.force !== true && (getters['haveAll'](type) || getters['haveAllNamespace'](type, opt.namespaced))) {
144
152
  const args = {
145
153
  type,
146
154
  revision: '',
147
155
  namespace: opt.watchNamespace
148
156
  };
149
157
 
150
- // if we are coming from a resource that wasn't watched
151
- // but for which we have results already, just return the results but start watching it
152
- if (opt.watch !== false && !getters.watchStarted(args)) {
158
+ if (opt.watch !== false ) {
153
159
  dispatch('watch', args);
154
160
  }
155
161
 
@@ -297,8 +303,9 @@ export default {
297
303
  commit('loadAll', {
298
304
  ctx,
299
305
  type,
300
- data: out.data,
301
- skipHaveAll
306
+ data: out.data,
307
+ skipHaveAll,
308
+ namespace: opt.namespaced,
302
309
  });
303
310
  }
304
311
  }
@@ -483,6 +490,15 @@ export default {
483
490
  });
484
491
  },
485
492
 
493
+ batchChanges(ctx, batch) {
494
+ const { commit } = ctx;
495
+
496
+ commit('batchChanges', {
497
+ ctx,
498
+ batch
499
+ });
500
+ },
501
+
486
502
  loadAll(ctx, { type, data }) {
487
503
  const { commit } = ctx;
488
504
 
@@ -516,20 +532,7 @@ export default {
516
532
  // Forget a type in the store
517
533
  // Remove all entries for that type and stop watching it
518
534
  forgetType({ commit, getters, dispatch }, type) {
519
- const obj = {
520
- type,
521
- stop: true, // Stops the watch on a type
522
- };
523
-
524
- if (getters['schemaFor'](type) && getters['watchStarted'](obj)) {
525
- // Set that we don't want to watch this type
526
- // Otherwise, the dispatch to unwatch below will just cause a re-watch when we
527
- // detect the stop message from the backend over the web socket
528
- commit('setWatchStopped', obj);
529
- dispatch('watch', obj); // Ask the backend to stop watching the type
530
- // Make sure anything in the pending queue for the type is removed, since we've now removed the type
531
- commit('clearFromQueue', type);
532
- }
535
+ dispatch('unwatch', type);
533
536
 
534
537
  commit('forgetType', type);
535
538
  },
@@ -572,6 +575,10 @@ export default {
572
575
  return resource;
573
576
  },
574
577
 
578
+ cleanForDownload(ctx, resource) {
579
+ return resource;
580
+ },
581
+
575
582
  // Wait for a schema that is expected to exist that may not have been loaded yet (for instance when loadCluster is still running).
576
583
  async waitForSchema({ getters, dispatch }, { type }) {
577
584
  let tries = SCHEMA_CHECK_RETRIES;
@@ -11,6 +11,40 @@ import { keyFieldFor, normalizeType } from './normalize';
11
11
  import { lookup } from './model-loader';
12
12
  import garbageCollect from '@shell/utils/gc/gc';
13
13
 
14
+ export const urlFor = (state, getters) => (type, id, opt) => {
15
+ opt = opt || {};
16
+ type = getters.normalizeType(type);
17
+ let url = opt.url;
18
+
19
+ if ( !url ) {
20
+ const schema = getters.schemaFor(type);
21
+
22
+ if ( !schema ) {
23
+ throw new Error(`Unknown schema for type: ${ type }`);
24
+ }
25
+
26
+ url = schema.links.collection;
27
+
28
+ if ( !url ) {
29
+ throw new Error(`You don't have permission to list this type: ${ type }`);
30
+ }
31
+
32
+ if ( id ) {
33
+ url += `/${ id }`;
34
+ }
35
+ }
36
+
37
+ if ( !url.startsWith('/') && !url.startsWith('http') ) {
38
+ const baseUrl = state.config.baseUrl.replace(/\/$/, '');
39
+
40
+ url = `${ baseUrl }/${ url }`;
41
+ }
42
+
43
+ url = getters.urlOptions(url, opt);
44
+
45
+ return url;
46
+ };
47
+
14
48
  export default {
15
49
 
16
50
  all: (state, getters, rootState) => (type) => {
@@ -225,6 +259,21 @@ export default {
225
259
  return false;
226
260
  },
227
261
 
262
+ haveAllNamespace: (state, getters) => (type, namespace) => {
263
+ if (!namespace) {
264
+ return false;
265
+ }
266
+
267
+ type = getters.normalizeType(type);
268
+ const entry = state.types[type];
269
+
270
+ if ( entry ) {
271
+ return entry.haveNamespace === namespace;
272
+ }
273
+
274
+ return false;
275
+ },
276
+
228
277
  haveSelector: (state, getters) => (type, selector) => {
229
278
  type = getters.normalizeType(type);
230
279
  const entry = state.types[type];
@@ -244,39 +293,7 @@ export default {
244
293
  return keyFieldFor(type);
245
294
  },
246
295
 
247
- urlFor: (state, getters) => (type, id, opt) => {
248
- opt = opt || {};
249
- type = getters.normalizeType(type);
250
- let url = opt.url;
251
-
252
- if ( !url ) {
253
- const schema = getters.schemaFor(type);
254
-
255
- if ( !schema ) {
256
- throw new Error(`Unknown schema for type: ${ type }`);
257
- }
258
-
259
- url = schema.links.collection;
260
-
261
- if ( !url ) {
262
- throw new Error(`You don't have permission to list this type: ${ type }`);
263
- }
264
-
265
- if ( id ) {
266
- url += `/${ id }`;
267
- }
268
- }
269
-
270
- if ( !url.startsWith('/') && !url.startsWith('http') ) {
271
- const baseUrl = state.config.baseUrl.replace(/\/$/, '');
272
-
273
- url = `${ baseUrl }/${ url }`;
274
- }
275
-
276
- url = getters.urlOptions(url, opt);
277
-
278
- return url;
279
- },
296
+ urlFor,
280
297
 
281
298
  urlOptions: () => (url, opt) => {
282
299
  return url;