@rancher/shell 0.5.3 → 1.2.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 (356) hide show
  1. package/.DS_Store +0 -0
  2. package/assets/images/providers/aks-black.svg +28 -0
  3. package/assets/images/providers/aks.svg +31 -0
  4. package/assets/styles/global/_labeled-input.scss +1 -0
  5. package/assets/styles/global/_layout.scss +0 -99
  6. package/assets/translations/en-us.yaml +76 -74
  7. package/assets/translations/zh-hans.yaml +25 -23
  8. package/babel.config.js +1 -7
  9. package/chart/gatekeeper.vue +11 -2
  10. package/chart/istio.vue +10 -1
  11. package/chart/logging/index.vue +11 -2
  12. package/chart/monitoring/alerting/index.vue +21 -7
  13. package/chart/monitoring/grafana/index.vue +2 -57
  14. package/chart/monitoring/index.vue +26 -52
  15. package/chart/monitoring/prometheus/index.vue +43 -37
  16. package/chart/rancher-backup/index.vue +10 -3
  17. package/cloud-credential/azure.vue +17 -4
  18. package/components/AsyncButton.vue +0 -9
  19. package/components/Carousel.vue +0 -1
  20. package/components/ChartPsp.vue +76 -0
  21. package/components/ClusterIconMenu.vue +9 -24
  22. package/components/CodeMirror.vue +16 -75
  23. package/components/CopyCode.vue +2 -6
  24. package/components/CopyToClipboard.vue +1 -2
  25. package/components/CopyToClipboardText.vue +9 -14
  26. package/components/CruResource.vue +0 -1
  27. package/components/EtcdInfoBanner.vue +5 -5
  28. package/components/ExplorerProjectsNamespaces.vue +1 -25
  29. package/components/FixedBanner.vue +0 -1
  30. package/components/IconOrSvg.vue +1 -1
  31. package/components/Markdown.vue +12 -16
  32. package/components/Questions/index.vue +1 -1
  33. package/components/ResourceDetail/Masthead.vue +9 -25
  34. package/components/ResourceDetail/index.vue +4 -1
  35. package/components/ResourceList/Masthead.vue +18 -1
  36. package/components/ResourceTable.vue +2 -14
  37. package/components/ResourceYaml.vue +5 -34
  38. package/components/SideNav.vue +65 -43
  39. package/components/SortableTable/THead.vue +9 -7
  40. package/components/SortableTable/index.vue +2 -1
  41. package/components/StatusTable.vue +1 -5
  42. package/components/TabTitle.vue +84 -0
  43. package/components/Tabbed/index.vue +0 -12
  44. package/components/YamlEditor.vue +0 -1
  45. package/components/__tests__/ChartPsp.test.ts +75 -0
  46. package/components/__tests__/CopyCode.test.ts +4 -5
  47. package/components/fleet/FleetBundles.vue +11 -5
  48. package/components/fleet/FleetRepos.vue +27 -62
  49. package/components/fleet/FleetResources.vue +1 -6
  50. package/components/fleet/FleetStatus.vue +3 -3
  51. package/components/fleet/FleetSummary.vue +30 -35
  52. package/components/form/ArrayList.vue +8 -1
  53. package/components/form/ArrayListSelect.vue +9 -9
  54. package/components/form/BannerSettings.vue +0 -3
  55. package/components/form/FileSelector.vue +0 -1
  56. package/components/form/KeyValue.vue +0 -2
  57. package/components/form/LabeledSelect.vue +0 -4
  58. package/components/form/Password.vue +1 -3
  59. package/components/form/Select.vue +1 -1
  60. package/components/form/SelectOrCreateAuthSecret.vue +4 -4
  61. package/components/form/__tests__/KeyValue.test.ts +1 -1
  62. package/components/formatter/Checked.vue +3 -11
  63. package/components/formatter/ClusterProvider.vue +18 -1
  64. package/components/formatter/FleetSummaryGraph.vue +11 -23
  65. package/components/formatter/LiveDate.vue +16 -0
  66. package/components/formatter/LiveDuration.vue +1 -1
  67. package/components/formatter/PercentageBar.vue +1 -1
  68. package/components/formatter/WorkloadDetailEndpoints.vue +22 -12
  69. package/components/formatter/__tests__/ClusterProvider.test.ts +28 -0
  70. package/components/nav/Group.vue +2 -2
  71. package/components/nav/Header.vue +2 -2
  72. package/components/nav/Jump.vue +9 -19
  73. package/components/nav/TopLevelMenu.vue +18 -66
  74. package/components/nav/Type.vue +7 -16
  75. package/components/nav/WindowManager/ContainerLogs.vue +19 -120
  76. package/components/nav/WindowManager/ContainerShell.vue +1 -6
  77. package/components/nav/WindowManager/index.vue +10 -11
  78. package/components/nav/__tests__/TopLevelMenu.test.ts +1 -34
  79. package/components/nav/__tests__/Type.test.ts +1 -31
  80. package/components/nuxt/nuxt-child.js +78 -14
  81. package/components/nuxt/nuxt.js +1 -1
  82. package/components/user.retention/user-retention-header.vue +34 -0
  83. package/composables/useI18n.ts +26 -0
  84. package/composables/useStore.ts +16 -0
  85. package/config/harvester-manager-types.js +0 -2
  86. package/config/home-links.js +32 -2
  87. package/config/private-label.js +0 -22
  88. package/config/product/explorer.js +4 -4
  89. package/config/product/fleet.js +1 -6
  90. package/config/product/legacy.js +1 -84
  91. package/config/product/manager.js +15 -8
  92. package/config/query-params.js +0 -1
  93. package/config/router.js +368 -385
  94. package/config/settings.ts +9 -2
  95. package/config/store.js +1 -1
  96. package/config/system-namespaces.js +0 -3
  97. package/config/table-headers.js +27 -47
  98. package/config/types.js +5 -0
  99. package/config/uiplugins.js +1 -1
  100. package/core/plugin-helpers.js +5 -3
  101. package/core/plugin-routes.ts +114 -56
  102. package/core/plugin.ts +10 -16
  103. package/core/plugins-loader.js +9 -7
  104. package/core/plugins.js +3 -0
  105. package/core/types-provisioning.ts +0 -7
  106. package/creators/app/init +0 -19
  107. package/detail/fleet.cattle.io.bundle.vue +1 -1
  108. package/detail/fleet.cattle.io.cluster.vue +1 -11
  109. package/detail/node.vue +0 -42
  110. package/detail/pod.vue +1 -68
  111. package/detail/provisioning.cattle.io.cluster.vue +8 -25
  112. package/detail/workload/index.vue +1 -15
  113. package/dialog/ScaleMachineDownDialog.vue +17 -34
  114. package/edit/auth/googleoauth.vue +5 -1
  115. package/edit/catalog.cattle.io.clusterrepo.vue +7 -20
  116. package/edit/cloudcredential.vue +0 -2
  117. package/edit/fleet.cattle.io.gitrepo.vue +4 -3
  118. package/edit/management.cattle.io.project.vue +52 -1
  119. package/edit/management.cattle.io.setting.vue +2 -32
  120. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +1 -1
  121. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +2 -1
  122. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -1
  123. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -12
  124. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +1 -2
  125. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
  126. package/edit/provisioning.cattle.io.cluster/{tabs/Basics.vue → Basics.vue} +125 -106
  127. package/edit/provisioning.cattle.io.cluster/{tabs/MachinePool.vue → MachinePool.vue} +7 -1
  128. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +7 -15
  129. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
  130. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.test.ts → CustomCommand.tests.ts} +0 -6
  131. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  132. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +1 -7
  133. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  134. package/edit/provisioning.cattle.io.cluster/index.vue +40 -109
  135. package/edit/provisioning.cattle.io.cluster/rke2.vue +689 -152
  136. package/edit/service.vue +0 -12
  137. package/edit/token.vue +0 -1
  138. package/edit/workload/Upgrading.vue +2 -3
  139. package/edit/workload/index.vue +1 -2
  140. package/edit/workload/mixins/workload.js +1 -1
  141. package/initialize/App.js +71 -25
  142. package/initialize/client.js +162 -21
  143. package/initialize/index.js +124 -47
  144. package/initialize/layouts.ts +26 -0
  145. package/{components/templates → layouts}/blank.vue +1 -1
  146. package/{components/templates → layouts}/default.vue +98 -8
  147. package/{components/templates → layouts}/error.vue +19 -10
  148. package/{components/templates → layouts}/home.vue +1 -4
  149. package/{components/templates → layouts}/plain.vue +1 -4
  150. package/{components/templates → layouts}/standalone.vue +1 -1
  151. package/{components/templates → layouts}/unauthenticated.vue +1 -1
  152. package/list/catalog.cattle.io.app.vue +0 -1
  153. package/list/management.cattle.io.feature.vue +7 -1
  154. package/list/management.cattle.io.setting.vue +0 -1
  155. package/list/management.cattle.io.user.vue +25 -1
  156. package/list/node.vue +0 -1
  157. package/machine-config/__tests__/vmwarevsphere.test.ts +161 -56
  158. package/machine-config/azure.vue +37 -21
  159. package/machine-config/vmwarevsphere.vue +47 -42
  160. package/middleware/authenticated.js +19 -14
  161. package/mixins/auth-config.js +7 -2
  162. package/mixins/brand.js +41 -29
  163. package/mixins/fetch.server.js +73 -0
  164. package/mixins/labeled-form-element.ts +1 -6
  165. package/models/__tests__/management.cattle.io.node.ts +0 -85
  166. package/models/__tests__/namespace.test.ts +9 -49
  167. package/models/cluster/node.js +4 -4
  168. package/models/cluster.x-k8s.io.machine.js +1 -1
  169. package/models/cluster.x-k8s.io.machinedeployment.js +0 -14
  170. package/models/fleet.cattle.io.cluster.js +0 -4
  171. package/models/fleet.cattle.io.gitrepo.js +13 -56
  172. package/models/management.cattle.io.cluster.js +3 -11
  173. package/models/management.cattle.io.kontainerdriver.js +0 -1
  174. package/models/management.cattle.io.node.js +14 -18
  175. package/models/management.cattle.io.nodepool.js +0 -17
  176. package/models/management.cattle.io.project.js +36 -0
  177. package/models/management.cattle.io.setting.js +7 -11
  178. package/models/management.cattle.io.user.js +65 -0
  179. package/models/namespace.js +1 -1
  180. package/models/pod.js +0 -20
  181. package/models/provisioning.cattle.io.cluster.js +9 -91
  182. package/models/secret.js +18 -126
  183. package/models/storage.k8s.io.storageclass.js +1 -1
  184. package/models/workload.js +0 -16
  185. package/models/workload.service.js +0 -18
  186. package/package.json +10 -12
  187. package/pages/about.vue +1 -0
  188. package/pages/account/create-key.vue +1 -0
  189. package/pages/account/index.vue +1 -0
  190. package/pages/auth/login.vue +1 -0
  191. package/pages/auth/logout.vue +2 -0
  192. package/pages/auth/setup.vue +4 -37
  193. package/pages/auth/verify.vue +8 -14
  194. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +17 -2
  195. package/pages/c/_cluster/apps/charts/index.vue +58 -64
  196. package/pages/c/_cluster/apps/charts/install.helpers.js +13 -2
  197. package/pages/c/_cluster/apps/charts/install.vue +5 -5
  198. package/pages/c/_cluster/apps/index.vue +2 -0
  199. package/pages/c/_cluster/auth/index.vue +2 -0
  200. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  201. package/pages/c/_cluster/ecm/index.vue +2 -0
  202. package/pages/c/_cluster/explorer/index.vue +53 -56
  203. package/pages/c/_cluster/explorer/tools/index.vue +3 -171
  204. package/pages/c/_cluster/fleet/index.vue +1 -1
  205. package/pages/c/_cluster/index.vue +2 -0
  206. package/pages/c/_cluster/manager/pages/_page.vue +5 -4
  207. package/pages/c/_cluster/monitoring/index.vue +1 -17
  208. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -1
  209. package/pages/c/_cluster/settings/banners.vue +2 -0
  210. package/pages/c/_cluster/settings/brand.vue +2 -3
  211. package/pages/c/_cluster/settings/index.vue +2 -0
  212. package/pages/c/_cluster/settings/links.vue +3 -2
  213. package/pages/c/_cluster/settings/performance.vue +1 -0
  214. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +1 -2
  215. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +46 -10
  216. package/pages/c/_cluster/uiplugins/index.vue +2 -0
  217. package/pages/c/index.vue +9 -0
  218. package/pages/diagnostic.vue +2 -1
  219. package/pages/fail-whale.vue +1 -0
  220. package/pages/prefs.vue +1 -0
  221. package/pages/rio/mesh.vue +508 -0
  222. package/pages/support/index.vue +8 -2
  223. package/pkg/auto-import.js +1 -1
  224. package/plugins/axios.js +36 -0
  225. package/plugins/back-button.js +5 -3
  226. package/plugins/clean-html-directive.js +19 -1
  227. package/plugins/clean-tooltip-directive.js +1 -1
  228. package/plugins/codemirror-loader.js +1 -1
  229. package/plugins/codemirror.js +0 -41
  230. package/plugins/dashboard-store/__tests__/{mutations.test.ts → mutations.spec.ts} +1 -1
  231. package/plugins/dashboard-store/actions.js +17 -16
  232. package/plugins/dashboard-store/classify.js +18 -1
  233. package/plugins/dashboard-store/getters.js +7 -70
  234. package/plugins/dashboard-store/index.js +12 -0
  235. package/plugins/dashboard-store/mutations.js +4 -0
  236. package/plugins/dashboard-store/resource-class.js +20 -65
  237. package/plugins/i18n.js +1 -1
  238. package/plugins/steve/__tests__/getters.spec.ts +48 -26
  239. package/plugins/steve/__tests__/subscribe.spec.ts +106 -0
  240. package/plugins/steve/actions.js +37 -3
  241. package/plugins/steve/getters.js +24 -7
  242. package/plugins/steve/mutations.js +5 -2
  243. package/plugins/steve/norman-class.js +0 -19
  244. package/plugins/steve/steve-class.js +0 -22
  245. package/plugins/steve/subscribe.js +34 -13
  246. package/plugins/transitions.js +4 -0
  247. package/plugins/vue-clipboard2.js +4 -0
  248. package/rancher-components/Accordion/Accordion.vue +3 -2
  249. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  250. package/rancher-components/Banner/Banner.test.ts +1 -5
  251. package/rancher-components/Banner/Banner.vue +2 -2
  252. package/rancher-components/Card/Card.vue +4 -4
  253. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  254. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  255. package/rancher-components/Form/LabeledInput/LabeledInput.vue +55 -24
  256. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  257. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  258. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  259. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  260. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  261. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  262. package/rancher-components/StringList/StringList.vue +8 -8
  263. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  264. package/rancher-components/components/BadgeState/BadgeState.test.ts +12 -0
  265. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +2 -19
  266. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +14 -11
  267. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +1 -1
  268. package/rancher-components/components/StringList/StringList.test.ts +0 -270
  269. package/rancher-components/components/StringList/StringList.vue +18 -57
  270. package/scripts/extension/bundle +7 -19
  271. package/scripts/extension/helm/scripts/package +3 -11
  272. package/scripts/extension/parse-tag-name +4 -4
  273. package/scripts/extension/publish +9 -20
  274. package/scripts/publish-shell.sh +1 -11
  275. package/scripts/test-plugins-build.sh +9 -85
  276. package/store/catalog.js +1 -1
  277. package/store/features.js +0 -1
  278. package/store/i18n.js +0 -11
  279. package/store/index.js +13 -11
  280. package/store/prefs.js +38 -33
  281. package/store/type-map.js +82 -157
  282. package/tsconfig.default.json +46 -0
  283. package/tsconfig.json +9 -35
  284. package/types/shell/index.d.ts +407 -468
  285. package/utils/axios.js +19 -0
  286. package/utils/create-yaml.js +1 -5
  287. package/utils/custom-validators.js +2 -0
  288. package/utils/error.js +1 -16
  289. package/utils/monitoring.js +2 -37
  290. package/utils/nuxt.js +39 -18
  291. package/utils/object.js +0 -24
  292. package/utils/router.scrollBehavior.js +14 -12
  293. package/utils/socket.js +1 -0
  294. package/utils/time.js +1 -1
  295. package/utils/title.ts +3 -0
  296. package/utils/url.ts +1 -1
  297. package/utils/validators/formRules/__tests__/index.test.ts +4 -49
  298. package/utils/validators/formRules/index.ts +9 -12
  299. package/utils/validators/setting.js +10 -6
  300. package/vue.config.js +3 -24
  301. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  302. package/components/Certificates.vue +0 -164
  303. package/components/__tests__/CodeMirror.spec.ts +0 -99
  304. package/components/fleet/__tests__/FleetSummary.test.ts +0 -316
  305. package/components/formatter/FleetClusterSummaryGraph.vue +0 -27
  306. package/components/formatter/__tests__/Checked.test.ts +0 -19
  307. package/components/formatter/__tests__/WorkloadDetailEndpoints.test.ts +0 -81
  308. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +0 -186
  309. package/composables/useCompactInput.ts +0 -20
  310. package/composables/useLabeledFormElement.ts +0 -138
  311. package/creators/app/files/.gitlab-ci.yml +0 -14
  312. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +0 -77
  313. package/edit/__tests__/service.test.ts +0 -89
  314. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -112
  315. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +0 -473
  316. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +0 -73
  317. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +0 -386
  318. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +0 -137
  319. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +0 -157
  320. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -135
  321. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +0 -189
  322. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +0 -147
  323. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +0 -76
  324. package/mixins/v1-workload-metrics.js +0 -43
  325. package/models/__tests__/management.cattle.io.cluster.test.ts +0 -23
  326. package/models/__tests__/management.cattle.io.nodepool.ts +0 -83
  327. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -241
  328. package/models/__tests__/secret.test.ts +0 -37
  329. package/models/__tests__/storage.k8s.io.storageclass.test.ts +0 -22
  330. package/models/__tests__/workload.test.ts +0 -91
  331. package/plugins/clean-html.js +0 -53
  332. package/plugins/dashboard-store/__tests__/resource-class.test.ts +0 -49
  333. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +0 -7
  334. package/plugins/index.js +0 -11
  335. package/plugins/steve/__tests__/resource-utils.test.ts +0 -159
  336. package/plugins/steve/__tests__/steve-class.spec.ts +0 -59
  337. package/plugins/steve/__tests__/utils/steve-mocks.ts +0 -31
  338. package/plugins/steve/resource-utils.ts +0 -38
  339. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +0 -50
  340. package/server/har-file.js +0 -183
  341. package/store/__tests__/type-map.test.ts +0 -1122
  342. package/tsconfig.paths.json +0 -18
  343. package/utils/azure.js +0 -24
  344. package/utils/clipboard.js +0 -5
  345. /package/components/form/__tests__/{NameNsDescription.test.ts → NameNsDescription.ts} +0 -0
  346. /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.test.ts → selectors.ts} +0 -0
  347. /package/edit/provisioning.cattle.io.cluster/{tabs/networking/ACE.vue → ACE.vue} +0 -0
  348. /package/edit/provisioning.cattle.io.cluster/{tabs/AgentConfiguration.vue → AgentConfiguration.vue} +0 -0
  349. /package/edit/provisioning.cattle.io.cluster/{tabs/upgrade/DrainOptions.vue → DrainOptions.vue} +0 -0
  350. /package/edit/provisioning.cattle.io.cluster/{tabs/MemberRoles.vue → MemberRoles.vue} +0 -0
  351. /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryConfigs.vue → RegistryConfigs.vue} +0 -0
  352. /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryMirrors.vue → RegistryMirrors.vue} +0 -0
  353. /package/edit/provisioning.cattle.io.cluster/{tabs/etcd/S3Config.vue → S3Config.vue} +0 -0
  354. /package/plugins/dashboard-store/__tests__/{actions.test.ts → actions.spec.ts} +0 -0
  355. /package/plugins/dashboard-store/__tests__/{getters.test.ts → getters.spec.ts} +0 -0
  356. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
@@ -72,10 +72,6 @@ export async function loadSchemas(ctx, watch = true) {
72
72
  return all;
73
73
  }
74
74
 
75
- const findAllGetter = (getters, type, opt) => {
76
- return opt.namespaced ? getters.matching(type, null, opt.namespaced, { skipSelector: true }) : getters.all(type);
77
- };
78
-
79
75
  export default {
80
76
  request() {
81
77
  throw new Error('Not Implemented');
@@ -157,19 +153,19 @@ export default {
157
153
 
158
154
  // No need to request the resources if we have them already
159
155
  if ( opt.force !== true && (getters['haveAll'](type) || getters['haveAllNamespace'](type, opt.namespaced))) {
160
- const args = {
161
- type,
162
- revision: '',
163
- // watchNamespace - used sometimes when we haven't fetched the results of a single namespace
164
- // namespaced - used when we have fetched the result of a single namespace (see https://github.com/rancher/dashboard/pull/7329/files)
165
- namespace: opt.watchNamespace || opt.namespaced
166
- };
167
-
168
156
  if (opt.watch !== false ) {
157
+ const args = {
158
+ type,
159
+ revision: '',
160
+ // watchNamespace - used sometimes when we haven't fetched the results of a single namespace
161
+ // namespaced - used when we have fetched the result of a single namespace (see https://github.com/rancher/dashboard/pull/7329/files)
162
+ namespace: opt.watchNamespace || opt.namespaced
163
+ };
164
+
169
165
  dispatch('watch', args);
170
166
  }
171
167
 
172
- return findAllGetter(getters, type, opt);
168
+ return getters.all(type);
173
169
  }
174
170
 
175
171
  let load = (opt.load === undefined ? _ALL : opt.load);
@@ -334,7 +330,7 @@ export default {
334
330
  dispatch('watch', args);
335
331
  }
336
332
 
337
- const all = findAllGetter(getters, type, opt);
333
+ const all = getters.all(type);
338
334
 
339
335
  if (!opt.incremental && opt.hasManualRefresh) {
340
336
  dispatch('resource-fetch/updateManualRefreshIsLoading', false, { root: true });
@@ -443,8 +439,13 @@ export default {
443
439
  const watchMsg = {
444
440
  type,
445
441
  id,
446
- revision: res?.metadata?.resourceVersion,
447
- force: opt.forceWatch === true,
442
+ // Although not used by sockets, we need this for when resyncWatch calls find.... which needs namespace to construct the url
443
+ namespace: opt.namespaced,
444
+ // Override the revision. Used in cases where we need to avoid using the resource's own revision which would be `too old`.
445
+ // For the above case opt.revision will be `null`. If left as `undefined` the subscribe mechanism will try to determine a revision
446
+ // from resources in store (which would be this one, with the too old revision)
447
+ revision: typeof opt.revision !== 'undefined' ? opt.revision : res?.metadata?.resourceVersion,
448
+ force: opt.forceWatch === true,
448
449
  };
449
450
 
450
451
  const idx = id.indexOf('/');
@@ -12,7 +12,24 @@ export function classify(ctx, obj, isClone = false) {
12
12
 
13
13
  const customModel = ctx.getters['classify'](obj);
14
14
 
15
- const out = new customModel(obj, ctx, null, isClone);
15
+ const out = new customModel(obj, ctx, (process.server ? ctx.state.config.namespace : null), isClone);
16
+
17
+ if ( process.server ) {
18
+ Object.defineProperty(obj, '__rehydrate', {
19
+ value: ctx.state.config.namespace,
20
+ enumerable: true,
21
+ configurable: true
22
+ });
23
+
24
+ if ( isClone ) {
25
+ Object.defineProperty(obj, '__clone', {
26
+ value: true,
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true
30
+ });
31
+ }
32
+ }
16
33
 
17
34
  return out;
18
35
  }
@@ -1,5 +1,5 @@
1
1
 
2
- import { SCHEMA, COUNT } from '@shell/config/types';
2
+ import { SCHEMA } from '@shell/config/types';
3
3
 
4
4
  import { matches } from '@shell/utils/selector';
5
5
  import { typeMunge, typeRef, SIMPLE_TYPES } from '@shell/utils/create-yaml';
@@ -45,29 +45,6 @@ export const urlFor = (state, getters) => (type, id, opt) => {
45
45
  return url;
46
46
  };
47
47
 
48
- /**
49
- * Find the number of resources given
50
- * - if the type is namespaced
51
- * - if there are any counts per namespace
52
- * - if there are no namespaces
53
- * - if there is no total count
54
- */
55
- function matchingCounts(typeObj, namespaces) {
56
- // That was easy
57
- if ( !typeObj.namespaced || !typeObj.byNamespace || namespaces === null || typeObj.count === null) {
58
- return typeObj.count;
59
- }
60
-
61
- let out = 0;
62
-
63
- // Otherwise start with 0 and count up
64
- for ( const namespace of namespaces ) {
65
- out += typeObj.byNamespace[namespace]?.count || 0;
66
- }
67
-
68
- return out;
69
- }
70
-
71
48
  export default {
72
49
 
73
50
  all: (state, getters, rootState) => (type) => {
@@ -87,24 +64,19 @@ export default {
87
64
  return state.types[type].list;
88
65
  },
89
66
 
90
- matching: (state, getters, rootState) => (type, selector, namespace, config = { skipSelector: false }) => {
91
- let matching = getters['all'](type);
67
+ matching: (state, getters, rootState) => (type, selector, namespace) => {
68
+ let all = getters['all'](type);
92
69
 
93
70
  // Filter first by namespace if one is provided, since this is efficient
94
- if (namespace && typeof namespace === 'string') {
95
- matching = matching.filter((obj) => obj.namespace === namespace);
71
+ if (namespace) {
72
+ all = all.filter((obj) => obj.namespace === namespace);
96
73
  }
97
74
 
98
75
  garbageCollect.gcUpdateLastAccessed({
99
76
  state, getters, rootState
100
77
  }, type);
101
78
 
102
- // Looks like a falsy selector is a thing, so if we're not interested in filtering by the selector... explicitly avoid it
103
- if (config.skipSelector) {
104
- return matching;
105
- }
106
-
107
- return matching.filter((obj) => {
79
+ return all.filter((obj) => {
108
80
  return matches(obj, selector);
109
81
  });
110
82
  },
@@ -368,40 +340,5 @@ export default {
368
340
 
369
341
  gcIgnoreTypes: () => {
370
342
  return {};
371
- },
372
-
373
- /**
374
- * For the given type, and it's settings, find the number of resources associated with it
375
- *
376
- * This takes into account if the type is namespaced.
377
- *
378
- * @param typeObj see inners for properties. must have at least `name` (resource type)
379
- *
380
- */
381
- count: (state, getters, rootState, rootGetters) => (typeObj) => {
382
- let _typeObj = typeObj;
383
- const { name: type, count } = _typeObj;
384
-
385
- if (!type) {
386
- throw new Error(`Resource type required to calc count: ${ JSON.stringify(typeObj) }`);
387
- }
388
-
389
- if (!count) {
390
- const schema = getters.schemaFor(type);
391
- const counts = getters.all(COUNT)?.[0]?.counts || {};
392
- const count = counts[type];
393
-
394
- _typeObj = {
395
- count: count ? count.summary.count || 0 : null,
396
- byNamespace: count ? count.namespaces : {},
397
- revision: count ? count.revision : null,
398
- namespaced: schema?.attributes?.namespaced
399
- };
400
- }
401
-
402
- const namespaces = Object.keys(rootGetters.activeNamespaceCache || {});
403
-
404
- return matchingCounts(_typeObj, namespaces.length ? namespaces : null);
405
- },
406
-
343
+ }
407
344
  };
@@ -33,9 +33,21 @@ export default (vuexModule, config, init) => {
33
33
  const namespace = config.namespace || '';
34
34
 
35
35
  return function(store) {
36
+ // const inst = SteveFactory(namespace, config.baseUrl);
37
+
36
38
  store.registerModule(namespace, vuexModule);
37
39
  store.commit(`${ namespace }/applyConfig`, config);
38
40
 
41
+ if ( !process.client ) {
42
+ return;
43
+ }
44
+
45
+ // store.subscribe(({ type }, state) => {
46
+ // if ( type === 'auth/loggedOut' ) {
47
+ // store.dispatch(`${ namespace }/unsubscribe`);
48
+ // }
49
+ // });
50
+
39
51
  const module = store._modules.root._children[namespace];
40
52
  const fromServer = window.__NUXT__;
41
53
 
@@ -23,6 +23,10 @@ function registerType(state, type) {
23
23
  // Not enumerable so they don't get sent back to the client for SSR
24
24
  Object.defineProperty(cache, 'map', { value: new Map() });
25
25
 
26
+ if ( process.server && !cache.list.__rehydrateAll ) {
27
+ Object.defineProperty(cache.list, '__rehydrateAll', { value: `${ state.config.namespace }/${ type }`, enumerable: true });
28
+ }
29
+
26
30
  Vue.set(state.types, type, cache);
27
31
  }
28
32
 
@@ -105,7 +105,6 @@ export const STATES_ENUM = {
105
105
  ERRORING: 'erroring',
106
106
  ERRORS: 'errors',
107
107
  EXPIRED: 'expired',
108
- EXPIRING: 'expiring',
109
108
  FAIL: 'fail',
110
109
  FAILED: 'failed',
111
110
  HEALTHY: 'healthy',
@@ -168,13 +167,6 @@ export const STATES_ENUM = {
168
167
  WARNING: 'warning',
169
168
  };
170
169
 
171
- export function mapStateToEnum(statusString) {
172
- // e.g. in fleet Status is Capitalized. This function will map it to the enum
173
- return Object.values(STATES_ENUM).find((val) => {
174
- return val.toLowerCase() === statusString.toLocaleLowerCase();
175
- });
176
- }
177
-
178
170
  export const STATES = {
179
171
  [STATES_ENUM.IN_USE]: {
180
172
  color: 'success', icon: 'dot-open', label: 'In Use', compoundIcon: 'checkmark'
@@ -261,10 +253,7 @@ export const STATES = {
261
253
  color: 'error', icon: 'error', label: 'Errors', compoundIcon: 'error'
262
254
  },
263
255
  [STATES_ENUM.EXPIRED]: {
264
- color: 'error', icon: 'error', label: 'Expired', compoundIcon: 'warning'
265
- },
266
- [STATES_ENUM.EXPIRING]: {
267
- color: 'warning', icon: 'error', label: 'Expiring', compoundIcon: 'error'
256
+ color: 'warning', icon: 'error', label: 'Expired', compoundIcon: 'warning'
268
257
  },
269
258
  [STATES_ENUM.FAIL]: {
270
259
  color: 'error', icon: 'error', label: 'Fail', compoundIcon: 'error'
@@ -523,28 +512,6 @@ export function stateDisplay(state) {
523
512
  return key.split(/-/).map(ucFirst).join('-');
524
513
  }
525
514
 
526
- export function primaryDisplayStatusFromCount(status) {
527
- const statusOrder = [
528
- STATES_ENUM.ERROR,
529
- STATES_ENUM.FAILED,
530
- STATES_ENUM.WARNING,
531
- STATES_ENUM.MODIFIED,
532
- STATES_ENUM.WAIT_APPLIED,
533
- STATES_ENUM.ORPHANED,
534
- STATES_ENUM.MISSING,
535
- STATES_ENUM.UNKNOWN,
536
- STATES_ENUM.NOT_READY,
537
- STATES_ENUM.READY,
538
- ];
539
-
540
- // sort status by order of statusOrder
541
- const existingStatuses = Object.keys(status).filter((key) => {
542
- return status[key] > 0 && statusOrder.includes(key.toLowerCase());
543
- }).sort((a, b) => statusOrder.indexOf(a.toLowerCase()) - statusOrder.indexOf(b.toLowerCase()));
544
-
545
- return existingStatuses[0] ? existingStatuses[0] : STATES_ENUM.UNKNOWN;
546
- }
547
-
548
515
  export function stateSort(color, display) {
549
516
  color = color.replace(/^(text|bg)-/, '');
550
517
 
@@ -1122,16 +1089,6 @@ export default class Resource {
1122
1089
  return this._save(...arguments);
1123
1090
  }
1124
1091
 
1125
- /**
1126
- * Remove any unwanted properties from the object that will be saved
1127
- */
1128
- cleanForSave(data, forNew) {
1129
- delete data.__rehydrate;
1130
- delete data.__clone;
1131
-
1132
- return data;
1133
- }
1134
-
1135
1092
  /**
1136
1093
  * Allow to handle the response of the save request
1137
1094
  * @param {*} res Full request response
@@ -1139,6 +1096,9 @@ export default class Resource {
1139
1096
  processSaveResponse(res) { }
1140
1097
 
1141
1098
  async _save(opt = {}) {
1099
+ delete this.__rehydrate;
1100
+ delete this.__clone;
1101
+
1142
1102
  const forNew = !this.id;
1143
1103
 
1144
1104
  const errors = await this.validationErrors(this, opt.ignoreFields);
@@ -1185,24 +1145,22 @@ export default class Resource {
1185
1145
  // @TODO remove this once the API maps steve _type <-> k8s type in both directions
1186
1146
  opt.data = this.toSave() || { ...this };
1187
1147
 
1188
- if (opt.data._type) {
1148
+ if (opt?.data._type) {
1189
1149
  opt.data.type = opt.data._type;
1190
1150
  }
1191
1151
 
1192
- if (opt.data._name) {
1152
+ if (opt?.data._name) {
1193
1153
  opt.data.name = opt.data._name;
1194
1154
  }
1195
1155
 
1196
- if (opt.data._labels) {
1156
+ if (opt?.data._labels) {
1197
1157
  opt.data.labels = opt.data._labels;
1198
1158
  }
1199
1159
 
1200
- if (opt.data._annotations) {
1160
+ if (opt?.data._annotations) {
1201
1161
  opt.data.annotations = opt.data._annotations;
1202
1162
  }
1203
1163
 
1204
- opt.data = this.cleanForSave(opt.data, forNew);
1205
-
1206
1164
  // handle "replace" opt as a query param _replace=true for norman PUT requests
1207
1165
  if (opt?.replace && opt.method === 'put') {
1208
1166
  const argParam = opt.url.includes('?') ? '&' : '?';
@@ -1260,11 +1218,19 @@ export default class Resource {
1260
1218
  // ------------------------------------------------------------------
1261
1219
 
1262
1220
  currentRoute() {
1263
- return window.$nuxt.$route;
1221
+ if ( process.server ) {
1222
+ return this.$rootState.$route;
1223
+ } else {
1224
+ return window.$nuxt.$route;
1225
+ }
1264
1226
  }
1265
1227
 
1266
1228
  currentRouter() {
1267
- return window.$nuxt.$router;
1229
+ if ( process.server ) {
1230
+ return this.$rootState.$router;
1231
+ } else {
1232
+ return window.$nuxt.$router;
1233
+ }
1268
1234
  }
1269
1235
 
1270
1236
  get listLocation() {
@@ -1381,7 +1347,7 @@ export default class Resource {
1381
1347
 
1382
1348
  async download() {
1383
1349
  const value = await this.followLink('view', { headers: { accept: 'application/yaml' } });
1384
- const data = await this.cleanForDownload(value.data);
1350
+ const data = await this.$dispatch('cleanForDownload', value.data);
1385
1351
 
1386
1352
  downloadFile(`${ this.nameDisplay }.yaml`, data, 'application/yaml');
1387
1353
  }
@@ -1404,7 +1370,7 @@ export default class Resource {
1404
1370
  await eachLimit(items, 10, (item, idx) => {
1405
1371
  return item.followLink('view', { headers: { accept: 'application/yaml' } } ).then(async(data) => {
1406
1372
  const yaml = data.data || data;
1407
- const cleanedYaml = await this.cleanForDownload(yaml);
1373
+ const cleanedYaml = await this.$dispatch('cleanForDownload', yaml);
1408
1374
 
1409
1375
  files[`resources/${ names[idx] }`] = cleanedYaml;
1410
1376
  });
@@ -1481,10 +1447,6 @@ export default class Resource {
1481
1447
  this.$dispatch(`cleanForDiff`, this.toJSON());
1482
1448
  }
1483
1449
 
1484
- async cleanForDownload(yaml) {
1485
- return this.$dispatch(`cleanForDownload`, yaml);
1486
- }
1487
-
1488
1450
  yamlForSave(yaml) {
1489
1451
  try {
1490
1452
  const obj = jsyaml.load(yaml);
@@ -1969,11 +1931,4 @@ export default class Resource {
1969
1931
  get creationTimestamp() {
1970
1932
  return this.metadata?.creationTimestamp;
1971
1933
  }
1972
-
1973
- /**
1974
- * Allows model to specify JSON Paths that should be folded in the YAML editor by default
1975
- */
1976
- get yamlFolding() {
1977
- return [];
1978
- }
1979
1934
  }
package/plugins/i18n.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import Vue from 'vue';
2
2
  import { escapeHtml } from '../utils/string';
3
3
 
4
- function stringFor(store, key, args, raw = false, escapehtml = true) {
4
+ export function stringFor(store, key, args, raw = false, escapehtml = true) {
5
5
  const translation = store.getters['i18n/t'](key, args);
6
6
 
7
7
  let out;
@@ -5,36 +5,63 @@ const { urlFor, urlOptions } = _getters;
5
5
  describe('steve: getters', () => {
6
6
  describe('steve > getters > urlFor', () => {
7
7
  // we're not testing function output based off of state or getter inputs here since they are dependencies
8
- const state = { config: { baseUrl: 'protocol' } };
8
+ const baseUrl = '/v1';
9
+ const collectionUrl = 'https://abc.com/v1/urlFoo';
10
+ const namespace = 'myNamespace';
11
+ const state = { config: { baseUrl } };
9
12
  const getters = {
10
- normalizeType: (type) => type,
11
- schemaFor: (type) => {
12
- if (type === 'typeFoo') {
13
- return { links: { collection: 'urlFoo' } };
13
+ normalizeType: (type: string) => type,
14
+ schemaFor: (type: string) => {
15
+ if (type === 'rType') {
16
+ return { links: { collection: collectionUrl } };
17
+ }
18
+ if (type === 'trailingforwardslash') {
19
+ return { links: { collection: `${ collectionUrl }/` } };
14
20
  }
15
21
  },
16
22
  // this has its own tests so it just returns the input string
17
- urlOptions: (string) => string
23
+ urlOptions: (url: string, opt: any) => {
24
+ if (opt.addParam) {
25
+ url += '?param=true';
26
+ }
27
+
28
+ return url;
29
+ }
18
30
  };
19
31
 
20
32
  const urlForGetter = urlFor(state, getters);
21
33
 
22
34
  // most tests for this getter will go through the dashboard-store getters test spec, this only tests logic specific to the steve variant
23
35
 
24
- it('expects urlFor to return a function', () => {
25
- expect(typeof urlFor(state, getters)).toBe('function');
26
- });
36
+ it.each([
37
+ ['rType', undefined, undefined, collectionUrl],
27
38
 
28
- it('expects function returned by urlFor to return a string a type', () => {
29
- expect(urlForGetter('typeFoo')).toBe('protocol/urlFoo');
30
- });
39
+ // No namespace
40
+ ['rType', undefined, { }, `${ collectionUrl }`],
41
+ ['rType', undefined, { addParam: true }, `${ collectionUrl }?param=true`],
42
+ ['rType', 'abc', { }, `${ collectionUrl }/abc`],
43
+ ['rType', 'abc', { addParam: true }, `${ collectionUrl }/abc?param=true`],
31
44
 
32
- it('expects function returned by urlFor to return a string containing a namespace when provided with a type and a single namespace string', () => {
33
- expect(urlForGetter('typeFoo', undefined, { namespaced: 'nsBar' })).toBe('protocol/urlFoo/nsBar');
34
- });
45
+ // With namespace
46
+ ['rType', undefined, { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }`],
47
+ ['rType', undefined, { addParam: true, namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }?param=true`],
48
+ ['rType', 'abc', { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }/abc`],
49
+ ['rType', 'abc', { addParam: true, namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }/abc?param=true`],
50
+
51
+ // With url (mostly no op)
52
+ ['rType', undefined, { url: `${ baseUrl }/urlFoo`, namespaced: `${ namespace }` }, `${ baseUrl }/urlFoo`],
53
+ ['rType', undefined, { url: `${ baseUrl }/urlFoo/abc`, namespaced: `${ namespace }` }, `${ baseUrl }/urlFoo/abc`],
54
+ ['rType', undefined, { url: `/urlFoo`, namespaced: `${ namespace }` }, `/urlFoo`],
55
+ ['rType', undefined, { url: `/urlFoo/abc`, namespaced: `${ namespace }` }, `/urlFoo/abc`],
56
+
57
+ // multiple namespaces (no op)
58
+ ['rType', undefined, { namespaced: [`${ namespace }`, 'nsBaz'] }, `${ collectionUrl }`],
35
59
 
36
- it('expects function returned by urlFor to return a string not containing a namespace when provided with a type and a multiple namespaces string', () => {
37
- expect(urlForGetter('typeFoo', undefined, { namespaced: ['nsBar', 'nsBaz'] })).toBe('protocol/urlFoo');
60
+ // handle trailing space
61
+ ['trailingforwardslash', undefined, { namespaced: `${ namespace }` }, `${ collectionUrl }/${ namespace }`],
62
+
63
+ ])("given type '%p', id '%p' and opt '%p', should get url '%p'", (type, id, opt, url) => {
64
+ expect(urlForGetter(type, id, opt)).toBe(url);
38
65
  });
39
66
  });
40
67
 
@@ -43,13 +70,8 @@ describe('steve: getters', () => {
43
70
  const state = { config: { baseUrl: 'protocol' } };
44
71
  const getters = {
45
72
  normalizeType: (type) => type,
46
- schemaFor: (type) => {
47
- if (type === 'typeFoo') {
48
- return { links: { collection: 'urlFoo' } };
49
- }
50
- },
51
73
  // this has its own tests so it just returns the input string
52
- urlOptions: (string) => string
74
+ urlOptions: (string) => string
53
75
  };
54
76
 
55
77
  const urlOptionsGetter = urlOptions();
@@ -72,8 +94,8 @@ describe('steve: getters', () => {
72
94
  it('returns a string with a single filter statement applied and formatted for steve if a single filter statement is applied and the url starts with "/v1"', () => {
73
95
  expect(urlOptionsGetter('/v1/foo', { filter: { bar: 'baz' } })).toBe('/v1/foo?filter=bar=baz&exclude=metadata.managedFields');
74
96
  });
75
- it('returns a string with a single filter statement applied and formatted for steve if a single filter statement is applied and the url starts with "/k8s/clusters/c-m-n4x45x4b/v1/"', () => {
76
- expect(urlOptionsGetter('/k8s/clusters/c-m-n4x45x4b/v1/foo', { filter: { bar: 'baz' } })).toBe('/k8s/clusters/c-m-n4x45x4b/v1/foo?filter=bar=baz&exclude=metadata.managedFields');
97
+ it('returns a string with a single filter statement applied and formatted for steve if a single filter statement is NOT applied and the url starts with "/k8s/clusters/c-m-n4x45x4b/v1/"', () => {
98
+ expect(urlOptionsGetter('/k8s/clusters/c-m-n4x45x4b/v1/foo', { filter: { bar: 'baz' } })).toBe('/k8s/clusters/c-m-n4x45x4b/v1/foo?bar=baz');
77
99
  });
78
100
  it('returns a string with a multiple filter statements applied if a single filter statement is applied', () => {
79
101
  expect(urlOptionsGetter('foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('foo?bar=baz&far=faz');
@@ -93,7 +115,7 @@ describe('steve: getters', () => {
93
115
  it('returns a string without an exclude statement if excludeFields is but the url does not start with "/v1/"', () => {
94
116
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
95
117
  });
96
- it('returns a string without an exclude statement if excludeFields is an array but the URL doesnt include the "/v1/ string"', () => {
118
+ it('returns a string without an exclude statement if excludeFields is an array but the URL doesn\'t include the "/v1/ string"', () => {
97
119
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
98
120
  });
99
121
  it('returns a string with a limit applied if a limit is provided', () => {
@@ -0,0 +1,106 @@
1
+ import { actions } from '../subscribe';
2
+
3
+ describe('steve: subscribe', () => {
4
+ describe('actions', () => {
5
+ describe('watch', () => {
6
+ const state = {};
7
+ const getters = {
8
+ normalizeType: (type: string) => type,
9
+ schemaFor: () => null,
10
+ inError: () => false,
11
+ watchStarted: () => false,
12
+ };
13
+ const rootGetters = { 'type-map/isSpoofed': () => false };
14
+
15
+ const type = 'test';
16
+ const selector = undefined;
17
+ const id = undefined;
18
+ const revision = 1;
19
+ const namespace = undefined;
20
+ const stop = false;
21
+ const force = undefined;
22
+
23
+ it('no schema', () => {
24
+ const dispatch = jest.fn();
25
+
26
+ actions.watch({
27
+ state, dispatch, getters, rootGetters
28
+ }, {
29
+ type, selector, id, revision, namespace, stop, force
30
+ });
31
+
32
+ expect(dispatch).toHaveBeenCalledWith('send', {
33
+ resourceType: type,
34
+ resourceVersion: revision.toString(),
35
+
36
+ });
37
+ });
38
+
39
+ it('schema with watch verb', () => {
40
+ const dispatch = jest.fn();
41
+ const testGetters = {
42
+ ...getters,
43
+ schemaFor: (type: string) => ({ attributes: { verbs: ['watch'] } }),
44
+ };
45
+
46
+ actions.watch({
47
+ state, dispatch, getters: testGetters, rootGetters
48
+ }, {
49
+ type, selector, id, revision, namespace, stop, force
50
+ });
51
+
52
+ expect(dispatch).toHaveBeenCalledWith('send', {
53
+ resourceType: type,
54
+ resourceVersion: revision.toString(),
55
+ });
56
+ });
57
+
58
+ it('schema with no watch verb', () => {
59
+ const dispatch = jest.fn();
60
+ const testGetters = {
61
+ ...getters,
62
+ schemaFor: (type: string) => ({ attributes: { verbs: [] } }),
63
+ };
64
+
65
+ actions.watch({
66
+ state, dispatch, getters: testGetters, rootGetters
67
+ }, {
68
+ type, selector, id, revision, namespace, stop, force
69
+ });
70
+
71
+ expect(dispatch).not.toHaveBeenCalled();
72
+ });
73
+
74
+ it('don\'t watch when the watch is in error', () => {
75
+ const dispatch = jest.fn();
76
+ const testGetters = {
77
+ ...getters,
78
+ inError: (params: any) => true,
79
+ };
80
+
81
+ actions.watch({
82
+ state, dispatch, getters: testGetters, rootGetters
83
+ }, {
84
+ type, selector, id, revision, namespace, stop, force
85
+ });
86
+
87
+ expect(dispatch).not.toHaveBeenCalled();
88
+ });
89
+ });
90
+
91
+ describe('ws.resource.error', () => {
92
+ it('handle no permission error', () => {
93
+ const commit = jest.fn();
94
+ const getters = { storeName: 'storeName' };
95
+ const dispatch = undefined;
96
+
97
+ const msg = { data: { error: 'the server does not allow this method on the requested resource' } };
98
+
99
+ actions['ws.resource.error']({
100
+ getters, commit, dispatch
101
+ }, msg);
102
+ expect(commit).toHaveBeenCalledWith('setInError', { msg, reason: 'NO_PERMS' });
103
+ });
104
+ });
105
+ });
106
+ });