@rancher/shell 3.0.4 → 3.0.5-rc.2

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 (270) hide show
  1. package/assets/images/providers/sks.svg +1 -0
  2. package/assets/styles/base/_basic.scss +6 -0
  3. package/assets/styles/base/_helpers.scss +4 -0
  4. package/assets/styles/base/_variables.scss +1 -0
  5. package/assets/styles/global/_button.scss +1 -0
  6. package/assets/translations/en-us.yaml +65 -15
  7. package/assets/translations/zh-hans.yaml +4 -3
  8. package/chart/monitoring/index.vue +3 -1
  9. package/cloud-credential/aws.vue +2 -0
  10. package/components/ActionDropdownShell.vue +71 -0
  11. package/components/AppModal.vue +18 -4
  12. package/components/AsyncButton.vue +24 -7
  13. package/components/BannerGraphic.vue +1 -0
  14. package/components/CommunityLinks.vue +4 -59
  15. package/components/CopyToClipboardText.vue +2 -1
  16. package/components/CruResource.vue +6 -1
  17. package/components/DetailText.vue +5 -0
  18. package/components/ExplorerMembers.vue +1 -1
  19. package/components/ExplorerProjectsNamespaces.vue +68 -18
  20. package/components/GlobalRoleBindings.vue +5 -1
  21. package/components/GrowlManager.vue +1 -0
  22. package/components/LandingPagePreference.vue +7 -3
  23. package/components/LocaleSelector.vue +39 -95
  24. package/components/ModalManager.vue +55 -0
  25. package/components/ModalWithCard.vue +1 -0
  26. package/components/PromptModal.vue +47 -8
  27. package/components/PromptRemove.vue +1 -0
  28. package/components/PromptRestore.vue +1 -0
  29. package/components/ResourceCancelModal.vue +1 -0
  30. package/components/ResourceDetail/Masthead.vue +38 -12
  31. package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
  32. package/components/ResourceDetail/index.vue +47 -12
  33. package/components/ResourceTable.vue +54 -19
  34. package/components/SideNav.vue +5 -1
  35. package/components/SlideInPanelManager.vue +126 -0
  36. package/components/SortableTable/THead.vue +5 -2
  37. package/components/SortableTable/actions.js +1 -1
  38. package/components/SortableTable/index.vue +64 -51
  39. package/components/SortableTable/paging.js +16 -19
  40. package/components/SortableTable/selection.js +0 -11
  41. package/components/Wizard.vue +2 -2
  42. package/components/__tests__/AsyncButton.test.ts +2 -2
  43. package/components/__tests__/ModalManager.spec.ts +176 -0
  44. package/components/__tests__/PromptModal.test.ts +148 -0
  45. package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
  46. package/components/auth/AuthBanner.vue +13 -11
  47. package/components/auth/Principal.vue +1 -0
  48. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  49. package/components/auth/login/ldap.vue +1 -1
  50. package/components/fleet/FleetResources.vue +21 -6
  51. package/components/form/ArrayList.vue +76 -60
  52. package/components/form/BannerSettings.vue +17 -2
  53. package/components/form/ColorInput.vue +35 -6
  54. package/components/form/Command.vue +6 -15
  55. package/components/form/EnvVars.vue +16 -8
  56. package/components/form/HealthCheck.vue +3 -3
  57. package/components/form/HookOption.vue +11 -16
  58. package/components/form/LabeledSelect.vue +18 -22
  59. package/components/form/LifecycleHooks.vue +3 -3
  60. package/components/form/MatchExpressions.vue +14 -8
  61. package/components/form/NameNsDescription.vue +128 -104
  62. package/components/form/Networking.vue +20 -12
  63. package/components/form/NodeAffinity.vue +31 -23
  64. package/components/form/NodeScheduling.vue +13 -3
  65. package/components/form/NotificationSettings.vue +15 -1
  66. package/components/form/Password.vue +1 -0
  67. package/components/form/PodAffinity.vue +43 -43
  68. package/components/form/Probe.vue +68 -66
  69. package/components/form/ResourceQuota/Project.vue +5 -1
  70. package/components/form/ResourceSelector.vue +7 -9
  71. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +16 -24
  72. package/components/form/SSHKnownHosts/index.vue +30 -13
  73. package/components/form/Security.vue +54 -56
  74. package/components/form/Select.vue +32 -21
  75. package/components/form/ShellInput.vue +5 -1
  76. package/components/form/Tolerations.vue +5 -1
  77. package/components/form/ValueFromResource.vue +134 -121
  78. package/components/form/WorkloadPorts.vue +18 -18
  79. package/components/form/__tests__/ArrayList.test.ts +5 -2
  80. package/components/form/__tests__/ColorInput.test.ts +35 -0
  81. package/components/form/__tests__/LabeledSelect.test.ts +40 -0
  82. package/components/form/__tests__/MatchExpressions.test.ts +12 -12
  83. package/components/form/__tests__/NameNsDescription.test.ts +115 -14
  84. package/components/form/__tests__/Probe.test.ts +12 -8
  85. package/components/form/__tests__/SSHKnownHosts.test.ts +22 -2
  86. package/components/form/__tests__/Select.test.ts +37 -0
  87. package/components/formatter/InternalExternalIP.vue +2 -0
  88. package/components/formatter/SecretData.vue +20 -7
  89. package/components/nav/Group.vue +27 -5
  90. package/components/nav/Header.vue +17 -43
  91. package/components/nav/NamespaceFilter.vue +134 -86
  92. package/components/nav/TopLevelMenu.vue +4 -5
  93. package/components/nav/Type.vue +12 -1
  94. package/components/nav/WindowManager/ContainerLogs.vue +87 -61
  95. package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
  96. package/components/templates/blank.vue +4 -1
  97. package/components/templates/default.vue +8 -3
  98. package/components/templates/home.vue +10 -1
  99. package/components/templates/plain.vue +10 -4
  100. package/composables/focusTrap.ts +12 -4
  101. package/composables/useRuntimeFlag.ts +29 -0
  102. package/config/router/routes.js +20 -13
  103. package/config/store.js +4 -0
  104. package/config/uiplugins.js +5 -1
  105. package/core/types.ts +12 -6
  106. package/detail/catalog.cattle.io.app.vue +6 -1
  107. package/detail/fleet.cattle.io.bundle.vue +70 -6
  108. package/detail/fleet.cattle.io.gitrepo.vue +1 -1
  109. package/detail/namespace.vue +0 -3
  110. package/detail/node.vue +17 -13
  111. package/detail/provisioning.cattle.io.cluster.vue +72 -6
  112. package/dialog/AddCustomBadgeDialog.vue +1 -1
  113. package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
  114. package/{components/AssignTo.vue → dialog/AssignToDialog.vue} +71 -80
  115. package/dialog/ChangePasswordDialog.vue +106 -0
  116. package/dialog/DeactivateDriverDialog.vue +1 -0
  117. package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
  118. package/dialog/DisableAuthProviderDialog.vue +101 -0
  119. package/dialog/DrainNode.vue +1 -1
  120. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
  121. package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +69 -57
  122. package/dialog/FeatureFlagListDialog.vue +288 -0
  123. package/dialog/ForceMachineRemoveDialog.vue +5 -2
  124. package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
  125. package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
  126. package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -59
  127. package/dialog/MoveNamespaceDialog.vue +157 -0
  128. package/dialog/ScalePoolDownDialog.vue +1 -1
  129. package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
  130. package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
  131. package/dialog/WechatDialog.vue +57 -0
  132. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
  133. package/edit/auth/__tests__/oidc.test.ts +152 -109
  134. package/edit/auth/azuread.vue +2 -1
  135. package/edit/auth/github.vue +1 -1
  136. package/edit/auth/googleoauth.vue +5 -1
  137. package/edit/auth/ldap/index.vue +1 -1
  138. package/edit/auth/oidc.vue +38 -5
  139. package/edit/auth/saml.vue +1 -1
  140. package/edit/cloudcredential.vue +24 -9
  141. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
  142. package/edit/management.cattle.io.user.vue +28 -3
  143. package/edit/namespace.vue +1 -4
  144. package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
  145. package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
  146. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
  147. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
  148. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
  149. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
  150. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
  151. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
  152. package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
  153. package/edit/provisioning.cattle.io.cluster/rke2.vue +49 -41
  154. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
  155. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
  156. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
  157. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
  158. package/edit/token.vue +2 -0
  159. package/edit/workload/index.vue +1 -0
  160. package/edit/workload/mixins/workload.js +0 -2
  161. package/initialize/install-plugins.js +2 -1
  162. package/list/harvesterhci.io.management.cluster.vue +4 -1
  163. package/list/management.cattle.io.feature.vue +4 -287
  164. package/list/provisioning.cattle.io.cluster.vue +20 -12
  165. package/machine-config/azure.vue +16 -4
  166. package/mixins/vue-select-overrides.js +0 -4
  167. package/models/__tests__/namespace.test.ts +25 -1
  168. package/models/cloudcredential.js +5 -0
  169. package/models/fleet.cattle.io.cluster.js +8 -2
  170. package/models/fleet.cattle.io.gitrepo.js +8 -34
  171. package/models/kontainerdriver.js +6 -3
  172. package/models/management.cattle.io.feature.js +7 -1
  173. package/models/management.cattle.io.node.js +3 -3
  174. package/models/namespace.js +11 -6
  175. package/models/nodedriver.js +6 -3
  176. package/models/workload.js +4 -1
  177. package/package.json +3 -3
  178. package/pages/about.vue +13 -3
  179. package/pages/account/index.vue +16 -6
  180. package/pages/auth/login.vue +18 -7
  181. package/pages/auth/logout.vue +4 -1
  182. package/pages/auth/setup.vue +2 -0
  183. package/pages/auth/verify.vue +13 -8
  184. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  185. package/pages/c/_cluster/apps/charts/install.vue +26 -26
  186. package/pages/c/_cluster/auth/config/index.vue +10 -12
  187. package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
  188. package/pages/c/_cluster/explorer/index.vue +17 -15
  189. package/pages/c/_cluster/istio/index.vue +2 -2
  190. package/pages/c/_cluster/longhorn/index.vue +1 -1
  191. package/pages/c/_cluster/monitoring/index.vue +1 -1
  192. package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
  193. package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
  194. package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
  195. package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
  196. package/pages/c/_cluster/neuvector/index.vue +1 -1
  197. package/pages/c/_cluster/settings/banners.vue +4 -3
  198. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
  199. package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
  200. package/pages/c/_cluster/uiplugins/index.vue +98 -55
  201. package/pages/diagnostic.vue +59 -11
  202. package/pages/fail-whale.vue +14 -8
  203. package/pages/home.vue +24 -18
  204. package/pages/prefs.vue +7 -6
  205. package/pages/support/index.vue +4 -1
  206. package/plugins/internal-api/index.ts +37 -0
  207. package/plugins/internal-api/shared/base-api.ts +13 -0
  208. package/plugins/internal-api/shell/shell.api.ts +108 -0
  209. package/plugins/steve/actions.js +0 -12
  210. package/public/index.html +1 -0
  211. package/rancher-components/Card/Card.vue +1 -1
  212. package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
  213. package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
  214. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +47 -0
  215. package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
  216. package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
  217. package/rancher-components/Form/Radio/RadioButton.vue +20 -4
  218. package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
  219. package/rancher-components/Form/Radio/RadioGroup.vue +52 -10
  220. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
  221. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +5 -0
  222. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
  223. package/rancher-components/RcButton/RcButton.vue +2 -1
  224. package/rancher-components/RcButton/types.ts +1 -0
  225. package/rancher-components/RcDropdown/RcDropdown.vue +18 -6
  226. package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
  227. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
  228. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
  229. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
  230. package/rancher-components/RcDropdown/index.ts +2 -0
  231. package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
  232. package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
  233. package/rancher-components/RcDropdown/useDropdownItem.ts +63 -0
  234. package/scripts/extension/bundle +20 -0
  235. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
  236. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  237. package/scripts/extension/helmpatch +44 -31
  238. package/scripts/extension/publish +12 -12
  239. package/scripts/typegen.sh +2 -4
  240. package/server/har-file.js +25 -3
  241. package/store/action-menu.js +26 -56
  242. package/store/features.js +2 -1
  243. package/store/index.js +5 -0
  244. package/store/modal.ts +71 -0
  245. package/store/slideInPanel.ts +47 -0
  246. package/store/type-map.js +12 -1
  247. package/store/type-map.utils.ts +4 -4
  248. package/types/global-vue.d.ts +5 -0
  249. package/types/internal-api/shell/growl.d.ts +25 -0
  250. package/types/internal-api/shell/modal.d.ts +77 -0
  251. package/types/internal-api/shell/slideIn.d.ts +15 -0
  252. package/types/resources/fleet.d.ts +0 -14
  253. package/types/shell/index.d.ts +43 -24
  254. package/types/vue-shim.d.ts +4 -1
  255. package/utils/__mocks__/tabbable.js +13 -0
  256. package/utils/__tests__/object.test.ts +38 -4
  257. package/utils/cluster.js +35 -0
  258. package/utils/fleet.ts +15 -73
  259. package/utils/object.js +48 -5
  260. package/utils/validators/formRules/__tests__/index.test.ts +10 -1
  261. package/utils/validators/formRules/index.ts +27 -3
  262. package/utils/validators/machine-pool.ts +20 -0
  263. package/components/DisableAuthProviderModal.vue +0 -114
  264. package/components/MoveModal.vue +0 -166
  265. package/components/PromptChangePassword.vue +0 -123
  266. package/components/fleet/FleetBundleResources.vue +0 -86
  267. package/components/formatter/ExtensionCache.vue +0 -74
  268. package/components/formatter/Port.vue +0 -24
  269. package/components/formatter/SecretType.vue +0 -41
  270. package/types/vue-shim.d +0 -20
@@ -618,8 +618,6 @@ export default {
618
618
  this.registerBeforeHook(this.getPorts, 'getPorts');
619
619
 
620
620
  this.registerAfterHook(this.saveService, 'saveService');
621
-
622
- this.selectContainer(this.container);
623
621
  },
624
622
 
625
623
  methods: {
@@ -26,6 +26,7 @@ import replaceAll from '@shell/plugins/replaceall';
26
26
  import steveCreateWorker from '@shell/plugins/steve-create-worker';
27
27
  import emberCookie from '@shell/plugins/ember-cookie';
28
28
  import ShortKey from '@shell/plugins/shortkey';
29
+ import internalApiPlugin from '@shell/plugins/internal-api';
29
30
 
30
31
  import 'floating-vue/dist/style.css';
31
32
  import { floatingVueOptions } from '@shell/plugins/floating-vue';
@@ -46,7 +47,7 @@ export async function installPlugins(vueApp) {
46
47
  }
47
48
 
48
49
  export async function installInjectedPlugins(app, vueApp) {
49
- const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, plugin, steveCreateWorker, emberCookie];
50
+ const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, plugin, steveCreateWorker, emberCookie, internalApiPlugin];
50
51
 
51
52
  const installations = pluginDefinitions.map(async(pluginDefinition) => {
52
53
  if (typeof pluginDefinition === 'function') {
@@ -178,7 +178,10 @@ export default {
178
178
  <div class="no-clusters">
179
179
  {{ t('harvesterManager.cluster.none') }}
180
180
  </div>
181
- <hr class="info-section">
181
+ <hr
182
+ class="info-section"
183
+ role="none"
184
+ >
182
185
  <div class="logo">
183
186
  <BrandImage
184
187
  file-name="harvester.png"
@@ -1,27 +1,13 @@
1
1
  <script>
2
- import { mapState, mapGetters } from 'vuex';
3
- import AsyncButton from '@shell/components/AsyncButton';
4
- import AppModal from '@shell/components/AppModal';
5
- import { Card } from '@components/Card';
2
+ import { mapGetters } from 'vuex';
6
3
  import ResourceTable from '@shell/components/ResourceTable';
7
- import { Banner } from '@components/Banner';
8
- import { LabeledInput } from '@components/Form/LabeledInput';
9
4
  import { MANAGEMENT } from '@shell/config/types';
10
- import { SETTING } from '@shell/config/settings';
11
5
  import ResourceFetch from '@shell/mixins/resource-fetch';
12
- import { getVendor } from '@shell/config/private-label';
13
6
 
14
7
  export default {
15
- components: {
16
- AsyncButton,
17
- Banner,
18
- Card,
19
- ResourceTable,
20
- LabeledInput,
21
- AppModal,
22
- },
23
- mixins: [ResourceFetch],
24
- props: {
8
+ components: { ResourceTable },
9
+ mixins: [ResourceFetch],
10
+ props: {
25
11
  resource: {
26
12
  type: String,
27
13
  required: true,
@@ -40,46 +26,15 @@ export default {
40
26
 
41
27
  async fetch() {
42
28
  await this.$fetchType(this.resource);
43
-
44
- this.serverUrlSetting = this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.SERVER_URL);
45
-
46
- if (this.serverUrlSetting?.value) {
47
- this.serverUrl = this.serverUrlSetting.value;
48
- } else {
49
- this.noUrlSet = true;
50
- this.serverUrl = window.location.origin;
51
- }
52
- },
53
-
54
- data() {
55
- return {
56
- update: [],
57
- updateMode: 'activate',
58
- error: null,
59
- enabling: false,
60
- restart: false,
61
- waiting: false,
62
- timer: null,
63
- serverUrlSetting: {},
64
- serverUrl: '',
65
- noUrlSet: false,
66
- showModal: false,
67
- vendor: getVendor(),
68
- };
69
29
  },
70
30
 
71
31
  computed: {
72
- ...mapState('action-menu', ['showPromptUpdate', 'toUpdate']),
73
32
  ...mapGetters({ t: 'i18n/t' }),
74
33
 
75
34
  filteredRows() {
76
35
  return this.rows.filter((x) => x.name !== 'fleet');
77
36
  },
78
37
 
79
- promptForUrl() {
80
- return this.update?.id === 'multi-cluster-management' && this.noUrlSet;
81
- },
82
-
83
38
  enableRowActions() {
84
39
  const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.FEATURE);
85
40
 
@@ -90,109 +45,6 @@ export default {
90
45
  $loadingResources() {
91
46
  // results are filtered so we wouldn't get the correct count on indicator...
92
47
  return { loadIndeterminate: true };
93
- },
94
-
95
- watch: {
96
- showPromptUpdate(show) {
97
- if (show) {
98
- // Clear last error
99
- this.error = null;
100
-
101
- this.showModal = true;
102
- } else {
103
- this.showModal = false;
104
- }
105
- },
106
-
107
- toUpdate(neu) {
108
- // Only support updating one at a time - bulk does not make sense, as they may
109
- // be in different states and with different restart values
110
- this.update = Array.isArray(neu) ? neu[0] : neu;
111
- if (this.update) {
112
- this.restart = this.update.restartRequired;
113
- // If the value is currently false, then we will be enabling it
114
- this.enabling = !this.update.enabled;
115
- this.updateMode = this.enabling ? 'activate' : 'deactivate';
116
- }
117
- }
118
- },
119
-
120
- methods: {
121
- close() {
122
- this.$store.commit('action-menu/togglePromptUpdate');
123
-
124
- if (this.timer) {
125
- clearTimeout(this.timer);
126
- this.timer = null;
127
- }
128
- },
129
-
130
- toggleFlag(btnCB) {
131
- if (this.restart) {
132
- this.doToggleWithRestart(btnCB);
133
- } else {
134
- this.doToggle(btnCB);
135
- }
136
- },
137
-
138
- async doToggle(btnCB) {
139
- this.error = null;
140
- try {
141
- this.update.spec.value = !this.update.enabled;
142
- await this.update.save();
143
- btnCB(true);
144
- this.close();
145
- } catch (err) {
146
- // An error occurred, so toggle back the value - the call failed, so the change was not made
147
- this.update.spec.value = !this.update.enabled;
148
- this.error = err.message || err;
149
- btnCB(false);
150
- }
151
- },
152
-
153
- doToggleWithRestart(btnCB) {
154
- this.error = null;
155
- try {
156
- this.update.spec.value = !this.update.enabled;
157
- // await can go back in when backend returns from the save before restarting
158
- this.update.save();
159
- } catch (err) {}
160
-
161
- this.waitForBackend(btnCB, this.update.id);
162
- this.waiting = true;
163
- },
164
-
165
- waitForBackend(btnCB, id) {
166
- const url = `/v3/features/${ id }`;
167
-
168
- this.timer = setTimeout(async() => {
169
- try {
170
- const response = await this.$axios.get(url, { timeout: 5000 });
171
-
172
- if (response?.status === 200) {
173
- await this.$store.dispatch('management/findAll', { type: this.resource, opt: { force: true } });
174
- btnCB(true);
175
- this.close();
176
- this.waiting = false;
177
- }
178
- } catch (e) {}
179
-
180
- if (this.waiting) {
181
- this.waitForBackend(btnCB, id);
182
- }
183
- }, 5000);
184
- },
185
-
186
- async saveUrl(btnCB) {
187
- try {
188
- this.serverUrlSetting.value = this.serverUrl;
189
- await this.serverUrlSetting.save();
190
- btnCB(true);
191
- } catch (err) {
192
- this.error = err;
193
- btnCB(false);
194
- }
195
- },
196
48
  }
197
49
  };
198
50
  </script>
@@ -217,145 +69,10 @@ export default {
217
69
  </div>
218
70
  </template>
219
71
  </ResourceTable>
220
- <app-modal
221
- v-if="showModal"
222
- class="update-modal"
223
- name="toggleFlag"
224
- :width="450"
225
- height="auto"
226
- styles="max-height: 100vh;"
227
- :click-to-close="!restart || !waiting"
228
- @close="close"
229
- >
230
- <Card
231
- v-if="!waiting"
232
- class="prompt-update"
233
- :show-highlight-border="false"
234
- >
235
- <template #title>
236
- <h4 class="text-default-text">
237
- {{ t('featureFlags.title') }}
238
- </h4>
239
- </template>
240
- <template #body>
241
- <div
242
- v-if="update"
243
- class="mb-10"
244
- >
245
- <div v-if="enabling">
246
- <span>
247
- {{ t('featureFlags.promptActivate', {flag: update.id}) }}
248
- </span>
249
- <div
250
- v-if="promptForUrl"
251
- class="mt-10"
252
- >
253
- <span> {{ t('featureFlags.requiresSetting') }}</span>
254
- <div
255
- :style="{'align-items':'center'}"
256
- class="row mt-10"
257
- >
258
- <LabeledInput
259
- v-model:value="serverUrl"
260
- :label="t('setup.serverUrl.label')"
261
- />
262
- <div class="col pl-5">
263
- <AsyncButton @click="saveUrl" />
264
- </div>
265
- </div>
266
- </div>
267
- </div>
268
- <span v-else>
269
- {{ t('featureFlags.promptDeactivate', {flag: update.id}) }}
270
- </span>
271
- <Banner
272
- v-if="restart"
273
- color="error"
274
- :label="t('featureFlags.restartRequired', vendor)"
275
- />
276
- </div>
277
- <div class="text-error mb-10">
278
- {{ error }}
279
- </div>
280
- </template>
281
- <template #actions>
282
- <button
283
- class="btn role-secondary"
284
- @click="close"
285
- >
286
- {{ t('generic.cancel') }}
287
- </button>
288
- <AsyncButton
289
- :disabled="promptForUrl && !serverUrlSetting.value"
290
- :mode="updateMode"
291
- class="btn bg-error ml-10"
292
- @click="toggleFlag"
293
- />
294
- </template>
295
- </Card>
296
- <Card
297
- v-else
298
- class="prompt-update"
299
- :show-highlight-border="false"
300
- >
301
- <template #title>
302
- <h4 class="text-default-text">
303
- {{ t('featureFlags.restart.title') }}
304
- </h4>
305
- </template>
306
- <template #body>
307
- <div class="waiting">
308
- <p>{{ t('featureFlags.restart.wait') }}</p>
309
- <span class="restarting-icon">
310
- <i class=" icon icon-spinner icon-spin" />
311
- </span>
312
- </div>
313
- </template>
314
- <template #actions>
315
- <button
316
- class="btn role-secondary"
317
- @click="close"
318
- >
319
- {{ t('generic.cancel') }}
320
- </button>
321
- </template>
322
- </Card>
323
- </app-modal>
324
72
  </div>
325
73
  </template>
326
74
 
327
75
  <style lang='scss' scoped>
328
- .prompt-update {
329
- &.card-container {
330
- box-shadow: none;
331
- }
332
-
333
- :deep() .card-actions {
334
- display: flex;
335
- justify-content: center;
336
- }
337
- }
338
-
339
- .waiting {
340
- text-align: center;
341
- font-size: 14px;
342
- margin: 10px 0;
343
-
344
- p {
345
- line-height: 20px;;
346
- }
347
- }
348
-
349
- .restarting-icon {
350
- display: flex;
351
- justify-content: center;
352
- margin-top: 10px;
353
-
354
- > I {
355
- font-size: 24px;
356
- }
357
- }
358
-
359
76
  .feature-name {
360
77
  align-items: center;
361
78
  display: flex;
@@ -113,24 +113,32 @@ export default {
113
113
  },
114
114
 
115
115
  createLocation() {
116
- return {
117
- name: 'c-cluster-product-resource-create',
118
- params: {
119
- product: this.$store.getters['currentProduct'].name,
120
- resource: this.resource
121
- },
116
+ const options = this.$store.getters[`type-map/optionsFor`](this.resource)?.custom || {};
117
+ const params = {
118
+ product: this.$store.getters['currentProduct'].name,
119
+ resource: this.resource
120
+ };
121
+ const defaultLocation = {
122
+ name: 'c-cluster-product-resource-create',
123
+ params
122
124
  };
125
+
126
+ return options.createLocation ? options.createLocation(params) : defaultLocation;
123
127
  },
124
128
 
125
129
  importLocation() {
126
- return {
127
- name: 'c-cluster-product-resource-create',
128
- params: {
129
- product: this.$store.getters['currentProduct'].name,
130
- resource: this.resource
131
- },
130
+ const options = this.$store.getters[`type-map/optionsFor`](this.resource)?.custom || {};
131
+ const params = {
132
+ product: this.$store.getters['currentProduct'].name,
133
+ resource: this.resource
134
+ };
135
+ const defaultLocation = {
136
+ name: 'c-cluster-product-resource-create',
137
+ params,
132
138
  query: { [MODE]: _IMPORT }
133
139
  };
140
+
141
+ return options.importLocation ? options.importLocation(params) : defaultLocation;
134
142
  },
135
143
 
136
144
  canImport() {
@@ -602,7 +602,10 @@ export default {
602
602
  />
603
603
  </div>
604
604
  </div>
605
- <hr class="mt-20">
605
+ <hr
606
+ class="mt-20"
607
+ role="none"
608
+ >
606
609
  <div class="row mt-20">
607
610
  <div class="col span-6">
608
611
  <LabeledInput
@@ -668,7 +671,10 @@ export default {
668
671
  </div>
669
672
  </div>
670
673
  </div>
671
- <hr class="mt-20 mb-20">
674
+ <hr
675
+ class="mt-20 mb-20"
676
+ role="none"
677
+ >
672
678
  <h2>{{ t('cluster.machineConfig.azure.sections.purchasePlan') }}</h2>
673
679
  <div class="row mt-20">
674
680
  <div class="col span-6">
@@ -681,7 +687,10 @@ export default {
681
687
  />
682
688
  </div>
683
689
  </div>
684
- <hr class="mt-20">
690
+ <hr
691
+ class="mt-20"
692
+ role="none"
693
+ >
685
694
  <h2>{{ t('cluster.machineConfig.azure.sections.network') }}</h2>
686
695
  <div class="row mt-20 mb-20">
687
696
  <div class="col span-6">
@@ -803,7 +812,10 @@ export default {
803
812
  />
804
813
  </div>
805
814
  </div>
806
- <hr class="mt-20 mb-20">
815
+ <hr
816
+ class="mt-20 mb-20"
817
+ role="none"
818
+ >
807
819
  <h2>{{ t('cluster.machineConfig.azure.sections.disks') }}</h2>
808
820
  <div class="row mt-20 mb-20">
809
821
  <div class="col span-6">
@@ -1,8 +1,5 @@
1
1
 
2
2
  export default {
3
- data() {
4
- return { overridesMixinPreventDoubleTriggerKeysOpen: false };
5
- },
6
3
  methods: {
7
4
  mappedKeys(map, vm) {
8
5
  // Defaults found at - https://github.com/sagalbot/vue-select/blob/master/src/components/Select.vue#L947
@@ -63,7 +60,6 @@ export default {
63
60
  if (vm.closeOnSelect) {
64
61
  // this ties in to the Select component implementation
65
62
  // so that the enter key handler doesn't open the dropdown again
66
- this.overridesMixinPreventDoubleTriggerKeysOpen = true;
67
63
  vm.open = false;
68
64
  vm.typeAheadPointer = -1;
69
65
  }
@@ -84,7 +84,31 @@ describe('class Namespace', () => {
84
84
  });
85
85
 
86
86
  it.todo('should return the project');
87
- it.todo('should return the groupByLabel with i18n');
87
+
88
+ describe('handling groupById', () => {
89
+ it('should return the groupById if have project id', () => {
90
+ const namespace = new Namespace({});
91
+
92
+ jest.spyOn(namespace, 'project', 'get').mockReturnValue({
93
+ id: 'mock-project-id',
94
+ type: 'project',
95
+ name: 'mock-project',
96
+ });
97
+
98
+ expect(namespace.groupById).toStrictEqual('mock-project-id');
99
+ });
100
+
101
+ it('should return the groupById if project id undefined', () => {
102
+ const t = jest.fn(() => 'Not in a Project');
103
+ const ctx = { rootGetters: { 'i18n/t': t } };
104
+ const namespace = new Namespace({}, ctx);
105
+
106
+ jest.spyOn(namespace, 'project', 'get').mockReturnValue({});
107
+
108
+ expect(namespace.groupById).toStrictEqual('Not in a Project');
109
+ });
110
+ });
111
+
88
112
  it.todo('should return the project name with i18n');
89
113
  it.todo('should return the projectNameSort');
90
114
  it.todo('should check if istioInstalled');
@@ -275,6 +275,11 @@ export default class CloudCredential extends NormanModel {
275
275
  expired: false,
276
276
  expiring: true,
277
277
  };
278
+ } else if (this.expiresIn) {
279
+ return {
280
+ expired: false,
281
+ expiring: false,
282
+ };
278
283
  }
279
284
 
280
285
  return null;
@@ -69,11 +69,17 @@ export default class FleetCluster extends SteveModel {
69
69
  }
70
70
 
71
71
  assignTo() {
72
- this.$dispatch('assignTo', [this]);
72
+ this.$dispatch('promptModal', {
73
+ component: 'AssignToDialog',
74
+ componentProps: { toAssign: [this] }
75
+ });
73
76
  }
74
77
 
75
78
  assignToBulk(items) {
76
- this.$dispatch('assignTo', items);
79
+ this.$dispatch('promptModal', {
80
+ component: 'AssignToDialog',
81
+ componentProps: { toAssign: items }
82
+ });
77
83
  }
78
84
 
79
85
  get canDelete() {
@@ -7,10 +7,7 @@ import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
7
7
  import { addObject, addObjects, findBy, insertAt } from '@shell/utils/array';
8
8
  import { set } from '@shell/utils/object';
9
9
  import SteveModel from '@shell/plugins/steve/steve-class';
10
- import {
11
- colorForState, mapStateToEnum, primaryDisplayStatusFromCount, stateDisplay, STATES_ENUM, stateSort,
12
- } from '@shell/plugins/dashboard-store/resource-class';
13
- import { NAME } from '@shell/config/product/explorer';
10
+ import { mapStateToEnum, primaryDisplayStatusFromCount, STATES_ENUM } from '@shell/plugins/dashboard-store/resource-class';
14
11
  import FleetUtils from '@shell/utils/fleet';
15
12
 
16
13
  function quacksLikeAHash(str) {
@@ -439,51 +436,28 @@ export default class GitRepo extends SteveModel {
439
436
  }, []);
440
437
 
441
438
  return resources.map((r) => {
442
- const {
443
- namespace, name, clusterId, state
444
- } = r;
445
- const id = FleetUtils.resourceId(r);
439
+ const { namespace, name, clusterId } = r;
446
440
  const type = FleetUtils.resourceType(r);
447
441
  const c = clusters[clusterId];
448
442
 
449
- const color = colorForState(state).replace('text-', 'bg-');
450
- const display = stateDisplay(state);
451
-
452
- const detailLocation = state !== STATES_ENUM.MISSING ? {
453
- name: `c-cluster-product-resource${ r.namespace ? '-namespace' : '' }-id`,
454
- params: {
455
- product: NAME,
456
- cluster: c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME], // explorer uses the "management" Cluster name, which differs from the Fleet Cluster name
457
- resource: type,
458
- namespace,
459
- id: name,
460
- }
461
- } : undefined;
462
-
463
- const key = `${ clusterId }-${ type }-${ namespace }-${ name }`;
464
-
465
443
  return {
466
- key,
467
- tableKey: key,
444
+ key: `${ clusterId }-${ type }-${ namespace }-${ name }`,
468
445
 
469
446
  // Needed?
470
- id,
447
+ id: FleetUtils.resourceId(r),
471
448
  type,
472
449
  clusterId,
473
450
 
474
451
  // columns, see FleetResources.vue
475
- state: mapStateToEnum(state),
452
+ state: mapStateToEnum(r.state),
476
453
  clusterName: c.nameDisplay,
477
454
  apiVersion: r.apiVersion,
478
455
  kind: r.kind,
479
- name: r.name,
480
- namespace: r.namespace,
456
+ name,
457
+ namespace,
481
458
 
482
459
  // other properties
483
- stateBackground: color,
484
- stateDisplay: display,
485
- stateSort: stateSort(color, display),
486
- detailLocation,
460
+ detailLocation: FleetUtils.detailLocation(r, c.metadata.labels[FLEET_ANNOTATIONS.CLUSTER_NAME]),
487
461
  };
488
462
  });
489
463
  }
@@ -72,14 +72,17 @@ export default class KontainerDriver extends Driver {
72
72
  return this.$dispatch('rancher/request', {
73
73
  url: `v3/kontainerDrivers/${ escape(this.id) }?action=activate`,
74
74
  method: 'post',
75
- }, { root: true });
75
+ }, { root: true }).catch((err) => {
76
+ this.$dispatch('growl/fromError', { title: this.t('drivers.error.activate', { name: this.nameDisplay }), err }, { root: true });
77
+ });
76
78
  }
77
79
 
78
80
  async activateBulk(resources) {
79
81
  await Promise.all(resources.map((resource) => this.$dispatch('rancher/request', {
80
82
  url: `v3/kontainerDrivers/${ escape(resource.id) }?action=activate`,
81
83
  method: 'post',
82
- }, { root: true }
83
- )));
84
+ }, { root: true }).catch((err) => {
85
+ this.$dispatch('growl/fromError', { title: this.t('drivers.error.activate', { name: resource.nameDisplay }), err }, { root: true });
86
+ })));
84
87
  }
85
88
  }
@@ -51,6 +51,12 @@ export default class Feature extends HybridModel {
51
51
  }
52
52
 
53
53
  toggleFeatureFlag(resources = this) {
54
- this.$dispatch('promptUpdate', resources);
54
+ this.$dispatch('promptModal', {
55
+ component: 'FeatureFlagListDialog',
56
+ resources: !Array.isArray(resources) ? [resources] : resources,
57
+ modalWidth: '450',
58
+ height: 'auto',
59
+ styles: 'max-height: 100vh;'
60
+ });
55
61
  }
56
62
  }
@@ -168,12 +168,12 @@ export default class MgmtNode extends HybridModel {
168
168
  }
169
169
 
170
170
  get canScaleDown() {
171
- if (!this.isEtcd && !this.isControlPlane) {
171
+ const hasAction = this.norman?.actions?.scaledown;
172
+
173
+ if (!this.isEtcd && !this.isControlPlane && hasAction) {
172
174
  return true;
173
175
  }
174
176
 
175
- const hasAction = this.norman?.actions?.scaledown;
176
-
177
177
  return hasAction && notOnlyOfRole(this, this.provisioningCluster?.nodes);
178
178
  }
179
179
  }