@rancher/shell 0.4.0 → 0.5.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 (274) hide show
  1. package/assets/images/providers/ovhcloudmks.svg +122 -0
  2. package/assets/images/providers/ovhcloudpubliccloud.svg +122 -0
  3. package/assets/styles/global/_layout.scss +99 -0
  4. package/assets/translations/en-us.yaml +30 -5
  5. package/assets/translations/zh-hans.yaml +1 -1
  6. package/babel.config.js +7 -1
  7. package/chart/monitoring/alerting/index.vue +7 -21
  8. package/chart/monitoring/grafana/index.vue +55 -0
  9. package/chart/monitoring/index.vue +51 -17
  10. package/chart/monitoring/prometheus/index.vue +37 -43
  11. package/chart/rancher-backup/index.vue +2 -1
  12. package/cloud-credential/azure.vue +4 -17
  13. package/components/AsyncButton.vue +17 -5
  14. package/components/Certificates.vue +164 -0
  15. package/components/CodeMirror.vue +19 -21
  16. package/components/CruResource.vue +1 -0
  17. package/components/DraggableZone.vue +2 -2
  18. package/components/EtcdInfoBanner.vue +1 -1
  19. package/components/ExplorerProjectsNamespaces.vue +25 -1
  20. package/components/IconOrSvg.vue +1 -1
  21. package/components/LandingPagePreference.vue +1 -4
  22. package/components/PodSecurityAdmission.vue +2 -2
  23. package/components/Questions/index.vue +1 -1
  24. package/components/ResourceDetail/Masthead.vue +16 -3
  25. package/components/ResourceTable.vue +14 -2
  26. package/components/ResourceYaml.vue +5 -0
  27. package/components/SideNav.vue +1 -1
  28. package/components/SingleClusterInfo.vue +1 -4
  29. package/components/Tabbed/index.vue +12 -0
  30. package/components/fleet/FleetRepos.vue +62 -27
  31. package/components/fleet/FleetResources.vue +6 -1
  32. package/components/form/ArrayListSelect.vue +10 -0
  33. package/components/form/Error.vue +3 -3
  34. package/components/form/Footer.vue +2 -2
  35. package/components/form/GitPicker.vue +83 -38
  36. package/components/form/KeyValue.vue +4 -0
  37. package/components/form/LabeledSelect.vue +4 -0
  38. package/components/formatter/Checked.vue +11 -3
  39. package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
  40. package/components/formatter/FleetSummaryGraph.vue +23 -11
  41. package/components/formatter/LiveDuration.vue +1 -1
  42. package/components/formatter/PercentageBar.vue +1 -1
  43. package/components/formatter/__tests__/Checked.test.ts +19 -0
  44. package/components/nav/Group.vue +2 -2
  45. package/components/nav/Header.vue +0 -1
  46. package/components/nav/TopLevelMenu.vue +36 -6
  47. package/components/nav/Type.vue +1 -3
  48. package/components/nav/WindowManager/ContainerLogs.vue +101 -3
  49. package/components/nav/WindowManager/ContainerShell.vue +6 -1
  50. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
  51. package/components/nav/WindowManager/index.vue +11 -10
  52. package/components/nav/__tests__/TopLevelMenu.test.ts +33 -0
  53. package/components/nav/__tests__/Type.test.ts +1 -1
  54. package/components/nuxt/nuxt-child.js +14 -78
  55. package/components/nuxt/nuxt.js +1 -1
  56. package/{layouts → components/templates}/blank.vue +1 -1
  57. package/{layouts → components/templates}/default.vue +8 -98
  58. package/{layouts → components/templates}/error.vue +10 -19
  59. package/{layouts → components/templates}/home.vue +4 -1
  60. package/{layouts → components/templates}/plain.vue +4 -1
  61. package/{layouts → components/templates}/standalone.vue +1 -1
  62. package/{layouts → components/templates}/unauthenticated.vue +1 -1
  63. package/composables/useCompactInput.test.ts +36 -0
  64. package/composables/useCompactInput.ts +20 -0
  65. package/composables/useLabeledFormElement.test.ts +135 -0
  66. package/composables/useLabeledFormElement.ts +138 -0
  67. package/config/harvester-manager-types.js +2 -0
  68. package/config/private-label.js +22 -0
  69. package/config/product/explorer.js +3 -0
  70. package/config/product/fleet.js +6 -1
  71. package/config/product/manager.js +8 -2
  72. package/config/query-params.js +1 -0
  73. package/config/router.js +385 -364
  74. package/config/settings.ts +1 -0
  75. package/config/store.js +1 -1
  76. package/config/system-namespaces.js +3 -0
  77. package/config/table-headers.js +47 -0
  78. package/core/plugin-routes.ts +56 -114
  79. package/core/plugin.ts +16 -10
  80. package/core/plugins-loader.js +7 -9
  81. package/core/plugins.js +0 -3
  82. package/creators/app/files/.gitlab-ci.yml +1 -1
  83. package/detail/fleet.cattle.io.cluster.vue +11 -1
  84. package/detail/provisioning.cattle.io.cluster.vue +4 -3
  85. package/dialog/ScaleMachineDownDialog.vue +34 -17
  86. package/edit/__tests__/service.test.ts +89 -0
  87. package/edit/auth/googleoauth.vue +1 -5
  88. package/edit/cloudcredential.vue +2 -0
  89. package/edit/configmap.vue +2 -1
  90. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +2 -2
  91. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
  92. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +15 -7
  93. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +112 -0
  94. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
  95. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +4 -0
  96. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  97. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
  98. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +7 -1
  99. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
  100. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  101. package/edit/provisioning.cattle.io.cluster/index.vue +92 -36
  102. package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -583
  103. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
  104. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +157 -0
  105. package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +94 -19
  106. package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
  107. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
  108. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +189 -0
  109. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +144 -0
  110. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
  111. package/edit/service.vue +12 -0
  112. package/edit/workload/mixins/workload.js +1 -1
  113. package/initialize/App.js +25 -71
  114. package/initialize/client.js +21 -162
  115. package/initialize/index.js +27 -123
  116. package/list/management.cattle.io.feature.vue +1 -7
  117. package/list/node.vue +1 -0
  118. package/machine-config/__tests__/vmwarevsphere.test.ts +100 -21
  119. package/machine-config/vmwarevsphere.vue +73 -51
  120. package/middleware/authenticated.js +10 -17
  121. package/mixins/auth-config.js +2 -7
  122. package/mixins/brand.js +29 -41
  123. package/mixins/create-edit-view/index.js +2 -2
  124. package/mixins/labeled-form-element.ts +6 -1
  125. package/models/__tests__/management.cattle.io.node.ts +85 -0
  126. package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
  127. package/models/__tests__/namespace.test.ts +49 -9
  128. package/models/__tests__/workload.test.ts +91 -0
  129. package/models/cluster/node.js +4 -4
  130. package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
  131. package/models/fleet.cattle.io.cluster.js +4 -0
  132. package/models/fleet.cattle.io.gitrepo.js +56 -13
  133. package/models/management.cattle.io.kontainerdriver.js +1 -1
  134. package/models/management.cattle.io.node.js +18 -14
  135. package/models/management.cattle.io.nodepool.js +17 -0
  136. package/models/namespace.js +1 -1
  137. package/models/pod.js +20 -0
  138. package/models/provisioning.cattle.io.cluster.js +20 -3
  139. package/models/secret.js +117 -18
  140. package/models/workload.js +16 -0
  141. package/models/workload.service.js +18 -0
  142. package/package.json +10 -9
  143. package/pages/about.vue +0 -1
  144. package/pages/account/create-key.vue +0 -1
  145. package/pages/account/index.vue +0 -1
  146. package/pages/auth/login.vue +0 -1
  147. package/pages/auth/logout.vue +0 -2
  148. package/pages/auth/setup.vue +0 -4
  149. package/pages/auth/verify.vue +14 -8
  150. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  151. package/pages/c/_cluster/apps/index.vue +0 -2
  152. package/pages/c/_cluster/auth/index.vue +0 -2
  153. package/pages/c/_cluster/ecm/index.vue +0 -2
  154. package/pages/c/_cluster/explorer/index.vue +28 -2
  155. package/pages/c/_cluster/fleet/index.vue +1 -1
  156. package/pages/c/_cluster/index.vue +0 -2
  157. package/pages/c/_cluster/settings/banners.vue +0 -2
  158. package/pages/c/_cluster/settings/brand.vue +0 -2
  159. package/pages/c/_cluster/settings/index.vue +0 -2
  160. package/pages/c/_cluster/settings/links.vue +0 -1
  161. package/pages/c/_cluster/settings/performance.vue +0 -1
  162. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -1
  163. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
  164. package/pages/c/_cluster/uiplugins/index.vue +0 -2
  165. package/pages/diagnostic.vue +1 -2
  166. package/pages/fail-whale.vue +0 -1
  167. package/pages/prefs.vue +0 -1
  168. package/pages/support/index.vue +2 -8
  169. package/pkg/auto-import.js +1 -1
  170. package/plugins/axios.js +0 -36
  171. package/plugins/back-button.js +3 -5
  172. package/plugins/codemirror-loader.js +1 -1
  173. package/plugins/codemirror.js +41 -0
  174. package/plugins/dashboard-store/__tests__/{mutations.spec.ts → mutations.test.ts} +1 -1
  175. package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
  176. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
  177. package/plugins/dashboard-store/actions.js +30 -4
  178. package/plugins/dashboard-store/classify.js +1 -18
  179. package/plugins/dashboard-store/getters.js +10 -5
  180. package/plugins/dashboard-store/index.js +0 -12
  181. package/plugins/dashboard-store/mutations.js +0 -4
  182. package/plugins/dashboard-store/resource-class.js +59 -18
  183. package/plugins/steve/__tests__/steve-class.spec.ts +59 -0
  184. package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
  185. package/plugins/steve/getters.js +4 -1
  186. package/plugins/steve/norman-class.js +19 -0
  187. package/plugins/steve/steve-class.js +22 -0
  188. package/plugins/steve/subscribe.js +4 -10
  189. package/rancher-components/Accordion/Accordion.test.ts +45 -0
  190. package/rancher-components/Accordion/Accordion.vue +86 -0
  191. package/rancher-components/Accordion/index.ts +1 -0
  192. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  193. package/rancher-components/Banner/Banner.vue +2 -2
  194. package/rancher-components/Card/Card.vue +3 -3
  195. package/rancher-components/Form/Checkbox/Checkbox.vue +3 -3
  196. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
  197. package/rancher-components/Form/LabeledInput/LabeledInput.vue +65 -24
  198. package/rancher-components/Form/Radio/RadioButton.test.ts +7 -3
  199. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  200. package/rancher-components/Form/Radio/RadioGroup.test.ts +30 -0
  201. package/rancher-components/Form/Radio/RadioGroup.vue +8 -3
  202. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
  203. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  204. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  205. package/rancher-components/StringList/StringList.test.ts +270 -0
  206. package/rancher-components/StringList/StringList.vue +65 -26
  207. package/rancher-components/components/Accordion/Accordion.test.ts +45 -0
  208. package/rancher-components/components/Accordion/Accordion.vue +86 -0
  209. package/rancher-components/components/Accordion/index.ts +1 -0
  210. package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
  211. package/rancher-components/components/Banner/Banner.vue +2 -2
  212. package/rancher-components/components/Card/Card.vue +3 -3
  213. package/rancher-components/components/Form/Checkbox/Checkbox.vue +3 -3
  214. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +18 -1
  215. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +57 -24
  216. package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
  217. package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
  218. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
  219. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  220. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
  221. package/rancher-components/components/StringList/StringList.vue +8 -8
  222. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +50 -0
  223. package/scripts/extension/parse-tag-name +2 -2
  224. package/scripts/publish-shell.sh +10 -0
  225. package/scripts/test-plugins-build.sh +85 -9
  226. package/server/har-file.js +183 -0
  227. package/store/catalog.js +1 -1
  228. package/store/features.js +1 -0
  229. package/store/i18n.js +11 -0
  230. package/store/index.js +10 -11
  231. package/store/prefs.js +33 -35
  232. package/store/type-map.js +8 -7
  233. package/tsconfig.json +35 -9
  234. package/tsconfig.paths.json +21 -0
  235. package/types/shell/index.d.ts +427 -234
  236. package/types/vue-shim.d.ts +42 -0
  237. package/utils/__tests__/create-yaml.test.ts +60 -0
  238. package/utils/axios.js +0 -19
  239. package/utils/azure.js +24 -0
  240. package/utils/create-yaml.js +17 -10
  241. package/utils/git.ts +1 -1
  242. package/utils/monitoring.js +1 -1
  243. package/utils/nuxt.js +18 -39
  244. package/utils/object.js +14 -0
  245. package/utils/router.scrollBehavior.js +12 -14
  246. package/utils/time.js +1 -1
  247. package/utils/url.ts +1 -1
  248. package/vue.config.js +23 -2
  249. package/.DS_Store +0 -0
  250. package/assets/images/providers/aks-black.svg +0 -28
  251. package/assets/images/providers/aks.svg +0 -31
  252. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -234
  253. package/initialize/layouts.ts +0 -26
  254. package/mixins/fetch.server.js +0 -73
  255. package/pages/c/index.vue +0 -9
  256. package/pages/rio/mesh.vue +0 -508
  257. package/plugins/transitions.js +0 -4
  258. package/scripts/.DS_Store +0 -0
  259. package/scripts/verdaccio.log +0 -205
  260. package/tsconfig.default.json +0 -46
  261. package/yarn-error.log +0 -200
  262. /package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +0 -0
  263. /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +0 -0
  264. /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
  265. /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
  266. /package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +0 -0
  267. /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
  268. /package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +0 -0
  269. /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
  270. /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
  271. /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
  272. /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
  273. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  274. /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
@@ -0,0 +1,36 @@
1
+ import { ref } from 'vue';
2
+ import { useCompactInput } from './useCompactInput';
3
+
4
+ describe('useCompactInput', () => {
5
+ it('should compute isCompact correctly when compact is explicitly set', () => {
6
+ const props = ref({
7
+ compact: true,
8
+ label: 'Test Label',
9
+ labelKey: 'testLabel',
10
+ });
11
+
12
+ const { isCompact } = useCompactInput(props.value);
13
+
14
+ expect(isCompact.value).toBe(true);
15
+
16
+ // When compact is explicitly set to false, isCompact should be false
17
+ props.value.compact = false;
18
+ expect(isCompact.value).toBe(false);
19
+ });
20
+
21
+ it('should compute isCompact correctly when compact is not explicitly set', () => {
22
+ const props = ref({
23
+ label: '',
24
+ labelKey: '',
25
+ });
26
+
27
+ const { isCompact } = useCompactInput(props.value);
28
+
29
+ // When there is no label and labelKey is also not present, isCompact should be true
30
+ expect(isCompact.value).toBe(true);
31
+
32
+ // When label is present, isCompact should be false
33
+ props.value.label = 'Updated Label';
34
+ expect(isCompact.value).toBe(false);
35
+ });
36
+ });
@@ -0,0 +1,20 @@
1
+ import { computed, ComputedRef } from 'vue';
2
+
3
+ interface CompactInputProps {
4
+ compact?: boolean | null;
5
+ label?: string;
6
+ labelKey?: string;
7
+ }
8
+
9
+ interface UseCompactInput {
10
+ isCompact: ComputedRef<boolean>;
11
+ }
12
+
13
+ export const useCompactInput = (props: CompactInputProps): UseCompactInput => {
14
+ const isCompact = computed(() => {
15
+ // Compact if explicitly set - otherwise compact if there is no label
16
+ return (props.compact !== null && props.compact !== undefined) ? !!props.compact : !(props.label || props.labelKey);
17
+ });
18
+
19
+ return { isCompact };
20
+ };
@@ -0,0 +1,135 @@
1
+ import { ref } from 'vue';
2
+ import { useLabeledFormElement } from './useLabeledFormElement';
3
+
4
+ describe('useLabeledFormElement', () => {
5
+ it('should set raised to true when focused', () => {
6
+ const props = {
7
+ mode: 'edit',
8
+ value: '',
9
+ required: true,
10
+ disabled: false,
11
+ rules: [],
12
+ };
13
+
14
+ const emit = jest.fn();
15
+ const { onFocusLabeled, onBlurLabeled, raised } = useLabeledFormElement(props, emit);
16
+
17
+ onFocusLabeled();
18
+ expect(raised.value).toBe(true);
19
+
20
+ onBlurLabeled();
21
+ expect(raised.value).toBe(false);
22
+ });
23
+
24
+ it('should set focused to true when focused', () => {
25
+ const props = {
26
+ mode: 'edit',
27
+ value: '',
28
+ required: true,
29
+ disabled: false,
30
+ rules: [],
31
+ };
32
+
33
+ const emit = jest.fn();
34
+ const { onFocusLabeled, onBlurLabeled, focused } = useLabeledFormElement(props, emit);
35
+
36
+ onFocusLabeled();
37
+ expect(focused.value).toBe(true);
38
+
39
+ onBlurLabeled();
40
+ expect(focused.value).toBe(false);
41
+ });
42
+
43
+ it('should set blurred to current timestamp when blurred', () => {
44
+ const props = {
45
+ mode: 'edit',
46
+ value: '',
47
+ required: true,
48
+ disabled: false,
49
+ rules: [],
50
+ };
51
+
52
+ const emit = jest.fn();
53
+ const { onBlurLabeled, blurred } = useLabeledFormElement(props, emit);
54
+
55
+ onBlurLabeled();
56
+ expect(blurred.value).toBeTruthy();
57
+ });
58
+
59
+ it('should compute isDisabled correctly', () => {
60
+ const props = ref({
61
+ mode: 'edit',
62
+ value: '',
63
+ required: true,
64
+ disabled: false,
65
+ rules: [],
66
+ });
67
+
68
+ const emit = jest.fn();
69
+ const { isDisabled } = useLabeledFormElement(props.value, emit);
70
+
71
+ expect(isDisabled.value).toBe(false);
72
+
73
+ props.value.disabled = true;
74
+ expect(isDisabled.value).toBe(true);
75
+
76
+ props.value.mode = 'view';
77
+ expect(isDisabled.value).toBe(true);
78
+ });
79
+
80
+ it('should compute validationMessage correctly for required field', () => {
81
+ const props = ref({
82
+ mode: 'edit',
83
+ value: '',
84
+ required: true,
85
+ disabled: false,
86
+ rules: [
87
+ (value: string[]) => (value.length < 5 ? 'This field is required' : undefined),
88
+ ],
89
+ });
90
+
91
+ const emit = jest.fn();
92
+ const { validationMessage, onBlurLabeled } = useLabeledFormElement(props.value, emit);
93
+
94
+ onBlurLabeled();
95
+ expect(validationMessage.value).toBe('This field is required');
96
+ });
97
+
98
+ it('should compute validationMessage correctly for custom rules', () => {
99
+ const props = ref({
100
+ mode: 'edit',
101
+ value: 'test',
102
+ required: false,
103
+ disabled: false,
104
+ rules: [
105
+ (value: string[]) => (value.length < 5 ? 'Value must be at least 5 characters long' : undefined),
106
+ (value: string[]) => (value.includes('test') ? 'Value cannot contain the word "test"' : undefined),
107
+ ],
108
+ });
109
+
110
+ const emit = jest.fn();
111
+ const { validationMessage, onBlurLabeled } = useLabeledFormElement(props.value, emit);
112
+
113
+ onBlurLabeled();
114
+ expect(validationMessage.value).toBe('Value must be at least 5 characters long, Value cannot contain the word "test"');
115
+ });
116
+
117
+ it('should compute requiredField correctly', () => {
118
+ const props = ref({
119
+ mode: 'edit',
120
+ value: '',
121
+ required: true,
122
+ disabled: false,
123
+ rules: [],
124
+ });
125
+
126
+ const emit = jest.fn();
127
+ const { requiredField } = useLabeledFormElement(props.value, emit);
128
+
129
+ expect(requiredField.value).toBe(true);
130
+
131
+ // When the field is not required, requiredField should be false
132
+ props.value.required = false;
133
+ expect(requiredField.value).toBe(false);
134
+ });
135
+ });
@@ -0,0 +1,138 @@
1
+ import { ref, computed, ComputedRef, Ref } from 'vue';
2
+ import { _VIEW, _EDIT } from '@shell/config/query-params';
3
+
4
+ interface LabeledFormElementProps {
5
+ mode: string;
6
+ value: string | number | Record<string, any>
7
+ required: boolean;
8
+ disabled: boolean;
9
+ rules: Array<any>;
10
+ }
11
+
12
+ interface UseLabeledFormElement {
13
+ raised: Ref<boolean>;
14
+ focused: Ref<boolean>;
15
+ blurred: Ref<number | null>;
16
+ requiredField: ComputedRef<any>;
17
+ isDisabled: ComputedRef<any>;
18
+ validationMessage: ComputedRef<any>;
19
+ onFocusLabeled: () => void;
20
+ onBlurLabeled: () => void;
21
+ }
22
+
23
+ export const labeledFormElementProps = {
24
+ tooltipKey: {
25
+ type: String,
26
+ default: null
27
+ },
28
+ placeholder: {
29
+ type: [String, Number],
30
+ default: ''
31
+ },
32
+ placeholderKey: {
33
+ type: String,
34
+ default: null
35
+ },
36
+ label: {
37
+ type: String,
38
+ default: null
39
+ },
40
+ labelKey: {
41
+ type: String,
42
+ default: null
43
+ },
44
+ value: {
45
+ type: [String, Number, Object],
46
+ default: ''
47
+ },
48
+ mode: {
49
+ type: String,
50
+ default: _EDIT,
51
+ },
52
+ rules: {
53
+ default: (): Array<unknown> => [],
54
+ type: Array,
55
+ // we only want functions in the rules array
56
+ validator: (rules: Array<unknown>): boolean => rules.every((rule: unknown) => ['function'].includes(typeof rule))
57
+ },
58
+ required: {
59
+ type: Boolean,
60
+ default: false,
61
+ },
62
+ disabled: {
63
+ type: Boolean,
64
+ default: false,
65
+ },
66
+ };
67
+
68
+ export const useLabeledFormElement = (props: LabeledFormElementProps, emit: (event: string, ...args: any[]) => void): UseLabeledFormElement => {
69
+ const raised = ref(props.mode === _VIEW || !!`${ props.value }`);
70
+ const focused = ref(false);
71
+ const blurred = ref<number | null>(null);
72
+
73
+ const requiredField = computed(() => {
74
+ return props.required || props.rules?.some((rule: any) => rule?.name === 'required');
75
+ });
76
+
77
+ const isView = computed(() => {
78
+ return props.mode === _VIEW;
79
+ });
80
+
81
+ const isDisabled = computed(() => {
82
+ return props.disabled || isView.value;
83
+ });
84
+
85
+ const validationMessage = computed(() => {
86
+ const requiredRule = props.rules.find((rule: any) => rule?.name === 'required') as Function;
87
+ const ruleMessages = [];
88
+ const value = props.value;
89
+
90
+ if (requiredRule && blurred.value && !focused.value) {
91
+ const message = requiredRule(value);
92
+
93
+ if (!!message) {
94
+ return message;
95
+ }
96
+ }
97
+
98
+ for (const rule of props.rules) {
99
+ const message = rule(value);
100
+
101
+ if (!!message && rule.name !== 'required') {
102
+ ruleMessages.push(message);
103
+ }
104
+ }
105
+
106
+ if (ruleMessages.length > 0 && (blurred.value || focused.value)) {
107
+ return ruleMessages.join(', ');
108
+ } else {
109
+ return undefined;
110
+ }
111
+ });
112
+
113
+ const onFocusLabeled = () => {
114
+ raised.value = true;
115
+ focused.value = true;
116
+ };
117
+
118
+ const onBlurLabeled = () => {
119
+ focused.value = false;
120
+
121
+ if (!props.value) {
122
+ raised.value = false;
123
+ }
124
+
125
+ blurred.value = Date.now();
126
+ };
127
+
128
+ return {
129
+ raised,
130
+ focused,
131
+ blurred,
132
+ onFocusLabeled,
133
+ onBlurLabeled,
134
+ isDisabled,
135
+ validationMessage,
136
+ requiredField
137
+ };
138
+ };
@@ -1 +1,3 @@
1
1
  export const NAME = 'harvesterManager';
2
+
3
+ export const KIND = { MACHINE_TEMPLATE: 'HarvesterMachineTemplate' };
@@ -23,6 +23,7 @@ export function setMode(m) {
23
23
 
24
24
  export function setVendor(v) {
25
25
  vendor = v;
26
+ setTitle();
26
27
  }
27
28
 
28
29
  export function setProduct(p) {
@@ -71,3 +72,24 @@ export function getVendor() {
71
72
  export function getProduct() {
72
73
  return product;
73
74
  }
75
+
76
+ export function setTitle() {
77
+ const v = getVendor();
78
+
79
+ if (v === 'Harvester') {
80
+ const ico = require(`~shell/assets/images/pl/harvester.png`);
81
+
82
+ document.title = 'Harvester';
83
+ const link = document.createElement('link');
84
+
85
+ link.hid = 'icon';
86
+ link.rel = 'icon';
87
+ link.type = 'image/x-icon';
88
+ link.hrefv = ico;
89
+ const head = document.getElementsByTagName('head')[0];
90
+
91
+ head.appendChild(link);
92
+ } else {
93
+ document.title = v;
94
+ }
95
+ }
@@ -7,6 +7,7 @@ import {
7
7
  MANAGEMENT,
8
8
  NAMESPACE,
9
9
  NORMAN,
10
+ SNAPSHOT,
10
11
  VIRTUAL_TYPES,
11
12
  } from '@shell/config/types';
12
13
 
@@ -162,6 +163,8 @@ export function init(store) {
162
163
  configureType(MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate: true });
163
164
  configureType(MANAGEMENT.PROJECT, { displayName: store.getters['i18n/t']('namespace.project.label') });
164
165
  configureType(NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, { depaginate: true });
166
+ configureType(SNAPSHOT, { depaginate: true });
167
+ configureType(NORMAN.ETCD_BACKUP, { depaginate: true });
165
168
 
166
169
  configureType(EVENT, { limit: 500 });
167
170
  weightType(EVENT, -1, true);
@@ -3,6 +3,7 @@ import { FLEET } from '@shell/config/types';
3
3
  import { STATE, NAME as NAME_COL, AGE } from '@shell/config/table-headers';
4
4
  import { FLEET as FLEET_FEATURE } from '@shell/store/features';
5
5
  import { gitRepoGraphConfig } from '@shell/pages/c/_cluster/fleet/GitRepoGraphConfig';
6
+ import { BLANK_CLUSTER } from '@shell/store/store-types.js';
6
7
 
7
8
  export const NAME = 'fleet';
8
9
  export const CHART_NAME = 'fleet';
@@ -26,6 +27,10 @@ export function init(store) {
26
27
  removable: false,
27
28
  showClusterSwitcher: false,
28
29
  showWorkspaceSwitcher: true,
30
+ to: {
31
+ name: 'c-cluster-fleet',
32
+ params: { resource: FLEET.DASHBOARD, cluster: BLANK_CLUSTER }
33
+ },
29
34
  });
30
35
 
31
36
  virtualType({
@@ -37,7 +42,7 @@ export function init(store) {
37
42
  weight: 110,
38
43
  route: {
39
44
  name: 'c-cluster-fleet',
40
- params: { resource: FLEET.DASHBOARD }
45
+ params: { resource: FLEET.DASHBOARD, cluster: BLANK_CLUSTER }
41
46
  },
42
47
  exact: true,
43
48
  });
@@ -4,9 +4,10 @@ import {
4
4
  CATALOG,
5
5
  NORMAN,
6
6
  HCI,
7
- MANAGEMENT
7
+ MANAGEMENT,
8
+ SNAPSHOT
8
9
  } from '@shell/config/types';
9
- import { MULTI_CLUSTER } from '@shell/store/features';
10
+ import { MULTI_CLUSTER, RKE1_UI } from '@shell/store/features';
10
11
  import { DSL } from '@shell/store/type-map';
11
12
  import { BLANK_CLUSTER } from '@shell/store/store-types.js';
12
13
 
@@ -60,6 +61,9 @@ export function init(store) {
60
61
  'drivers',
61
62
  ]);
62
63
 
64
+ configureType(SNAPSHOT, { depaginate: true });
65
+ configureType(NORMAN.ETCD_BACKUP, { depaginate: true });
66
+
63
67
  configureType(CAPI.RANCHER_CLUSTER, {
64
68
  showListMasthead: false, namespaced: false, alias: [HCI.CLUSTER]
65
69
  });
@@ -84,6 +88,7 @@ export function init(store) {
84
88
  });
85
89
 
86
90
  virtualType({
91
+ ifFeature: RKE1_UI,
87
92
  labelKey: 'manager.rkeTemplates.label',
88
93
  name: 'rke-templates',
89
94
  group: 'Root',
@@ -94,6 +99,7 @@ export function init(store) {
94
99
  });
95
100
 
96
101
  virtualType({
102
+ ifFeature: RKE1_UI,
97
103
  labelKey: 'manager.nodeTemplates.label',
98
104
  name: 'rke-node-templates',
99
105
  group: 'Root',
@@ -50,6 +50,7 @@ export const _SPLIT = 'split';
50
50
 
51
51
  // CruResource
52
52
  export const SUB_TYPE = 'type';
53
+ export const RKE_TYPE = 'rkeType';
53
54
 
54
55
  // App launch
55
56
  export const REPO_TYPE = 'repo-type';