@rancher/shell 0.5.2 → 1.2.0

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 (338) 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 +77 -71
  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/CodeMirror.vue +21 -19
  22. package/components/CopyCode.vue +2 -6
  23. package/components/CopyToClipboard.vue +1 -2
  24. package/components/CopyToClipboardText.vue +9 -14
  25. package/components/CruResource.vue +0 -1
  26. package/components/EtcdInfoBanner.vue +5 -5
  27. package/components/ExplorerProjectsNamespaces.vue +1 -25
  28. package/components/IconOrSvg.vue +1 -1
  29. package/components/Markdown.vue +12 -16
  30. package/components/Questions/index.vue +1 -1
  31. package/components/ResourceDetail/Masthead.vue +9 -25
  32. package/components/ResourceList/Masthead.vue +18 -1
  33. package/components/ResourceTable.vue +2 -14
  34. package/components/ResourceYaml.vue +0 -5
  35. package/components/SideNav.vue +1 -1
  36. package/components/SortableTable/THead.vue +9 -7
  37. package/components/SortableTable/index.vue +3 -2
  38. package/components/StatusTable.vue +1 -5
  39. package/components/TabTitle.vue +84 -0
  40. package/components/Tabbed/index.vue +0 -12
  41. package/components/__tests__/ChartPsp.test.ts +75 -0
  42. package/components/__tests__/CopyCode.test.ts +4 -5
  43. package/components/fleet/FleetBundles.vue +11 -5
  44. package/components/fleet/FleetRepos.vue +27 -62
  45. package/components/fleet/FleetResources.vue +1 -6
  46. package/components/fleet/FleetStatus.vue +3 -3
  47. package/components/fleet/FleetSummary.vue +30 -35
  48. package/components/form/ArrayList.vue +8 -1
  49. package/components/form/ArrayListSelect.vue +9 -9
  50. package/components/form/KeyValue.vue +0 -1
  51. package/components/form/LabeledSelect.vue +0 -4
  52. package/components/form/Password.vue +1 -3
  53. package/components/form/Select.vue +1 -1
  54. package/components/form/SelectOrCreateAuthSecret.vue +4 -4
  55. package/components/form/__tests__/KeyValue.test.ts +1 -1
  56. package/components/formatter/Checked.vue +3 -11
  57. package/components/formatter/ClusterProvider.vue +18 -1
  58. package/components/formatter/FleetSummaryGraph.vue +11 -23
  59. package/components/formatter/LiveDate.vue +16 -0
  60. package/components/formatter/LiveDuration.vue +1 -1
  61. package/components/formatter/PercentageBar.vue +1 -1
  62. package/components/formatter/__tests__/ClusterProvider.test.ts +28 -0
  63. package/components/nav/Group.vue +2 -2
  64. package/components/nav/Header.vue +2 -1
  65. package/components/nav/TopLevelMenu.vue +3 -29
  66. package/components/nav/Type.vue +3 -1
  67. package/components/nav/WindowManager/ContainerLogs.vue +19 -120
  68. package/components/nav/WindowManager/ContainerShell.vue +1 -6
  69. package/components/nav/WindowManager/index.vue +10 -11
  70. package/components/nav/__tests__/TopLevelMenu.test.ts +0 -33
  71. package/components/nav/__tests__/Type.test.ts +1 -1
  72. package/components/nuxt/nuxt-child.js +78 -14
  73. package/components/nuxt/nuxt.js +1 -1
  74. package/components/user.retention/user-retention-header.vue +34 -0
  75. package/composables/useI18n.ts +26 -0
  76. package/composables/useStore.ts +16 -0
  77. package/config/harvester-manager-types.js +0 -2
  78. package/config/home-links.js +32 -2
  79. package/config/private-label.js +0 -22
  80. package/config/product/explorer.js +4 -4
  81. package/config/product/fleet.js +1 -6
  82. package/config/product/legacy.js +1 -84
  83. package/config/product/manager.js +15 -8
  84. package/config/query-params.js +0 -1
  85. package/config/router.js +368 -385
  86. package/config/settings.ts +9 -2
  87. package/config/store.js +1 -1
  88. package/config/system-namespaces.js +0 -3
  89. package/config/table-headers.js +27 -47
  90. package/config/types.js +5 -0
  91. package/config/uiplugins.js +1 -1
  92. package/core/plugin-helpers.js +5 -3
  93. package/core/plugin-routes.ts +114 -56
  94. package/core/plugin.ts +10 -16
  95. package/core/plugins-loader.js +9 -7
  96. package/core/plugins.js +3 -0
  97. package/core/types-provisioning.ts +0 -7
  98. package/creators/app/init +0 -19
  99. package/detail/fleet.cattle.io.cluster.vue +1 -11
  100. package/detail/node.vue +0 -42
  101. package/detail/pod.vue +1 -68
  102. package/detail/provisioning.cattle.io.cluster.vue +4 -6
  103. package/detail/workload/index.vue +1 -15
  104. package/dialog/ScaleMachineDownDialog.vue +17 -34
  105. package/edit/auth/googleoauth.vue +5 -1
  106. package/edit/catalog.cattle.io.clusterrepo.vue +7 -20
  107. package/edit/cloudcredential.vue +0 -2
  108. package/edit/fleet.cattle.io.gitrepo.vue +4 -3
  109. package/edit/management.cattle.io.project.vue +52 -1
  110. package/edit/management.cattle.io.setting.vue +2 -31
  111. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -12
  112. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +1 -2
  113. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
  114. package/edit/provisioning.cattle.io.cluster/{tabs/Basics.vue → Basics.vue} +126 -109
  115. package/edit/provisioning.cattle.io.cluster/{tabs/MachinePool.vue → MachinePool.vue} +7 -1
  116. package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryConfigs.vue → RegistryConfigs.vue} +3 -1
  117. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +7 -15
  118. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
  119. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.test.ts → CustomCommand.tests.ts} +0 -6
  120. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  121. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +1 -7
  122. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  123. package/edit/provisioning.cattle.io.cluster/index.vue +37 -99
  124. package/edit/provisioning.cattle.io.cluster/rke2.vue +690 -181
  125. package/edit/service.vue +0 -12
  126. package/edit/workload/Upgrading.vue +2 -3
  127. package/edit/workload/index.vue +1 -2
  128. package/edit/workload/mixins/workload.js +1 -1
  129. package/initialize/App.js +71 -25
  130. package/initialize/client.js +162 -21
  131. package/initialize/index.js +124 -47
  132. package/initialize/layouts.ts +26 -0
  133. package/{components/templates → layouts}/blank.vue +1 -1
  134. package/{components/templates → layouts}/default.vue +98 -8
  135. package/{components/templates → layouts}/error.vue +19 -10
  136. package/{components/templates → layouts}/home.vue +1 -4
  137. package/{components/templates → layouts}/plain.vue +1 -4
  138. package/{components/templates → layouts}/standalone.vue +1 -1
  139. package/{components/templates → layouts}/unauthenticated.vue +1 -1
  140. package/list/management.cattle.io.feature.vue +7 -1
  141. package/list/management.cattle.io.user.vue +25 -1
  142. package/list/node.vue +0 -1
  143. package/machine-config/__tests__/vmwarevsphere.test.ts +161 -56
  144. package/machine-config/amazonec2.vue +1 -0
  145. package/machine-config/azure.vue +37 -21
  146. package/machine-config/vmwarevsphere.vue +47 -42
  147. package/middleware/authenticated.js +19 -14
  148. package/mixins/auth-config.js +7 -2
  149. package/mixins/brand.js +41 -29
  150. package/mixins/fetch.server.js +73 -0
  151. package/mixins/labeled-form-element.ts +1 -6
  152. package/models/__tests__/management.cattle.io.node.ts +0 -85
  153. package/models/__tests__/namespace.test.ts +9 -49
  154. package/models/cluster/node.js +4 -4
  155. package/models/cluster.x-k8s.io.machine.js +1 -1
  156. package/models/cluster.x-k8s.io.machinedeployment.js +0 -14
  157. package/models/fleet.cattle.io.cluster.js +0 -4
  158. package/models/fleet.cattle.io.gitrepo.js +13 -56
  159. package/models/management.cattle.io.cluster.js +3 -11
  160. package/models/management.cattle.io.kontainerdriver.js +0 -1
  161. package/models/management.cattle.io.node.js +14 -18
  162. package/models/management.cattle.io.nodepool.js +0 -17
  163. package/models/management.cattle.io.project.js +36 -0
  164. package/models/management.cattle.io.setting.js +7 -11
  165. package/models/management.cattle.io.user.js +65 -0
  166. package/models/namespace.js +1 -1
  167. package/models/pod.js +0 -20
  168. package/models/provisioning.cattle.io.cluster.js +8 -55
  169. package/models/secret.js +18 -117
  170. package/models/workload.js +0 -16
  171. package/models/workload.service.js +0 -18
  172. package/package.json +10 -12
  173. package/pages/about.vue +1 -0
  174. package/pages/account/create-key.vue +1 -0
  175. package/pages/account/index.vue +1 -0
  176. package/pages/auth/login.vue +1 -0
  177. package/pages/auth/logout.vue +2 -0
  178. package/pages/auth/setup.vue +4 -37
  179. package/pages/auth/verify.vue +8 -14
  180. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +17 -2
  181. package/pages/c/_cluster/apps/charts/index.vue +58 -64
  182. package/pages/c/_cluster/apps/charts/install.helpers.js +13 -2
  183. package/pages/c/_cluster/apps/charts/install.vue +5 -5
  184. package/pages/c/_cluster/apps/index.vue +2 -0
  185. package/pages/c/_cluster/auth/index.vue +2 -0
  186. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  187. package/pages/c/_cluster/ecm/index.vue +2 -0
  188. package/pages/c/_cluster/explorer/index.vue +53 -56
  189. package/pages/c/_cluster/explorer/tools/index.vue +3 -171
  190. package/pages/c/_cluster/fleet/index.vue +1 -1
  191. package/pages/c/_cluster/index.vue +2 -0
  192. package/pages/c/_cluster/manager/pages/_page.vue +5 -4
  193. package/pages/c/_cluster/monitoring/index.vue +1 -17
  194. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
  195. package/pages/c/_cluster/settings/banners.vue +2 -0
  196. package/pages/c/_cluster/settings/brand.vue +2 -0
  197. package/pages/c/_cluster/settings/index.vue +2 -0
  198. package/pages/c/_cluster/settings/links.vue +3 -2
  199. package/pages/c/_cluster/settings/performance.vue +1 -0
  200. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +4 -4
  201. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +1 -2
  202. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +46 -10
  203. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +5 -2
  204. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +96 -0
  205. package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +128 -0
  206. package/pages/c/_cluster/uiplugins/index.vue +2 -0
  207. package/pages/c/index.vue +9 -0
  208. package/pages/diagnostic.vue +2 -1
  209. package/pages/fail-whale.vue +1 -0
  210. package/pages/prefs.vue +1 -0
  211. package/pages/rio/mesh.vue +508 -0
  212. package/pages/support/index.vue +8 -2
  213. package/pkg/auto-import.js +1 -1
  214. package/plugins/axios.js +36 -0
  215. package/plugins/back-button.js +5 -3
  216. package/plugins/clean-html-directive.js +19 -1
  217. package/plugins/clean-tooltip-directive.js +1 -1
  218. package/plugins/codemirror-loader.js +1 -1
  219. package/plugins/codemirror.js +0 -41
  220. package/plugins/dashboard-store/__tests__/actions.spec.ts +250 -0
  221. package/plugins/dashboard-store/__tests__/{mutations.test.ts → mutations.spec.ts} +1 -1
  222. package/plugins/dashboard-store/actions.js +21 -22
  223. package/plugins/dashboard-store/classify.js +18 -1
  224. package/plugins/dashboard-store/getters.js +5 -10
  225. package/plugins/dashboard-store/index.js +12 -0
  226. package/plugins/dashboard-store/mutations.js +4 -0
  227. package/plugins/dashboard-store/resource-class.js +18 -59
  228. package/plugins/i18n.js +1 -1
  229. package/plugins/steve/__tests__/getters.spec.ts +56 -24
  230. package/plugins/steve/__tests__/subscribe.spec.ts +106 -0
  231. package/plugins/steve/getters.js +30 -7
  232. package/plugins/steve/mutations.js +5 -2
  233. package/plugins/steve/norman-class.js +0 -19
  234. package/plugins/steve/steve-class.js +0 -22
  235. package/plugins/steve/subscribe.js +34 -13
  236. package/plugins/transitions.js +4 -0
  237. package/plugins/vue-clipboard2.js +4 -0
  238. package/rancher-components/Accordion/Accordion.vue +3 -2
  239. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  240. package/rancher-components/Banner/Banner.test.ts +1 -5
  241. package/rancher-components/Banner/Banner.vue +2 -2
  242. package/rancher-components/Card/Card.vue +4 -4
  243. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  244. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  245. package/rancher-components/Form/LabeledInput/LabeledInput.vue +55 -24
  246. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  247. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  248. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  249. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  250. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  251. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  252. package/rancher-components/StringList/StringList.vue +8 -8
  253. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  254. package/rancher-components/components/BadgeState/BadgeState.test.ts +12 -0
  255. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +2 -19
  256. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +14 -11
  257. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +1 -1
  258. package/rancher-components/components/StringList/StringList.test.ts +0 -270
  259. package/rancher-components/components/StringList/StringList.vue +18 -57
  260. package/scripts/extension/bundle +7 -19
  261. package/scripts/extension/helm/scripts/package +3 -11
  262. package/scripts/extension/parse-tag-name +4 -4
  263. package/scripts/extension/publish +9 -20
  264. package/scripts/publish-shell.sh +1 -11
  265. package/scripts/test-plugins-build.sh +9 -85
  266. package/store/catalog.js +1 -1
  267. package/store/features.js +0 -1
  268. package/store/i18n.js +0 -11
  269. package/store/index.js +11 -8
  270. package/store/prefs.js +38 -33
  271. package/store/type-map.js +8 -13
  272. package/tsconfig.default.json +46 -0
  273. package/tsconfig.json +9 -35
  274. package/types/shell/index.d.ts +404 -463
  275. package/utils/__tests__/create-yaml.test.ts +10 -0
  276. package/utils/axios.js +19 -0
  277. package/utils/create-yaml.js +6 -6
  278. package/utils/custom-validators.js +2 -0
  279. package/utils/error.js +1 -16
  280. package/utils/monitoring.js +2 -37
  281. package/utils/nuxt.js +39 -18
  282. package/utils/object.js +0 -14
  283. package/utils/router.scrollBehavior.js +14 -12
  284. package/utils/socket.js +1 -0
  285. package/utils/time.js +1 -1
  286. package/utils/title.ts +3 -0
  287. package/utils/url.ts +1 -1
  288. package/utils/validators/formRules/__tests__/index.test.ts +4 -49
  289. package/utils/validators/formRules/index.ts +9 -12
  290. package/utils/validators/setting.js +10 -6
  291. package/vue.config.js +3 -24
  292. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  293. package/components/Certificates.vue +0 -164
  294. package/components/fleet/__tests__/FleetSummary.test.ts +0 -316
  295. package/components/formatter/FleetClusterSummaryGraph.vue +0 -27
  296. package/components/formatter/__tests__/Checked.test.ts +0 -19
  297. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +0 -186
  298. package/composables/useCompactInput.ts +0 -20
  299. package/composables/useLabeledFormElement.ts +0 -138
  300. package/creators/app/files/.gitlab-ci.yml +0 -14
  301. package/edit/__tests__/service.test.ts +0 -89
  302. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -112
  303. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +0 -473
  304. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +0 -73
  305. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +0 -386
  306. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +0 -137
  307. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +0 -157
  308. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -135
  309. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +0 -189
  310. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +0 -144
  311. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +0 -76
  312. package/mixins/v1-workload-metrics.js +0 -43
  313. package/models/__tests__/management.cattle.io.cluster.test.ts +0 -23
  314. package/models/__tests__/management.cattle.io.nodepool.ts +0 -83
  315. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -90
  316. package/models/__tests__/workload.test.ts +0 -91
  317. package/plugins/clean-html.js +0 -53
  318. package/plugins/dashboard-store/__tests__/actions.test.ts +0 -165
  319. package/plugins/dashboard-store/__tests__/resource-class.test.ts +0 -49
  320. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +0 -7
  321. package/plugins/index.js +0 -11
  322. package/plugins/steve/__tests__/steve-class.spec.ts +0 -59
  323. package/plugins/steve/__tests__/utils/steve-mocks.ts +0 -31
  324. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +0 -50
  325. package/server/har-file.js +0 -183
  326. package/tsconfig.paths.json +0 -18
  327. package/utils/azure.js +0 -24
  328. package/utils/clipboard.js +0 -5
  329. /package/components/form/__tests__/{NameNsDescription.test.ts → NameNsDescription.ts} +0 -0
  330. /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.test.ts → selectors.ts} +0 -0
  331. /package/edit/provisioning.cattle.io.cluster/{tabs/networking/ACE.vue → ACE.vue} +0 -0
  332. /package/edit/provisioning.cattle.io.cluster/{tabs/AgentConfiguration.vue → AgentConfiguration.vue} +0 -0
  333. /package/edit/provisioning.cattle.io.cluster/{tabs/upgrade/DrainOptions.vue → DrainOptions.vue} +0 -0
  334. /package/edit/provisioning.cattle.io.cluster/{tabs/MemberRoles.vue → MemberRoles.vue} +0 -0
  335. /package/edit/provisioning.cattle.io.cluster/{tabs/registries/RegistryMirrors.vue → RegistryMirrors.vue} +0 -0
  336. /package/edit/provisioning.cattle.io.cluster/{tabs/etcd/S3Config.vue → S3Config.vue} +0 -0
  337. /package/plugins/dashboard-store/__tests__/{getters.test.ts → getters.spec.ts} +0 -0
  338. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
@@ -5,50 +5,73 @@ 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`],
35
56
 
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');
57
+ // multiple namespaces (no op)
58
+ ['rType', undefined, { namespaced: [`${ namespace }`, 'nsBaz'] }, `${ collectionUrl }`],
59
+
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
  });
67
+
40
68
  describe('steve > getters > urlOptions', () => {
41
69
  // we're not testing function output based off of state or getter inputs here since they are dependencies
42
70
  const state = { config: { baseUrl: 'protocol' } };
43
71
  const getters = {
44
72
  normalizeType: (type) => type,
45
- schemaFor: (type) => {
46
- if (type === 'typeFoo') {
47
- return { links: { collection: 'urlFoo' } };
48
- }
49
- },
50
73
  // this has its own tests so it just returns the input string
51
- urlOptions: (string) => string
74
+ urlOptions: (string) => string
52
75
  };
53
76
 
54
77
  const urlOptionsGetter = urlOptions();
@@ -71,19 +94,28 @@ describe('steve: getters', () => {
71
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"', () => {
72
95
  expect(urlOptionsGetter('/v1/foo', { filter: { bar: 'baz' } })).toBe('/v1/foo?filter=bar=baz&exclude=metadata.managedFields');
73
96
  });
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');
99
+ });
74
100
  it('returns a string with a multiple filter statements applied if a single filter statement is applied', () => {
75
101
  expect(urlOptionsGetter('foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('foo?bar=baz&far=faz');
76
102
  });
77
103
  it('returns a string with a multiple filter statements applied and formatted for steve if a single filter statement is applied and the url starts with "/v1"', () => {
78
104
  expect(urlOptionsGetter('/v1/foo', { filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?filter=bar=baz&far=faz&exclude=metadata.managedFields');
79
105
  });
106
+ it('returns a string with a labelSelector and formatted for steve if the url starts with "/v1"', () => {
107
+ expect(urlOptionsGetter('/v1/foo', { labelSelector: 'a=b' })).toBe('/v1/foo?labelSelector=a=b&exclude=metadata.managedFields');
108
+ });
109
+ it('returns a string with a labelSelector and filter, and formatted for steve if the url starts with "/v1"', () => {
110
+ expect(urlOptionsGetter('/v1/foo', { labelSelector: 'a=b', filter: { bar: 'baz', far: 'faz' } })).toBe('/v1/foo?labelSelector=a=b&filter=bar=baz&far=faz&exclude=metadata.managedFields');
111
+ });
80
112
  it('returns a string with an exclude statement for "bar" and "metadata.managedFields" if excludeFields is a single element array with the string "bar" and the url starts with "/v1/"', () => {
81
113
  expect(urlOptionsGetter('/v1/foo', { excludeFields: ['bar'] })).toBe('/v1/foo?exclude=bar&exclude=metadata.managedFields');
82
114
  });
83
115
  it('returns a string without an exclude statement if excludeFields is but the url does not start with "/v1/"', () => {
84
116
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
85
117
  });
86
- 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"', () => {
87
119
  expect(urlOptionsGetter('foo', { excludeFields: ['bar'] })).toBe('foo');
88
120
  });
89
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
+ });
@@ -24,14 +24,17 @@ const GC_IGNORE_TYPES = {
24
24
  [UI.NAV_LINK]: true,
25
25
  };
26
26
 
27
- // Include calls to /v1 AND /k8s/clusters/<cluster id>/v1
28
- const steveRegEx = new RegExp('(/v1)|(\/k8s\/clusters\/[a-z0-9-]+\/v1)');
29
-
30
27
  export default {
31
28
  urlOptions: () => (url, opt) => {
32
29
  opt = opt || {};
33
30
  const parsedUrl = parse(url);
34
- const isSteve = steveRegEx.test(parsedUrl.path);
31
+ const isSteve = parsedUrl.path.startsWith('/v1');
32
+
33
+ // labelSelector
34
+ if ( opt.labelSelector ) {
35
+ url += `${ url.includes('?') ? '&' : '?' }labelSelector=${ opt.labelSelector }`;
36
+ }
37
+ // End: labelSelector
35
38
 
36
39
  // Filter
37
40
  if ( opt.filter ) {
@@ -120,10 +123,30 @@ export default {
120
123
  // `namespaced` is either
121
124
  // - a string representing a single namespace - add restriction to the url
122
125
  // - an array of namespaces or projects - add restriction as a param
123
- if (opt?.namespaced && !pAndNFiltering.isApplicable(opt)) {
124
- const parts = url.split('/');
126
+ if (!opt?.url && opt?.namespaced && !pAndNFiltering.isApplicable(opt)) {
127
+ // Update path to include `namespace`, but take into account
128
+ // - if there is an id
129
+ // - if there are query params
130
+
131
+ // Construct a url so query params / fragments are avoided
132
+ const urlObj = new URL(url);
133
+ const path = urlObj.pathname;
134
+
135
+ if (!!path?.length && path[path.length - 1] === '/') {
136
+ urlObj.pathname = path.substring(0, path.length - 1);
137
+ }
138
+ const parts = urlObj.pathname.split('/');
139
+
140
+ if (id) {
141
+ // namespace should go before the id in the path
142
+ parts.splice(parts.length - 1, 0, opt.namespaced);
143
+ urlObj.pathname = parts.join('/');
144
+ } else {
145
+ // namespace should go at the end of the path
146
+ urlObj.pathname = `${ urlObj.pathname.split('/').join('/') }/${ opt.namespaced }`;
147
+ }
125
148
 
126
- url = `${ parts.join('/') }/${ opt.namespaced }`;
149
+ url = urlObj.toString();
127
150
  }
128
151
 
129
152
  return url;
@@ -9,7 +9,6 @@ import {
9
9
  batchChanges,
10
10
  replace
11
11
  } from '@shell/plugins/dashboard-store/mutations';
12
- import { keyForSubscribe } from '@shell/plugins/steve/resourceWatcher';
13
12
  import { perfLoadAll } from '@shell/plugins/steve/performanceTesting';
14
13
  import Vue from 'vue';
15
14
  import { classify } from '@shell/plugins/dashboard-store/classify';
@@ -151,7 +150,11 @@ export default {
151
150
 
152
151
  forgetType(state, type) {
153
152
  if ( forgetType(state, type) ) {
154
- delete state.inError[keyForSubscribe({ type })];
153
+ Object.keys(state.inError).forEach((key) => {
154
+ if (key.startsWith(type)) {
155
+ delete state.inError[key];
156
+ }
157
+ });
155
158
  }
156
159
  },
157
160
 
@@ -3,7 +3,6 @@ import pickBy from 'lodash/pickBy';
3
3
  import Vue from 'vue';
4
4
  import { matchesSomeRegex } from '@shell/utils/string';
5
5
  import Resource from '@shell/plugins/dashboard-store/resource-class';
6
- import { findBy } from '@shell/utils/array';
7
6
 
8
7
  export default class NormanModel extends Resource {
9
8
  setLabels(val) {
@@ -57,22 +56,4 @@ export default class NormanModel extends Resource {
57
56
  Vue.set(this, key, { ...spec[key] });
58
57
  });
59
58
  }
60
-
61
- isCondition(condition, withStatus = 'True') {
62
- if ( !this.conditions ) {
63
- return false;
64
- }
65
-
66
- const entry = findBy((this.conditions || []), 'type', condition);
67
-
68
- if ( !entry ) {
69
- return false;
70
- }
71
-
72
- if ( !withStatus ) {
73
- return true;
74
- }
75
-
76
- return (entry.status || '').toLowerCase() === `${ withStatus }`.toLowerCase();
77
- }
78
59
  }
@@ -1,17 +1,5 @@
1
1
  import { DESCRIPTION } from '@shell/config/labels-annotations';
2
2
  import HybridModel from './hybrid-class';
3
- import { NEVER_ADD } from '@shell/utils/create-yaml';
4
- import { deleteProperty } from '@shell/utils/object';
5
-
6
- // Some fields that are removed for YAML (NEVER_ADD) are required via API
7
- const STEVE_ADD = [
8
- 'metadata.resourceVersion',
9
- 'metadata.fields',
10
- 'metadata.clusterName',
11
- 'metadata.deletionGracePeriodSeconds',
12
- 'metadata.generateName',
13
- ];
14
- const STEVE_NEVER_SAVE = NEVER_ADD.filter((na) => !STEVE_ADD.includes(na));
15
3
 
16
4
  export default class SteveModel extends HybridModel {
17
5
  get name() {
@@ -40,14 +28,4 @@ export default class SteveModel extends HybridModel {
40
28
 
41
29
  this._description = value;
42
30
  }
43
-
44
- cleanForSave(data, forNew) {
45
- const val = super.cleanForSave(data);
46
-
47
- for (const field of STEVE_NEVER_SAVE) {
48
- deleteProperty(val, field);
49
- }
50
-
51
- return val;
52
- }
53
31
  }
@@ -22,7 +22,8 @@ import Socket, {
22
22
  EVENT_DISCONNECT_ERROR,
23
23
  NO_WATCH,
24
24
  NO_SCHEMA,
25
- REVISION_TOO_OLD
25
+ REVISION_TOO_OLD,
26
+ NO_PERMS
26
27
  } from '@shell/utils/socket';
27
28
  import { normalizeType } from '@shell/plugins/dashboard-store/normalize';
28
29
  import day from 'dayjs';
@@ -332,6 +333,10 @@ const sharedActions = {
332
333
 
333
334
  commit('setWantSocket', true);
334
335
 
336
+ if ( process.server ) {
337
+ return;
338
+ }
339
+
335
340
  state.debugSocket && console.info(`Subscribe [${ getters.storeName }]`); // eslint-disable-line no-console
336
341
 
337
342
  const url = `${ state.config.baseUrl }/subscribe`;
@@ -430,6 +435,14 @@ const sharedActions = {
430
435
  return;
431
436
  }
432
437
 
438
+ const schema = getters.schemaFor(type, false, false);
439
+
440
+ if (!!schema?.attributes?.verbs?.includes && !schema.attributes.verbs.includes('watch')) {
441
+ state.debugSocket && console.info('Will not Watch (type does not have watch verb)', JSON.stringify(params)); // eslint-disable-line no-console
442
+
443
+ return;
444
+ }
445
+
433
446
  // If socket is in error don't try to watch.... unless we `force` it
434
447
  const inError = getters.inError(params);
435
448
 
@@ -597,7 +610,7 @@ const defaultActions = {
597
610
  },
598
611
 
599
612
  rehydrateSubscribe({ state, dispatch }) {
600
- if ( state.wantSocket && !state.socket ) {
613
+ if ( process.client && state.wantSocket && !state.socket ) {
601
614
  dispatch('subscribe');
602
615
  }
603
616
  },
@@ -635,13 +648,17 @@ const defaultActions = {
635
648
  await dispatch('find', {
636
649
  type: resourceType,
637
650
  id,
638
- opt,
651
+ opt: {
652
+ ...opt,
653
+ // Pass the namespace so `find` can construct the url correctly
654
+ namespaced: namespace,
655
+ // Ensure that find calls watch with no revision (otherwise it'll use the revision from the resource which is probably stale)
656
+ revision: null
657
+ },
639
658
  });
640
- commit('clearInError', params);
641
659
 
642
660
  return;
643
661
  }
644
-
645
662
  let have, want;
646
663
 
647
664
  if ( selector ) {
@@ -724,9 +741,11 @@ const defaultActions = {
724
741
  }
725
742
 
726
743
  // Try resending any frames that were attempted to be sent while the socket was down, once.
727
- for ( const obj of state.pendingFrames.slice() ) {
728
- commit('dequeuePendingFrame', obj);
729
- dispatch('sendImmediate', obj);
744
+ if ( !process.server ) {
745
+ for ( const obj of state.pendingFrames.slice() ) {
746
+ commit('dequeuePendingFrame', obj);
747
+ dispatch('sendImmediate', obj);
748
+ }
730
749
  }
731
750
  },
732
751
 
@@ -844,15 +863,17 @@ const defaultActions = {
844
863
  const err = msg.data?.error?.toLowerCase();
845
864
 
846
865
  if ( err.includes('watch not allowed') ) {
847
- commit('setInError', { type: msg.resourceType, reason: NO_WATCH });
866
+ commit('setInError', { msg, reason: NO_WATCH });
848
867
  } else if ( err.includes('failed to find schema') ) {
849
- commit('setInError', { type: msg.resourceType, reason: NO_SCHEMA });
868
+ commit('setInError', { msg, reason: NO_SCHEMA });
850
869
  } else if ( err.includes('too old') ) {
851
870
  // Set an error for (all) subs of this type. This..
852
871
  // 1) blocks attempts by resource.stop to resub (as type is in error)
853
872
  // 2) will be cleared when resyncWatch --> watch (with force) --> resource.start completes
854
- commit('setInError', { type: msg.resourceType, reason: REVISION_TOO_OLD });
873
+ commit('setInError', { msg, reason: REVISION_TOO_OLD });
855
874
  dispatch('resyncWatch', msg);
875
+ } else if ( err.includes('the server does not allow this method on the requested resource')) {
876
+ commit('setInError', { msg, reason: NO_PERMS });
856
877
  }
857
878
  },
858
879
 
@@ -1023,10 +1044,10 @@ const defaultMutations = {
1023
1044
  }
1024
1045
  },
1025
1046
 
1026
- setInError(state, msg) {
1047
+ setInError(state, { msg, reason }) {
1027
1048
  const key = keyForSubscribe(msg);
1028
1049
 
1029
- state.inError[key] = msg.reason;
1050
+ state.inError[key] = reason;
1030
1051
  },
1031
1052
 
1032
1053
  clearInError(state, msg) {
@@ -0,0 +1,4 @@
1
+ import Vue from 'vue';
2
+ import Transitions from 'vue2-transitions';
3
+
4
+ Vue.use(Transitions);
@@ -0,0 +1,4 @@
1
+ import Vue from 'vue';
2
+ import VueClipboard from 'vue-clipboard2';
3
+
4
+ Vue.use(VueClipboard);
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
- import Vue from 'vue';
2
+ import { defineComponent } from 'vue';
3
3
  import { mapGetters } from 'vuex';
4
- export default Vue.extend({
4
+
5
+ export default defineComponent({
5
6
  props: {
6
7
  title: {
7
8
  type: String,
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import Vue, { PropType } from 'vue';
2
+ import { PropType, defineComponent } from 'vue';
3
3
 
4
4
  interface Badge {
5
5
  stateBackground: string;
@@ -11,7 +11,7 @@ interface Badge {
11
11
  * <p>Represents a badge whose label and color is either taken from the value property or
12
12
  * from the label and color properties. The state property takes precedence.</p>
13
13
  */
14
- export default Vue.extend({
14
+ export default defineComponent({
15
15
  props: {
16
16
  /**
17
17
  * A value having the properties `stateBackground` and `stateDisplay`
@@ -59,7 +59,7 @@ export default Vue.extend({
59
59
  </script>
60
60
 
61
61
  <template>
62
- <span :class="{'badge-state': true, [bg]: true}">
62
+ <span :class="['badge-state', bg]">
63
63
  <i
64
64
  v-if="icon"
65
65
  class="icon"
@@ -1,16 +1,12 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import { Banner } from './index';
3
- import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
4
3
 
5
4
  describe('component: Banner', () => {
6
5
  it('should display text based on label', () => {
7
6
  const label = 'test';
8
7
  const wrapper = mount(
9
8
  Banner,
10
- {
11
- directives: { cleanHtmlDirective },
12
- propsData: { label }
13
- });
9
+ { propsData: { label } });
14
10
 
15
11
  const element = wrapper.find('span').element;
16
12
 
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
- import Vue from 'vue';
2
+ import { defineComponent } from 'vue';
3
3
  import { nlToBr } from '@shell/utils/string';
4
4
  import { stringify } from '@shell/utils/error';
5
5
 
6
- export default Vue.extend({
6
+ export default defineComponent({
7
7
  props: {
8
8
  /**
9
9
  * A color class that represents the color of the banner.
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
- import Vue from 'vue';
2
+ import { defineComponent, PropType } from 'vue';
3
3
 
4
- export default Vue.extend({
4
+ export default defineComponent({
5
5
  name: 'Card',
6
6
  props: {
7
7
  /**
@@ -22,7 +22,7 @@ export default Vue.extend({
22
22
  * The function to invoke when the default action button is clicked.
23
23
  */
24
24
  buttonAction: {
25
- type: Function,
25
+ type: Function as PropType<(event: MouseEvent) => void>,
26
26
  default: (): void => { }
27
27
  },
28
28
  /**
@@ -151,7 +151,7 @@ export default Vue.extend({
151
151
 
152
152
  .card-body {
153
153
  justify-content: flex-start;
154
- overflow: scroll;
154
+ overflow: auto;
155
155
  }
156
156
 
157
157
  > * {
@@ -1,10 +1,10 @@
1
1
  <script lang="ts">
2
- import Vue, { PropType } from 'vue';
2
+ import { PropType, defineComponent } from 'vue';
3
3
  import { _EDIT, _VIEW } from '@shell/config/query-params';
4
4
  import { addObject, removeObject } from '@shell/utils/array';
5
5
  import cloneDeep from 'lodash/cloneDeep';
6
6
 
7
- export default Vue.extend({
7
+ export default defineComponent({
8
8
  name: 'Checkbox',
9
9
 
10
10
  props: {
@@ -140,7 +140,7 @@ export default Vue.extend({
140
140
  /**
141
141
  * Toggles the checked state for the checkbox and emits an 'input' event.
142
142
  */
143
- clicked(event: MouseEvent): boolean | void {
143
+ clicked(event: MouseEvent | KeyboardEvent): boolean | void {
144
144
  if ((event.target as HTMLLinkElement).tagName === 'A' && (event.target as HTMLLinkElement).href) {
145
145
  // Ignore links inside the checkbox label so you can click them
146
146
  return true;
@@ -325,6 +325,7 @@ $fontColor: var(--input-label);
325
325
  border-radius: var(--border-radius);
326
326
  transition: all 0.3s ease-out;
327
327
  border: 1px solid var(--border);
328
+ flex-shrink: 0;
328
329
  }
329
330
 
330
331
  input {
@@ -5,7 +5,7 @@ describe('component: LabeledInput', () => {
5
5
  it('should emit input only once', () => {
6
6
  const value = '2';
7
7
  const delay = 1;
8
- const wrapper = mount(LabeledInput as any, {
8
+ const wrapper = mount(LabeledInput, {
9
9
  propsData: { delay },
10
10
  mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
11
11
  });