@rancher/shell 3.0.8-rc.8 → 3.0.8

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 (260) hide show
  1. package/apis/impl/apis.ts +61 -0
  2. package/apis/index.ts +40 -0
  3. package/apis/intf/modal.ts +90 -0
  4. package/apis/intf/shell.ts +36 -0
  5. package/apis/intf/slide-in.ts +98 -0
  6. package/apis/intf/system.ts +41 -0
  7. package/apis/shell/__tests__/modal.test.ts +80 -0
  8. package/apis/shell/__tests__/notifications.test.ts +71 -0
  9. package/apis/shell/__tests__/slide-in.test.ts +54 -0
  10. package/apis/shell/__tests__/system.test.ts +129 -0
  11. package/apis/shell/index.ts +38 -0
  12. package/apis/shell/modal.ts +41 -0
  13. package/apis/shell/notifications.ts +65 -0
  14. package/apis/shell/slide-in.ts +33 -0
  15. package/apis/shell/system.ts +65 -0
  16. package/apis/vue-shim.d.ts +11 -0
  17. package/assets/brand/suse/dark/rancher-logo.svg +1 -64
  18. package/assets/styles/global/_tooltip.scss +6 -1
  19. package/assets/translations/en-us.yaml +14 -1
  20. package/components/ActionMenuShell.vue +3 -1
  21. package/components/BackLink.vue +8 -0
  22. package/components/BannerGraphic.vue +1 -5
  23. package/components/BrandImage.vue +17 -6
  24. package/components/Cron/CronExpressionEditor.vue +1 -1
  25. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  26. package/components/CruResource.vue +8 -1
  27. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +1 -0
  28. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +50 -1
  29. package/components/Drawer/ResourceDetailDrawer/composables.ts +19 -0
  30. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -1
  31. package/components/Drawer/ResourceDetailDrawer/types.ts +2 -1
  32. package/components/LocaleSelector.vue +2 -2
  33. package/components/ModalManager.vue +11 -1
  34. package/components/Questions/__tests__/Yaml.test.ts +1 -1
  35. package/components/Questions/__tests__/index.test.ts +159 -0
  36. package/components/RelatedResources.vue +5 -0
  37. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  38. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  39. package/components/Resource/Detail/Metadata/index.vue +3 -3
  40. package/components/Resource/Detail/ResourcePopover/index.vue +5 -1
  41. package/components/Resource/Detail/composables.ts +2 -2
  42. package/components/ResourceDetail/Masthead/latest.vue +23 -21
  43. package/components/ResourceDetail/index.vue +3 -0
  44. package/components/ResourceTable.vue +54 -21
  45. package/components/SlideInPanelManager.vue +16 -11
  46. package/components/SortableTable/THead.vue +2 -1
  47. package/components/SortableTable/index.vue +20 -2
  48. package/components/Tabbed/__tests__/index.test.ts +86 -0
  49. package/components/Tabbed/index.vue +37 -2
  50. package/components/__tests__/NamespaceFilter.test.ts +49 -0
  51. package/components/auth/SelectPrincipal.vue +28 -6
  52. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  53. package/components/auth/login/ldap.vue +3 -3
  54. package/components/fleet/FleetSecretSelector.vue +1 -1
  55. package/components/form/KeyValue.vue +1 -1
  56. package/components/form/NameNsDescription.vue +1 -1
  57. package/components/form/NodeScheduling.vue +2 -2
  58. package/components/form/ResourceTabs/composable.ts +2 -2
  59. package/components/form/ResourceTabs/index.vue +0 -2
  60. package/components/form/__tests__/NameNsDescription.test.ts +42 -0
  61. package/components/formatter/InternalExternalIP.vue +4 -1
  62. package/components/formatter/LinkName.vue +5 -0
  63. package/components/formatter/__tests__/InternalExternalIP.test.ts +1 -1
  64. package/components/nav/Group.vue +25 -7
  65. package/components/nav/Header.vue +1 -1
  66. package/components/nav/NamespaceFilter.vue +1 -0
  67. package/components/nav/Type.vue +17 -6
  68. package/components/nav/WindowManager/panels/TabBodyContainer.vue +1 -1
  69. package/components/nav/__tests__/Type.test.ts +59 -0
  70. package/components/templates/standalone.vue +1 -1
  71. package/composables/cruResource.ts +27 -0
  72. package/composables/focusTrap.ts +3 -1
  73. package/composables/resourceDetail.ts +15 -0
  74. package/composables/useI18n.ts +10 -1
  75. package/composables/useLabeledFormElement.ts +3 -4
  76. package/config/__test__/uiplugins.test.ts +309 -0
  77. package/config/labels-annotations.js +1 -0
  78. package/config/product/explorer.js +3 -1
  79. package/config/product/fleet.js +1 -1
  80. package/config/router/navigation-guards/clusters.js +3 -3
  81. package/config/router/navigation-guards/products.js +1 -1
  82. package/config/router/routes.js +7 -7
  83. package/config/types.js +7 -0
  84. package/config/uiplugins.js +46 -2
  85. package/core/__tests__/extension-manager-impl.test.js +437 -0
  86. package/core/extension-manager-impl.js +21 -25
  87. package/core/plugin-helpers.ts +2 -2
  88. package/core/plugin.ts +9 -1
  89. package/core/plugins-loader.js +2 -2
  90. package/core/types-provisioning.ts +5 -1
  91. package/core/types.ts +35 -0
  92. package/detail/provisioning.cattle.io.cluster.vue +9 -6
  93. package/dialog/DeveloperLoadExtensionDialog.vue +13 -4
  94. package/dialog/MoveNamespaceDialog.vue +20 -4
  95. package/dialog/RollbackWorkloadDialog.vue +2 -5
  96. package/dialog/SearchDialog.vue +1 -0
  97. package/dialog/__tests__/MoveNamespaceDialog.test.ts +249 -0
  98. package/directives/__tests__/clean-tooltip.test.ts +298 -0
  99. package/directives/clean-tooltip.ts +234 -0
  100. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -2
  101. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +100 -3
  102. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  103. package/edit/configmap.vue +1 -0
  104. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  105. package/edit/fleet.cattle.io.helmop.vue +11 -6
  106. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  107. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  108. package/edit/logging-flow/index.vue +1 -0
  109. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  110. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  111. package/edit/management.cattle.io.project.vue +1 -0
  112. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  113. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  114. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  115. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  116. package/edit/monitoring.coreos.com.route.vue +1 -1
  117. package/edit/namespace.vue +1 -0
  118. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  119. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  120. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  121. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  122. package/edit/node.vue +1 -0
  123. package/edit/persistentvolume/index.vue +27 -22
  124. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  125. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  126. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  127. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  128. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  129. package/edit/persistentvolume/plugins/csi.vue +18 -16
  130. package/edit/persistentvolume/plugins/fc.vue +13 -14
  131. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  132. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  133. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  134. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  135. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  136. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  137. package/edit/persistentvolume/plugins/local.vue +1 -3
  138. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  139. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  140. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  141. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  142. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  143. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  144. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  145. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  146. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  147. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +21 -21
  148. package/edit/provisioning.cattle.io.cluster/index.vue +5 -5
  149. package/edit/provisioning.cattle.io.cluster/rke2.vue +9 -8
  150. package/edit/resources.cattle.io.restore.vue +1 -1
  151. package/edit/secret/index.vue +1 -1
  152. package/edit/service.vue +1 -0
  153. package/edit/serviceaccount.vue +1 -0
  154. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  155. package/edit/workload/Job.vue +2 -2
  156. package/edit/workload/index.vue +2 -1
  157. package/edit/workload/mixins/workload.js +1 -1
  158. package/initialize/App.vue +4 -4
  159. package/initialize/install-plugins.js +19 -5
  160. package/machine-config/azure.vue +1 -1
  161. package/machine-config/components/GCEImage.vue +1 -1
  162. package/mixins/__tests__/brand.spec.ts +2 -2
  163. package/mixins/brand.js +1 -7
  164. package/mixins/create-edit-view/index.js +5 -0
  165. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +128 -5
  166. package/models/chart.js +70 -74
  167. package/models/management.cattle.io.cluster.js +21 -3
  168. package/models/provisioning.cattle.io.cluster.js +31 -11
  169. package/package.json +11 -10
  170. package/pages/auth/login.vue +4 -6
  171. package/pages/auth/setup.vue +1 -1
  172. package/pages/auth/verify.vue +3 -3
  173. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  174. package/pages/c/_cluster/apps/charts/chart.vue +33 -15
  175. package/pages/c/_cluster/apps/charts/index.vue +122 -24
  176. package/pages/c/_cluster/apps/charts/install.vue +33 -0
  177. package/pages/c/_cluster/explorer/__tests__/index.test.ts +1 -1
  178. package/pages/c/_cluster/explorer/index.vue +8 -6
  179. package/pages/c/_cluster/fleet/index.vue +4 -7
  180. package/pages/c/_cluster/manager/hostedprovider/index.vue +12 -6
  181. package/pages/c/_cluster/settings/brand.vue +1 -1
  182. package/pages/c/_cluster/settings/index.vue +5 -0
  183. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  184. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  185. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  186. package/pkg/auto-import.js +3 -3
  187. package/pkg/dynamic-importer.lib.js +1 -1
  188. package/pkg/import.js +1 -1
  189. package/plugins/__tests__/mutations.tests.ts +179 -0
  190. package/plugins/dashboard-client-init.js +3 -0
  191. package/plugins/dashboard-store/getters.js +19 -2
  192. package/plugins/dashboard-store/model-loader.js +1 -1
  193. package/plugins/dashboard-store/mutations.js +23 -2
  194. package/plugins/dashboard-store/resource-class.js +11 -5
  195. package/plugins/i18n.js +8 -0
  196. package/plugins/plugin.js +2 -2
  197. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +506 -0
  198. package/plugins/steve/steve-class.js +1 -1
  199. package/plugins/steve/steve-pagination-utils.ts +131 -47
  200. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  201. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  202. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -42
  203. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  204. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  205. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  206. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  207. package/rancher-components/Pill/types.ts +0 -1
  208. package/rancher-components/RcDropdown/useDropdownContext.ts +2 -4
  209. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  210. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  211. package/rancher-components/RcIcon/index.ts +1 -0
  212. package/rancher-components/RcIcon/types.ts +160 -0
  213. package/rancher-components/RcItemCard/RcItemCard.vue +1 -1
  214. package/rancher-components/utils/status.test.ts +67 -0
  215. package/rancher-components/utils/status.ts +77 -0
  216. package/scripts/publish-shell.sh +25 -0
  217. package/scripts/typegen.sh +1 -0
  218. package/store/__tests__/catalog.test.ts +1 -1
  219. package/store/__tests__/type-map.test.ts +164 -2
  220. package/store/action-menu.js +8 -0
  221. package/store/auth.js +25 -13
  222. package/store/catalog.js +6 -0
  223. package/store/i18n.js +3 -3
  224. package/store/index.js +8 -6
  225. package/store/notifications.ts +2 -0
  226. package/store/prefs.js +6 -7
  227. package/store/type-map.js +17 -7
  228. package/store/wm.ts +4 -4
  229. package/types/internal-api/shell/modal.d.ts +6 -6
  230. package/types/notifications/index.ts +126 -15
  231. package/types/rancher/index.d.ts +9 -0
  232. package/types/shell/index.d.ts +54 -3
  233. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  234. package/types/store/pagination.types.ts +157 -9
  235. package/types/vue-shim.d.ts +5 -4
  236. package/utils/__tests__/provider.test.ts +98 -0
  237. package/utils/__tests__/router.test.js +238 -0
  238. package/utils/__tests__/selector-typed.test.ts +263 -0
  239. package/utils/cluster.js +4 -1
  240. package/utils/color.js +1 -1
  241. package/utils/dynamic-content/__tests__/info.test.ts +6 -0
  242. package/utils/dynamic-content/info.ts +43 -0
  243. package/utils/favicon.js +4 -4
  244. package/utils/fleet.ts +8 -1
  245. package/utils/pagination-utils.ts +2 -2
  246. package/utils/pagination-wrapper.ts +1 -1
  247. package/utils/provider.ts +14 -0
  248. package/utils/router.js +50 -0
  249. package/utils/selector-typed.ts +6 -2
  250. package/utils/unit-tests/pagination-utils.spec.ts +8 -8
  251. package/vue.config.js +3 -3
  252. package/composables/useExtensionManager.ts +0 -17
  253. package/core/plugins.js +0 -38
  254. package/directives/clean-tooltip.js +0 -32
  255. package/plugins/internal-api/index.ts +0 -37
  256. package/plugins/internal-api/shared/base-api.ts +0 -13
  257. package/plugins/internal-api/shell/shell.api.ts +0 -108
  258. package/plugins/nuxt-client-init.js +0 -3
  259. package/types/internal-api/shell/growl.d.ts +0 -25
  260. package/types/internal-api/shell/slideIn.d.ts +0 -15
package/store/i18n.js CHANGED
@@ -285,8 +285,8 @@ export const actions = {
285
285
  return;
286
286
  }
287
287
 
288
- const lastLoad = rootState.$plugin?.lastLoad;
289
- const i18nExt = rootState.$plugin?.getDynamic('l10n', locale);
288
+ const lastLoad = rootState.$extension?.lastLoad;
289
+ const i18nExt = rootState.$extension?.getDynamic('l10n', locale);
290
290
  const reload = lastLoaded < lastLoad;
291
291
 
292
292
  lastLoaded = lastLoad;
@@ -314,7 +314,7 @@ export const actions = {
314
314
 
315
315
  // load all of the default locales from the plugins for fallback
316
316
  if (locale !== DEFAULT_LOCALE) {
317
- const defaultI18nExt = rootState.$plugin?.getDynamic('l10n', DEFAULT_LOCALE);
317
+ const defaultI18nExt = rootState.$extension?.getDynamic('l10n', DEFAULT_LOCALE);
318
318
 
319
319
  if (defaultI18nExt && defaultI18nExt.length) {
320
320
  defaultI18nExt.forEach((fn) => {
package/store/index.js CHANGED
@@ -233,7 +233,7 @@ const updateActiveNamespaceCache = (state, activeNamespaceCache) => {
233
233
  * Are we in the vai enabled world where mgmt clusters are paginated?
234
234
  */
235
235
  const paginateClusters = ({ rootGetters, state }) => {
236
- return paginationUtils.isEnabled({ rootGetters, $plugin: state.$plugin }, { store: 'management', resource: { id: MANAGEMENT.CLUSTER, context: 'side-bar' } });
236
+ return paginationUtils.isEnabled({ rootGetters, $extension: state.$extension }, { store: 'management', resource: { id: MANAGEMENT.CLUSTER, context: 'side-bar' } });
237
237
  };
238
238
 
239
239
  export const state = () => {
@@ -262,6 +262,7 @@ export const state = () => {
262
262
  $router: markRaw({}),
263
263
  $route: markRaw({}),
264
264
  $plugin: markRaw({}),
265
+ $extension: markRaw({}),
265
266
  showWorkspaceSwitcher: true,
266
267
  localCluster: null,
267
268
  };
@@ -775,6 +776,7 @@ export const mutations = {
775
776
  },
776
777
 
777
778
  setPlugin(state, pluginDefinition) {
779
+ state.$extension = markRaw(pluginDefinition || {});
778
780
  state.$plugin = markRaw(pluginDefinition || {});
779
781
  },
780
782
 
@@ -1195,7 +1197,7 @@ export const actions = {
1195
1197
 
1196
1198
  store.dispatch('gcStopIntervals');
1197
1199
 
1198
- Object.values(this.$plugin.getPlugins()).forEach((p) => {
1200
+ Object.values(this.$extension.getPlugins()).forEach((p) => {
1199
1201
  if (p.onLogOut) {
1200
1202
  p.onLogOut(store);
1201
1203
  }
@@ -1251,10 +1253,10 @@ export const actions = {
1251
1253
  }
1252
1254
  },
1253
1255
 
1254
- nuxtClientInit({ dispatch, commit, rootState }, nuxt) {
1255
- commit('setRouter', nuxt.app.router);
1256
- commit('setRoute', nuxt.route);
1257
- commit('setPlugin', nuxt.app.$plugin);
1256
+ dashboardClientInit({ dispatch, commit, rootState }, context) {
1257
+ commit('setRouter', context.app.router);
1258
+ commit('setRoute', context.route);
1259
+ commit('setPlugin', context.app.$extension);
1258
1260
 
1259
1261
  dispatch('management/rehydrateSubscribe');
1260
1262
  dispatch('cluster/rehydrateSubscribe');
@@ -299,6 +299,8 @@ export const actions = {
299
299
 
300
300
  // Show a growl for the notification if necessary
301
301
  dispatch('growl/notification', notification, { root: true });
302
+
303
+ return notification.id;
302
304
  },
303
305
 
304
306
  async fromGrowl( { commit, getters }: any, notification: Notification) {
package/store/prefs.js CHANGED
@@ -233,13 +233,13 @@ export const getters = {
233
233
  }
234
234
  const clusterPref = getters['get'](CLUSTER);
235
235
 
236
- return { name: 'c-cluster-explorer', params: { product: 'explorer', cluster: clusterPref } };
236
+ return { name: 'c-cluster-explorer', params: { cluster: clusterPref } };
237
237
  }
238
238
  case (!!afterLoginRoutePref.match(/.+-dashboard$/)):
239
239
  {
240
240
  const clusterId = afterLoginRoutePref.split('-dashboard')[0];
241
241
 
242
- return { name: 'c-cluster-explorer', params: { product: 'explorer', cluster: clusterId } };
242
+ return { name: 'c-cluster-explorer', params: { cluster: clusterId } };
243
243
  }
244
244
  default:
245
245
  return { name: afterLoginRoutePref };
@@ -523,15 +523,14 @@ export const actions = {
523
523
  setBrandStyle({ rootState, rootGetters }, dark = false) {
524
524
  if (rootState.managementReady) {
525
525
  try {
526
- const brandSetting = rootGetters['management/byId'](MANAGEMENT.SETTING, SETTING.BRAND);
526
+ const brandSetting = rootGetters['management/brand'];
527
527
 
528
- if (brandSetting && brandSetting.value && brandSetting.value !== '') {
529
- const brand = brandSetting.value;
530
- const brandMeta = getBrandMeta(brand);
528
+ if (brandSetting !== '') {
529
+ const brandMeta = getBrandMeta(brandSetting);
531
530
  const hasStylesheet = brandMeta.hasStylesheet === 'true';
532
531
 
533
532
  if (hasStylesheet) {
534
- document.body.classList.add(brand);
533
+ document.body.classList.add(brandMeta);
535
534
  } else {
536
535
  // TODO option apply color at runtime
537
536
  }
package/store/type-map.js CHANGED
@@ -35,6 +35,7 @@
35
35
  // ifHave, -- Show this product only if the given capability is available
36
36
  // ifHaveGroup, -- Show this product only if the given group exists in the store [inStore]
37
37
  // ifHaveType, -- Show this product only if the given type exists in the store [inStore], This can also be specified as an object { type: TYPE, store: 'management' } if the type isn't in the current [inStore]
38
+ // ifNotHaveType, -- Hide this product if the given type exists in the store [inStore] (opposite of ifHaveType)
38
39
  // ifHaveVerb, -- In combination with ifHaveTYpe, show it only if the type also has this collectionMethod
39
40
  // inStore, -- Which store to look at for if* above and the left-nav, defaults to "cluster"
40
41
  // rootProduct, -- Optional root (parent) product - if set, used to optimize navigation when product changes stays within root product
@@ -152,6 +153,7 @@ import { haveV2Monitoring } from '@shell/utils/monitoring';
152
153
  import { NEU_VECTOR_NAMESPACE } from '@shell/config/product/neuvector';
153
154
  import { createHeaders, rowValueGetter } from '@shell/store/type-map.utils';
154
155
  import { defineAsyncComponent } from 'vue';
156
+ import { filterLocationValidParams } from '@shell/utils/router';
155
157
 
156
158
  export const NAMESPACED = 'namespaced';
157
159
  export const CLUSTER_LEVEL = 'cluster';
@@ -238,7 +240,7 @@ export function DSL(store, product, module = 'type-map') {
238
240
  };
239
241
 
240
242
  // Convert strings to regex's - we do this once here for efficiency
241
- for ( const k of ['ifHaveGroup', 'ifHaveType'] ) {
243
+ for ( const k of ['ifHaveGroup', 'ifHaveType', 'ifNotHaveType'] ) {
242
244
  if ( opt[k] ) {
243
245
  if (Array.isArray(opt[k])) {
244
246
  opt[k] = opt[k].map((r) => regexToString(ensureRegex(r)));
@@ -365,7 +367,7 @@ export function DSL(store, product, module = 'type-map') {
365
367
 
366
368
  let called = false;
367
369
 
368
- export async function applyProducts(store, $plugin) {
370
+ export async function applyProducts(store, $extension) {
369
371
  if (called) {
370
372
  return;
371
373
  }
@@ -379,7 +381,7 @@ export async function applyProducts(store, $plugin) {
379
381
  }
380
382
  }
381
383
  // Load the products from all plugins
382
- $plugin.loadProducts();
384
+ $extension.loadProducts();
383
385
  }
384
386
 
385
387
  export function productsLoaded() {
@@ -694,7 +696,7 @@ export const getters = {
694
696
  }
695
697
  };
696
698
 
697
- typeObj.route = route;
699
+ typeObj.route = filterLocationValidParams(rootState.$router, route);
698
700
  }
699
701
 
700
702
  // Cluster ID and Product should always be set
@@ -711,7 +713,7 @@ export const getters = {
711
713
  exact: typeObj.exact || false,
712
714
  'exact-path': typeObj['exact-path'] || false,
713
715
  namespaced,
714
- route,
716
+ route: filterLocationValidParams(rootState.$router, route),
715
717
  name: typeObj.name,
716
718
  weight: typeObj.weight || getters.typeWeightFor(typeObj.schema?.id || label, isBasic),
717
719
  overview: !!typeObj.overview,
@@ -1419,6 +1421,14 @@ export const getters = {
1419
1421
  }
1420
1422
  }
1421
1423
 
1424
+ if ( p.ifNotHaveType ) {
1425
+ const haveIds = knownTypes[module].filter((t) => t.match(stringToRegex(p.ifNotHaveType)) );
1426
+
1427
+ if ( haveIds.length ) {
1428
+ return false;
1429
+ }
1430
+ }
1431
+
1422
1432
  if ( p.ifHaveGroup && !knownGroups[module].find((t) => t.match(stringToRegex(p.ifHaveGroup)) ) ) {
1423
1433
  return false;
1424
1434
  }
@@ -2026,7 +2036,7 @@ function hasCustom(state, rootState, kind, key, fallback) {
2026
2036
  }
2027
2037
 
2028
2038
  // Check to see if the custom kind is provided by a plugin (ignore booleans)
2029
- const pluginComponent = rootState.$plugin.getDynamic(kind, key);
2039
+ const pluginComponent = rootState.$extension.getDynamic(kind, key);
2030
2040
 
2031
2041
  if (typeof pluginComponent !== 'boolean' && !!pluginComponent) {
2032
2042
  cache[key] = true;
@@ -2046,7 +2056,7 @@ function hasCustom(state, rootState, kind, key, fallback) {
2046
2056
  }
2047
2057
 
2048
2058
  function loadExtension(rootState, kind, key, fallback) {
2049
- const ext = rootState.$plugin.getDynamic(kind, key);
2059
+ const ext = rootState.$extension.getDynamic(kind, key);
2050
2060
 
2051
2061
  if (ext) {
2052
2062
  if (typeof ext === 'function') {
package/store/wm.ts CHANGED
@@ -80,11 +80,11 @@ export const mutations = {
80
80
  addTab(state: State, tab: Tab) {
81
81
  const existing = state.tabs.find((x) => x.id === tab.id);
82
82
 
83
- if (!existing) {
84
- if (tab.position === undefined) {
85
- tab.position = (window.localStorage.getItem(STORAGE_KEY['pin']) || BOTTOM) as Position;
86
- }
83
+ if (tab.position === undefined || tab.position as string === 'undefined') {
84
+ tab.position = (window.localStorage.getItem(STORAGE_KEY['pin']) || BOTTOM) as Position;
85
+ }
87
86
 
87
+ if (!existing) {
88
88
  if (state.lockedPositions.includes(BOTTOM)) {
89
89
  tab.position = BOTTOM;
90
90
  }
@@ -14,7 +14,7 @@ export interface ModalConfig {
14
14
  *
15
15
  * this.$shell.modal({
16
16
  * component: MyCustomModal,
17
- * componentProps: { title: 'Hello Modal' }
17
+ * props: { title: 'Hello Modal' }
18
18
  * });
19
19
  * ```
20
20
  */
@@ -25,10 +25,10 @@ export interface ModalConfig {
25
25
  *
26
26
  * Example:
27
27
  * ```ts
28
- * componentProps: { title: 'Hello Modal', isVisible: true }
28
+ * props: { title: 'Hello Modal', isVisible: true }
29
29
  * ```
30
30
  */
31
- componentProps?: Record<string, any>;
31
+ props?: Record<string, any>;
32
32
 
33
33
  /**
34
34
  * Optional array of resources that the modal component might need.
@@ -47,11 +47,11 @@ export interface ModalConfig {
47
47
  *
48
48
  * Examples:
49
49
  * ```ts
50
- * modalWidth: '800px' // Width in pixels
51
- * modalWidth: '75%' // Width as a percentage
50
+ * width: '800px' // Width in pixels
51
+ * width: '75%' // Width as a percentage
52
52
  * ```
53
53
  */
54
- modalWidth?: string;
54
+ width?: string;
55
55
 
56
56
  /**
57
57
  * Determines if clicking outside the modal will close it. Defaults to `true`.
@@ -4,36 +4,102 @@ import { RouteLocationRaw } from 'vue-router';
4
4
  * Type definitions for the Notification Center
5
5
  */
6
6
 
7
- /**
8
- * Notification Level for a notification in the Notification Center
9
- */
10
7
  export enum NotificationLevel {
8
+ /**
9
+ * An announcement. To be used when we want to inform on high-interest topics - news, updates, changes, scheduled maintenance, etc. E.g. “New version available!” <img class="svg-blue" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-announcement.svg" width="20" />
10
+ */
11
11
  Announcement = 0, // eslint-disable-line no-unused-vars
12
+ /**
13
+ * A task that is underway. To be used when we want to inform on a process taking place - on-going actions that might take a while. E.g. “Cluster provisioning in progress”. The progress bar will also be shown if the `progress` field is set <img class="svg-blue" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-busy.svg" width="20" />
14
+ */
12
15
  Task, // eslint-disable-line no-unused-vars
16
+ /**
17
+ * Information notification. To be used when we want to inform on low-interest topics. E.g. “Welcome to Rancher v2.8" <img class="svg-blue" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-info.svg"/>
18
+ */
13
19
  Info, // eslint-disable-line no-unused-vars
20
+ /**
21
+ * Notification that something has completed successfully. To be used when we want to confirm a successful action was completed. E.g. “Cluster provisioning completed” <img class="svg-green" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-tick.svg"/>
22
+ */
14
23
  Success, // eslint-disable-line no-unused-vars
24
+ /**
25
+ * Notification of a warning. To be used when we want to warn about a potential risk. E.g. “Nodes limitation warning” <img class="svg-orange" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-warning.svg"/>
26
+ */
15
27
  Warning, // eslint-disable-line no-unused-vars
28
+ /**
29
+ * Notification of an error. To be used when we want to alert on a confirmed risk. E.g. “Extension failed to load” <img class="svg-red" src="https://raw.githubusercontent.com/rancher/icons/refs/heads/master/svg/notify-error.svg"/>
30
+ */
16
31
  Error, // eslint-disable-line no-unused-vars
17
32
  Hidden, // eslint-disable-line no-unused-vars
18
33
  }
19
34
 
20
35
  /**
21
- * An action that is shown as a button in the Notification Center
36
+ * Notification Action definition
22
37
  */
23
- export type NotificationAction = {
24
- label: string; // Button label for the action
25
- target?: string; // HREF target when the button is clicked
26
- route?: RouteLocationRaw; // Route to navigate to when the button is clicked
27
- };
38
+ export interface NotificationAction {
39
+ /**
40
+ * Button label for the action
41
+ */
42
+ label: string;
43
+ /**
44
+ * Href target when the button is clicked
45
+ */
46
+ target?: string;
47
+ /**
48
+ * Vue Route to navigate to when the button is clicked
49
+ */
50
+ route?: RouteLocationRaw;
51
+ }
28
52
 
29
53
  /**
30
- * Defines the User Preference linked to a notification
54
+ * Notification Preference definition
31
55
  */
32
- export type NotificationPreference = {
33
- key: string; // User preference key to use when setting the preference when the notification is marked as read/unread
34
- value: string; // User preference value to use when setting the preference when the notification is marked as read
35
- unsetValue?: string; // User preference value to use when setting the preference when the notification is marked as unread - defaults to empty string
36
- };
56
+ export interface NotificationPreference {
57
+ /**
58
+ * User preference key to use when setting the preference when the notification is marked as read
59
+ */
60
+ key: string;
61
+ /**
62
+ * User preference value to use when setting the preference when the notification is marked as read
63
+ */
64
+ value: string;
65
+ /**
66
+ * User preference value to use when setting the preference when the notification is marked as unread - defaults to empty string
67
+ */
68
+ unsetValue?: string;
69
+ }
70
+
71
+ /**
72
+ * Configuration object for the Notification Center
73
+ *
74
+ */
75
+ export interface NotificationConfig {
76
+ /**
77
+ * - **{@link NotificationAction}**
78
+ *
79
+ * Primary action to be shown in the notification
80
+ */
81
+ primaryAction?: NotificationAction;
82
+ /**
83
+ * - **{@link NotificationAction}**
84
+ *
85
+ * Secondary to be shown in the notification
86
+ */
87
+ secondaryAction?: NotificationAction;
88
+ /**
89
+ * Unique ID for the notification
90
+ */
91
+ id?: string;
92
+ /**
93
+ * Progress (0-100) for notifications of type `Task`
94
+ */
95
+ progress?: number;
96
+ /**
97
+ * - **{@link NotificationPreference}**
98
+ *
99
+ * User Preference tied to the notification (the preference will be updated when the notification is marked read)
100
+ */
101
+ preference?: NotificationPreference;
102
+ }
37
103
 
38
104
  /**
39
105
  * Type for Encrypted Notification data that is stored in local storage
@@ -96,3 +162,48 @@ export interface NotificationHandler {
96
162
  */
97
163
  onReadUpdated(notification: Notification, read: boolean): void;
98
164
  }
165
+
166
+ /**
167
+ * API for notifications in the Rancher UI Notification Center
168
+ * * ![notification Example](/img/notification.png)
169
+ */
170
+ export interface NotificationApi {
171
+ /**
172
+ * Sends a notification to the Rancher UI Notification Center
173
+ *
174
+ * Example:
175
+ * ```ts
176
+ * import { NotificationLevel } from '@shell/types/notifications';
177
+ *
178
+ * this.$shell.notification.send(NotificationLevel.Success, 'Some notification title', 'Hello world! Success!', {})
179
+ * ```
180
+ *
181
+ * For usage with the Composition API check usage guide [here](../../shell-api#using-composition-api-in-vue).
182
+ *
183
+ * @param level The `level` specifies the importance of the notification and determines the icon that is shown in the notification
184
+ * @param title The notification title
185
+ * @param message The notification message to be displayed
186
+ * @param config Notifications configuration object
187
+ *
188
+ * @returns notification ID
189
+ *
190
+ */
191
+ send(level: NotificationLevel | NotificationLevel, title: string, message?:string, config?: NotificationConfig): Promise<string>;
192
+
193
+ /**
194
+ * Update notification progress (Only valid for notifications of type `Task`)
195
+ *
196
+ * Example:
197
+ * ```ts
198
+ * this.$shell.notification.updateProgress('some-notification-id', 80)
199
+ * ```
200
+ *
201
+ * For usage with the Composition API check usage guide [here](../../shell-api#using-composition-api-in-vue).
202
+ *
203
+ * @param notificationId Unique ID for the notification
204
+ * @param progress Progress (0-100) for notifications of type `Task`
205
+ *
206
+ */
207
+
208
+ updateProgress(notificationId: string, progress: number): void;
209
+ }
@@ -8,3 +8,12 @@ declare module '@shell/store/type-map' {
8
8
  }
9
9
 
10
10
  declare module '@shell/plugins/dashboard-store';
11
+
12
+ declare module '@shell/config/query-params' {
13
+ export const _DETAIL: string;
14
+ }
15
+
16
+ declare module '@shell/config/version' {
17
+ export const CURRENT_RANCHER_VERSION: string;
18
+ export function getVersionData(): any;
19
+ }
@@ -79,6 +79,7 @@ export namespace CATALOG {
79
79
  let _RANCHER: string;
80
80
  let _PARTNER: string;
81
81
  let _OTHER: string;
82
+ let PRIME_ONLY: string;
82
83
  let EXPERIMENTAL: string;
83
84
  let NAMESPACE: string;
84
85
  let RELEASE_NAME: string;
@@ -2206,6 +2207,12 @@ export namespace MANAGEMENT {
2206
2207
  export let CLUSTER_PROXY_CONFIG: string;
2207
2208
  export let OIDC_CLIENT: string;
2208
2209
  }
2210
+ export namespace BRAND {
2211
+ let SUSE: string;
2212
+ let CSP: string;
2213
+ let FEDERAL: string;
2214
+ let RGS: string;
2215
+ }
2209
2216
  export namespace EXT {
2210
2217
  let USER_ACTIVITY: string;
2211
2218
  }
@@ -2442,6 +2449,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2442
2449
  type: BooleanConstructor;
2443
2450
  default: any;
2444
2451
  };
2452
+ defaultTab: {
2453
+ type: StringConstructor;
2454
+ default: any;
2455
+ };
2445
2456
  }>, {}, {
2446
2457
  errors: any[];
2447
2458
  }, {
@@ -2499,6 +2510,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2499
2510
  type: BooleanConstructor;
2500
2511
  default: any;
2501
2512
  };
2513
+ defaultTab: {
2514
+ type: StringConstructor;
2515
+ default: any;
2516
+ };
2502
2517
  }>> & Readonly<{
2503
2518
  [x: `on${Capitalize<string>}`]: (...args: any[]) => any;
2504
2519
  }>, {
@@ -2509,6 +2524,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
2509
2524
  liveValue: Record<string, any>;
2510
2525
  realMode: string;
2511
2526
  useTabbedHash: boolean;
2527
+ defaultTab: string;
2512
2528
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2513
2529
  export default _default;
2514
2530
  }
@@ -3239,6 +3255,7 @@ export default class Resource {
3239
3255
  get $state(): any;
3240
3256
  get $rootState(): any;
3241
3257
  get $plugin(): any;
3258
+ get $extension(): any;
3242
3259
  get customValidationRules(): any[];
3243
3260
  get _key(): any;
3244
3261
  get schema(): any;
@@ -3315,7 +3332,7 @@ export default class Resource {
3315
3332
  weight: number;
3316
3333
  divider?: undefined;
3317
3334
  })[];
3318
- showConfiguration(returnFocusSelector: any): void;
3335
+ showConfiguration(returnFocusSelector: any, defaultTab: any): void;
3319
3336
  get _availableActions(): ({
3320
3337
  action: string;
3321
3338
  label: any;
@@ -3633,6 +3650,26 @@ export default class Resource {
3633
3650
  }
3634
3651
  }
3635
3652
 
3653
+ // @shell/plugins/i18n
3654
+
3655
+ declare module '@shell/plugins/i18n' {
3656
+ /**
3657
+ * @param {import('vuex').Store<any>} store
3658
+ * @param {string} key
3659
+ * @param {Record<string, any>} [args]
3660
+ * @param {boolean} [raw]
3661
+ * @param {boolean} [escapehtml]
3662
+ * @returns {string}
3663
+ */
3664
+ export function stringFor(store: import("vuex").Store<any>, key: string, args?: Record<string, any>, raw?: boolean, escapehtml?: boolean): string;
3665
+ export function directiveSsr(vnode: any, binding: any): void;
3666
+ export default i18n;
3667
+ declare namespace i18n {
3668
+ let name: string;
3669
+ function install(vueApp: any, _options: any): void;
3670
+ }
3671
+ }
3672
+
3636
3673
  // @shell/plugins/steve/hybrid-class
3637
3674
 
3638
3675
  declare module '@shell/plugins/steve/hybrid-class' {
@@ -4012,7 +4049,7 @@ export function filterHiddenLocalCluster(mgmtClusters: any, store: any): any;
4012
4049
  export function abbreviateClusterName(input: string): string;
4013
4050
  export function labelForAddon(store: any, name: any, configuration?: boolean): any;
4014
4051
  export function filterOutDeprecatedPatchVersions(allVersions: any, currentVersion: any): any;
4015
- export function getAllOptionsAfterCurrentVersion(store: any, versions: any, currentVersion: any, defaultVersion: any): any;
4052
+ export function getAllOptionsAfterCurrentVersion(store: any, versions: any, currentVersion: any, defaultVersion: any, manual?: boolean): any;
4016
4053
  export function initSchedulingCustomization(value: any, features: any, store: any, mode: any): Promise<{
4017
4054
  clusterAgentDefaultPC: any;
4018
4055
  clusterAgentDefaultPDB: any;
@@ -4083,7 +4120,7 @@ export function contrastColor(color: any, contrastOptions?: {
4083
4120
  dark: string;
4084
4121
  light: string;
4085
4122
  }): string;
4086
- export function parseColor(str: any): any;
4123
+ export function parseColor(str: any): import("color").ColorInstance;
4087
4124
  export function textColor(color: any): "black" | "white";
4088
4125
  export function hexToRgb(hex: any): {
4089
4126
  r: number;
@@ -4760,6 +4797,20 @@ export function queryParamsFor(current: any, qp: any, defaults?: {}): any;
4760
4797
  export function getClusterFromRoute(to: any): any;
4761
4798
  export function getProductFromRoute(to: any): any;
4762
4799
  export function findMeta(route: any, key: any): any;
4800
+ /**
4801
+ * Find a route definition given a routeName
4802
+ * @param {*} router VueRouter instance
4803
+ * @param {*} routeName the name we want to look up
4804
+ * @returns the route definition or undefined if it wasn't found
4805
+ */
4806
+ export function findRouteDefinitionByName(router: any, routeName: any): any;
4807
+ /**
4808
+ * Looks for the route definition and then ensures there's only valid params
4809
+ * @param {*} router VueRouter instance
4810
+ * @param {*} routeRecord an object conforming to the Route Record interface
4811
+ * @returns the passed in routeLocation with only valid params.
4812
+ */
4813
+ export function filterLocationValidParams(router: any, routeRecord: any): any;
4763
4814
  export function getPackageFromRoute(route: any): any;
4764
4815
  export function getResourceFromRoute(to: any): any;
4765
4816
  export function routeMatched(to: any, fn: any): boolean;