@rancher/shell 3.0.8-rc.7 → 3.0.8-rc.9

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 (166) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -64
  2. package/assets/translations/en-us.yaml +9 -1
  3. package/components/BackLink.vue +8 -0
  4. package/components/BannerGraphic.vue +1 -5
  5. package/components/BrandImage.vue +17 -6
  6. package/components/Cron/CronExpressionEditor.vue +1 -1
  7. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  8. package/components/Drawer/Chrome.vue +2 -6
  9. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
  10. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
  11. package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
  12. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
  13. package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
  14. package/components/Drawer/types.ts +3 -0
  15. package/components/PaginatedResourceTable.vue +2 -6
  16. package/components/Questions/__tests__/index.test.ts +159 -0
  17. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  18. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  19. package/components/Resource/Detail/Metadata/composables.ts +9 -9
  20. package/components/Resource/Detail/Metadata/index.vue +3 -3
  21. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  22. package/components/Resource/Detail/composables.ts +12 -0
  23. package/components/Tabbed/__tests__/index.test.ts +86 -0
  24. package/components/auth/SelectPrincipal.vue +24 -6
  25. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  26. package/components/formatter/InternalExternalIP.vue +4 -1
  27. package/components/formatter/__tests__/InternalExternalIP.test.ts +1 -1
  28. package/components/nav/Header.vue +1 -2
  29. package/components/nav/TopLevelMenu.helper.ts +16 -6
  30. package/components/templates/standalone.vue +1 -1
  31. package/composables/useI18n.ts +10 -1
  32. package/config/__test__/uiplugins.test.ts +309 -0
  33. package/config/labels-annotations.js +1 -0
  34. package/config/product/explorer.js +3 -1
  35. package/config/router/routes.js +6 -2
  36. package/config/types.js +7 -0
  37. package/config/uiplugins.js +46 -2
  38. package/core/__test__/extension-manager-impl.test.js +236 -0
  39. package/core/extension-manager-impl.js +23 -6
  40. package/core/types-provisioning.ts +1 -1
  41. package/detail/provisioning.cattle.io.cluster.vue +1 -0
  42. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  43. package/dialog/RollbackWorkloadDialog.vue +2 -5
  44. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +2 -2
  45. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  46. package/edit/configmap.vue +1 -0
  47. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  48. package/edit/fleet.cattle.io.helmop.vue +6 -6
  49. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  50. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  51. package/edit/logging-flow/index.vue +1 -0
  52. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  53. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  54. package/edit/management.cattle.io.project.vue +1 -0
  55. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  56. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  57. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  58. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  59. package/edit/monitoring.coreos.com.route.vue +1 -1
  60. package/edit/namespace.vue +1 -0
  61. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  62. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  63. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  64. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  65. package/edit/node.vue +1 -0
  66. package/edit/persistentvolume/index.vue +27 -22
  67. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  68. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  69. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  70. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  71. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  72. package/edit/persistentvolume/plugins/csi.vue +18 -16
  73. package/edit/persistentvolume/plugins/fc.vue +13 -14
  74. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  75. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  76. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  77. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  78. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  79. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  80. package/edit/persistentvolume/plugins/local.vue +1 -3
  81. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  82. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  83. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  84. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  85. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  86. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  87. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  88. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  89. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  90. package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -0
  91. package/edit/secret/index.vue +1 -1
  92. package/edit/service.vue +1 -0
  93. package/edit/serviceaccount.vue +1 -0
  94. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  95. package/edit/workload/index.vue +2 -1
  96. package/edit/workload/mixins/workload.js +1 -1
  97. package/initialize/App.vue +4 -4
  98. package/initialize/install-plugins.js +17 -2
  99. package/machine-config/components/EC2Networking.vue +5 -2
  100. package/machine-config/components/__tests__/EC2Networking.test.ts +24 -0
  101. package/mixins/__tests__/brand.spec.ts +2 -2
  102. package/mixins/__tests__/chart.test.ts +21 -0
  103. package/mixins/brand.js +1 -7
  104. package/mixins/chart.js +7 -1
  105. package/mixins/create-edit-view/index.js +5 -0
  106. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  107. package/models/management.cattle.io.cluster.js +21 -3
  108. package/models/provisioning.cattle.io.cluster.js +21 -9
  109. package/package.json +5 -4
  110. package/pages/auth/login.vue +1 -3
  111. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  112. package/pages/c/_cluster/apps/charts/chart.vue +33 -15
  113. package/pages/c/_cluster/explorer/index.vue +8 -6
  114. package/pages/c/_cluster/manager/hostedprovider/index.vue +12 -6
  115. package/pages/c/_cluster/settings/brand.vue +1 -1
  116. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  117. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  118. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  119. package/pages/home.vue +5 -2
  120. package/pkg/dynamic-importer.lib.js +4 -0
  121. package/plugins/dashboard-client-init.js +3 -0
  122. package/plugins/dashboard-store/getters.js +18 -1
  123. package/plugins/dashboard-store/resource-class.js +4 -4
  124. package/plugins/i18n.js +8 -0
  125. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  126. package/plugins/steve/steve-pagination-utils.ts +39 -20
  127. package/plugins/steve/subscribe.js +17 -9
  128. package/plugins/subscribe-events.ts +4 -2
  129. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -42
  130. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  131. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  132. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  133. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  134. package/rancher-components/Pill/types.ts +0 -1
  135. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  136. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  137. package/rancher-components/RcIcon/index.ts +1 -0
  138. package/rancher-components/RcIcon/types.ts +160 -0
  139. package/rancher-components/utils/status.test.ts +67 -0
  140. package/rancher-components/utils/status.ts +77 -0
  141. package/scripts/typegen.sh +1 -0
  142. package/store/action-menu.js +8 -0
  143. package/store/auth.js +3 -3
  144. package/store/catalog.js +6 -0
  145. package/store/index.js +36 -17
  146. package/store/prefs.js +4 -5
  147. package/store/type-map.js +3 -3
  148. package/store/wm.ts +4 -4
  149. package/types/shell/index.d.ts +39 -2
  150. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  151. package/types/store/pagination.types.ts +157 -9
  152. package/types/store/subscribe-events.types.ts +8 -1
  153. package/types/store/subscribe.types.ts +1 -0
  154. package/utils/__tests__/provider.test.ts +98 -0
  155. package/utils/__tests__/selector-typed.test.ts +263 -0
  156. package/utils/__tests__/version.test.ts +19 -1
  157. package/utils/back-off.ts +3 -3
  158. package/utils/color.js +1 -1
  159. package/utils/dynamic-content/__tests__/info.test.ts +21 -9
  160. package/utils/dynamic-content/info.ts +44 -2
  161. package/utils/favicon.js +4 -4
  162. package/utils/pagination-wrapper.ts +12 -8
  163. package/utils/provider.ts +14 -0
  164. package/utils/selector-typed.ts +6 -2
  165. package/utils/version.js +15 -0
  166. package/plugins/nuxt-client-init.js +0 -3
@@ -0,0 +1,236 @@
1
+ import { DEVELOPER_LOAD_NAME_SUFFIX } from '@shell/core/extension-manager-impl';
2
+
3
+ // Mock external dependencies
4
+ jest.mock('@shell/store/type-map', () => ({ productsLoaded: jest.fn().mockReturnValue(true) }));
5
+
6
+ jest.mock('@shell/plugins/dashboard-store/model-loader', () => ({ clearModelCache: jest.fn() }));
7
+
8
+ jest.mock('@shell/config/uiplugins', () => ({ UI_PLUGIN_BASE_URL: '/api/v1/uiplugins' }));
9
+
10
+ jest.mock('@shell/plugins/clean-html', () => ({
11
+ addLinkInterceptor: jest.fn(),
12
+ removeLinkInterceptor: jest.fn(),
13
+ }));
14
+
15
+ // Mock the Plugin class
16
+ jest.mock('@shell/core/plugin', () => {
17
+ return {
18
+ Plugin: jest.fn().mockImplementation((id) => ({
19
+ id,
20
+ name: id,
21
+ types: {},
22
+ uiConfig: {},
23
+ l10n: {},
24
+ modelExtensions: {},
25
+ stores: [],
26
+ locales: [],
27
+ routes: [],
28
+ validators: {},
29
+ uninstallHooks: [],
30
+ productNames: [],
31
+ })),
32
+ EXT_IDS: {
33
+ MODELS: 'models',
34
+ MODEL_EXTENSION: 'model-extension'
35
+ },
36
+ ExtensionPoint: { EDIT_YAML: 'edit-yaml' }
37
+ };
38
+ });
39
+
40
+ // Mock PluginRoutes
41
+ jest.mock('@shell/core/plugin-routes', () => {
42
+ return { PluginRoutes: jest.fn().mockImplementation(() => ({ addRoutes: jest.fn() })) };
43
+ });
44
+
45
+ describe('extension Manager', () => {
46
+ let mockStore;
47
+ let mockApp;
48
+ let context;
49
+
50
+ // These variables will be assigned the fresh functions inside beforeEach
51
+ let initExtensionManager;
52
+ let getExtensionManager;
53
+
54
+ beforeEach(() => {
55
+ // singleton instance for every test run, preventing mock store leaks.
56
+ jest.resetModules();
57
+
58
+ // Re-require the System Under Test (SUT)
59
+ const extensionManagerModule = require('../extension-manager-impl');
60
+
61
+ initExtensionManager = extensionManagerModule.initExtensionManager;
62
+ getExtensionManager = extensionManagerModule.getExtensionManager;
63
+
64
+ jest.clearAllMocks();
65
+
66
+ // Setup Mock Context
67
+ mockStore = {
68
+ getters: { 'i18n/t': jest.fn() },
69
+ dispatch: jest.fn(),
70
+ commit: jest.fn(),
71
+ };
72
+
73
+ mockApp = { router: {} };
74
+
75
+ context = {
76
+ app: mockApp,
77
+ store: mockStore,
78
+ $axios: {},
79
+ redirect: jest.fn(),
80
+ };
81
+
82
+ // Clean up DOM from previous tests
83
+ document.head.innerHTML = '';
84
+ });
85
+
86
+ describe('singleton Pattern', () => {
87
+ it('initializes and returns the same instance', () => {
88
+ const instance1 = initExtensionManager(context);
89
+ const instance2 = getExtensionManager();
90
+ const instance3 = initExtensionManager(context);
91
+
92
+ expect(instance1).toBeDefined();
93
+ expect(instance1).toBe(instance2);
94
+ expect(instance1).toBe(instance3);
95
+ });
96
+ });
97
+
98
+ describe('registration (Dynamic)', () => {
99
+ it('registers and retrieves a dynamic component', () => {
100
+ const manager = initExtensionManager(context);
101
+ const mockFn = jest.fn();
102
+
103
+ manager.register('component', 'my-component', mockFn);
104
+
105
+ const retrieved = manager.getDynamic('component', 'my-component');
106
+
107
+ expect(retrieved).toBe(mockFn);
108
+ });
109
+
110
+ it('unregisters a dynamic component', () => {
111
+ const manager = initExtensionManager(context);
112
+ const mockFn = jest.fn();
113
+
114
+ manager.register('component', 'my-component', mockFn);
115
+ manager.unregister('component', 'my-component');
116
+
117
+ const retrieved = manager.getDynamic('component', 'my-component');
118
+
119
+ expect(retrieved).toBeUndefined();
120
+ });
121
+ });
122
+
123
+ describe('loadPluginAsync (URL Generation)', () => {
124
+ let manager;
125
+
126
+ beforeEach(() => {
127
+ manager = initExtensionManager(context);
128
+ // Mock the internal loadAsync so we only test URL generation here
129
+ jest.spyOn(manager, 'loadAsync').mockImplementation().mockResolvedValue();
130
+ });
131
+
132
+ it('generates correct URL for standard plugin', async() => {
133
+ const pluginData = { name: 'elemental', version: '1.0.0' };
134
+ const expectedId = 'elemental-1.0.0';
135
+ const expectedUrl = `/api/v1/uiplugins/elemental/1.0.0/plugin/elemental-1.0.0.umd.min.js`;
136
+
137
+ await manager.loadPluginAsync(pluginData);
138
+
139
+ expect(manager.loadAsync).toHaveBeenCalledWith(expectedId, expectedUrl);
140
+ });
141
+
142
+ it('handles "direct" metadata plugins', async() => {
143
+ const pluginData = {
144
+ name: 'direct-plugin',
145
+ version: '1.0.0',
146
+ endpoint: 'http://localhost:8000/plugin.js',
147
+ metadata: { direct: 'true' }
148
+ };
149
+
150
+ await manager.loadPluginAsync(pluginData);
151
+
152
+ expect(manager.loadAsync).toHaveBeenCalledWith('direct-plugin-1.0.0', 'http://localhost:8000/plugin.js');
153
+ });
154
+
155
+ it('removes developer suffix from ID but keeps it for internal logic', async() => {
156
+ const pluginData = {
157
+ name: `my-plugin${ DEVELOPER_LOAD_NAME_SUFFIX }`,
158
+ version: `1.0.0`
159
+ };
160
+
161
+ await manager.loadPluginAsync(pluginData);
162
+
163
+ // Expected ID passed to loadAsync should NOT have the suffix
164
+ const expectedIdWithoutSuffix = 'my-plugin-1.0.0';
165
+
166
+ expect(manager.loadAsync).toHaveBeenCalledWith(
167
+ expectedIdWithoutSuffix,
168
+ expect.any(String)
169
+ );
170
+ });
171
+ });
172
+
173
+ describe('loadAsync (Script Injection)', () => {
174
+ let manager;
175
+
176
+ beforeEach(() => {
177
+ manager = initExtensionManager(context);
178
+ });
179
+
180
+ it('resolves immediately if element already exists', async() => {
181
+ const id = 'existing-plugin';
182
+ const script = document.createElement('script');
183
+
184
+ script.id = id;
185
+ document.body.appendChild(script);
186
+
187
+ await expect(manager.loadAsync(id, 'url.js')).resolves.toBeUndefined();
188
+
189
+ document.body.removeChild(script);
190
+ });
191
+
192
+ it('injects script tag and initializes plugin on load', async() => {
193
+ const pluginId = 'test-plugin';
194
+ const pluginUrl = 'http://test.com/plugin.js';
195
+
196
+ // Mock the window object to simulate the plugin loading into global scope
197
+ const mockPluginInit = jest.fn();
198
+
199
+ window[pluginId] = { default: mockPluginInit };
200
+
201
+ // Start the load
202
+ const loadPromise = manager.loadAsync(pluginId, pluginUrl);
203
+
204
+ // Find the injected script tag in the DOM
205
+ const script = document.head.querySelector(`script[id="${ pluginId }"]`);
206
+
207
+ expect(script).toBeTruthy();
208
+ expect(script.src).toBe(pluginUrl);
209
+
210
+ // Manually trigger the onload event
211
+ script.onload();
212
+
213
+ // Await the promise
214
+ await loadPromise;
215
+
216
+ // Assertions
217
+ expect(mockPluginInit).toHaveBeenCalledWith(expect.objectContaining({ id: pluginId }), expect.objectContaining({ ...context }));
218
+ expect(mockStore.dispatch).toHaveBeenCalledWith('uiplugins/addPlugin', expect.objectContaining({ id: pluginId }));
219
+
220
+ // Cleanup
221
+ delete window[pluginId];
222
+ });
223
+
224
+ it('rejects if script load fails', async() => {
225
+ const pluginId = 'fail-plugin';
226
+ const loadPromise = manager.loadAsync(pluginId, 'bad-url.js');
227
+
228
+ const script = document.head.querySelector(`script[id="${ pluginId }"]`);
229
+
230
+ // Trigger error
231
+ script.onerror({ target: { src: 'bad-url.js' } });
232
+
233
+ await expect(loadPromise).rejects.toThrow('Failed to load script');
234
+ });
235
+ });
236
+ });
@@ -6,6 +6,8 @@ import { UI_PLUGIN_BASE_URL } from '@shell/config/uiplugins';
6
6
  import { ExtensionPoint } from './types';
7
7
  import { addLinkInterceptor, removeLinkInterceptor } from '@shell/plugins/clean-html';
8
8
 
9
+ export const DEVELOPER_LOAD_NAME_SUFFIX = '-developer-load';
10
+
9
11
  let extensionManagerInstance;
10
12
 
11
13
  const createExtensionManager = (context) => {
@@ -35,11 +37,11 @@ const createExtensionManager = (context) => {
35
37
  */
36
38
  function instantiateModelExtension($plugin, clz) {
37
39
  const context = {
38
- dispatch: store.dispatch,
39
- getters: store.getters,
40
- t: store.getters['i18n/t'],
40
+ dispatch: store.dispatch,
41
+ getters: store.getters,
42
+ t: store.getters['i18n/t'],
41
43
  $axios,
42
- $plugin,
44
+ $extension: $plugin,
43
45
  };
44
46
 
45
47
  return new clz(context);
@@ -63,9 +65,18 @@ const createExtensionManager = (context) => {
63
65
  // Load a plugin from a UI package
64
66
  loadPluginAsync(plugin) {
65
67
  const { name, version } = plugin;
66
- const id = `${ name }-${ version }`;
68
+ let id = `${ name }-${ version }`;
67
69
  let url;
68
70
 
71
+ // for a developer load, we need to remove the suffix applied
72
+ // otherwise the extension won't load correctly
73
+ // but with this at least we won't hit developer loaded cards find charts
74
+ // when they aren't supposed to
75
+ if (id.includes(DEVELOPER_LOAD_NAME_SUFFIX)) {
76
+ id = id.replace(DEVELOPER_LOAD_NAME_SUFFIX, '');
77
+ }
78
+
79
+ // this is where a developer load hits (direct=true, developer=true)
69
80
  if (plugin?.metadata?.direct === 'true') {
70
81
  url = plugin.endpoint;
71
82
  } else {
@@ -455,7 +466,13 @@ const createExtensionManager = (context) => {
455
466
  try {
456
467
  const provisioner = context.$extension.getDynamic('provisioner', name);
457
468
 
458
- return new provisioner({ ...context });
469
+ const defaults = {
470
+ isCreate: false,
471
+ isEdit: false,
472
+ isView: false
473
+ };
474
+
475
+ return new provisioner({ ...defaults, ...context });
459
476
  } catch (e) {
460
477
  console.error('Error loading provisioner(s) from extensions', e); // eslint-disable-line no-console
461
478
  }
@@ -63,7 +63,7 @@ export interface ClusterProvisionerContext {
63
63
  /**
64
64
  * Definition of the extension
65
65
  */
66
- $plugin: any,
66
+ $extension: any,
67
67
  /**
68
68
  * Function to retrieve a localised string
69
69
  */
@@ -578,6 +578,7 @@ export default {
578
578
  // Hosted kubernetes providers with private endpoints need the registration tab
579
579
  // https://github.com/rancher/dashboard/issues/6036
580
580
  // https://github.com/rancher/dashboard/issues/4545
581
+
581
582
  if ( this.value.isHostedKubernetesProvider && this.value.isPrivateHostedProvider && !this.isClusterReady ) {
582
583
  return this.extDetailTabs.registration;
583
584
  }
@@ -4,6 +4,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
4
4
  import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
5
5
  import { UI_PLUGIN } from '@shell/config/types';
6
6
  import { UI_PLUGIN_CHART_ANNOTATIONS, UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
7
+ import { DEVELOPER_LOAD_NAME_SUFFIX } from '@shell/core/extension-manager-impl';
7
8
 
8
9
  export default {
9
10
  emits: ['close'],
@@ -101,8 +102,16 @@ export default {
101
102
  const parts = name.split('-');
102
103
 
103
104
  if (parts.length >= 2) {
104
- version = parts.pop();
105
- crdName = parts.join('-');
105
+ // fixing the name-version separation, especially in RC versions
106
+ // like: elemental-3.0.1-rc.1
107
+ // on capturing version it must be "digit + dot + digit" + rest of string
108
+ const regex = /^(?<name>.+?)-(?<version>\d+\.\d+.*)$/;
109
+ const match = name.match(regex);
110
+
111
+ if (match && match.groups) {
112
+ version = match.groups.version;
113
+ crdName = match.groups.name;
114
+ }
106
115
  }
107
116
 
108
117
  if (this.persist) {
@@ -114,7 +123,7 @@ export default {
114
123
  },
115
124
  spec: {
116
125
  plugin: {
117
- name: crdName,
126
+ name: `${ crdName }${ DEVELOPER_LOAD_NAME_SUFFIX }`,
118
127
  version,
119
128
  endpoint: url,
120
129
  noCache: true,
@@ -165,12 +165,9 @@ export default {
165
165
  return option.label;
166
166
  },
167
167
  sizeDialog() {
168
- const dialogs = document.getElementsByClassName('modal-container');
169
- const width = this.showDiff ? '85%' : '600px';
168
+ const modalWidth = this.showDiff ? '85%' : '600px';
170
169
 
171
- if (dialogs.length === 1) {
172
- dialogs[0].style.setProperty('width', width);
173
- }
170
+ this.$store.commit('action-menu/updateModalData', [{ key: 'modalWidth', value: modalWidth }]);
174
171
  },
175
172
  sanitizeYaml(obj, path = '') {
176
173
  const res = {};
@@ -243,7 +243,7 @@ describe.each([
243
243
 
244
244
  await fleetSecretSelector.vm.$emit('update:value', ['secret2', 'secret3']);
245
245
 
246
- expect(wrapper.vm.value.spec.helm.downstreamResources).toStrictEqual([{ name: 'secret2', kind: 'Secret' }, { name: 'secret3', kind: 'Secret' }]);
246
+ expect(wrapper.vm.value.spec.downstreamResources).toStrictEqual([{ name: 'secret2', kind: 'Secret' }, { name: 'secret3', kind: 'Secret' }]);
247
247
  });
248
248
 
249
249
  it('should update downstreamResources with new ConfigMaps when FleetConfigMapSelector emits update event', async() => {
@@ -260,6 +260,6 @@ describe.each([
260
260
 
261
261
  await fleetConfigMapSelector.vm.$emit('update:value', ['configMap2', 'configMap3']);
262
262
 
263
- expect(wrapper.vm.value.spec.helm.downstreamResources).toStrictEqual([{ name: 'configMap2', kind: 'ConfigMap' }, { name: 'configMap3', kind: 'ConfigMap' }]);
263
+ expect(wrapper.vm.value.spec.downstreamResources).toStrictEqual([{ name: 'configMap2', kind: 'ConfigMap' }, { name: 'configMap3', kind: 'ConfigMap' }]);
264
264
  });
265
265
  });
@@ -209,6 +209,7 @@ export default {
209
209
  <Tabbed
210
210
  :side-tabs="true"
211
211
  :use-hash="useTabbedHash"
212
+ :default-tab="defaultTab"
212
213
  >
213
214
  <Tab
214
215
  name="target"
@@ -111,6 +111,7 @@ export default {
111
111
  <Tabbed
112
112
  :side-tabs="true"
113
113
  :use-hash="useTabbedHash"
114
+ :default-tab="defaultTab"
114
115
  >
115
116
  <Tab
116
117
  name="data"
@@ -278,6 +278,7 @@ export default {
278
278
  <Tabbed
279
279
  :side-tabs="true"
280
280
  :use-hash="useTabbedHash"
281
+ :default-tab="defaultTab"
281
282
  @changed="onTabChanged"
282
283
  >
283
284
  <Tab
@@ -237,11 +237,11 @@ export default {
237
237
  },
238
238
 
239
239
  downstreamSecretsList() {
240
- return (this.value.spec.helm.downstreamResources || []).filter((r) => r.kind === 'Secret').map((r) => r.name);
240
+ return (this.value.spec.downstreamResources || []).filter((r) => r.kind === 'Secret').map((r) => r.name);
241
241
  },
242
242
 
243
243
  downstreamConfigMapsList() {
244
- return (this.value.spec.helm.downstreamResources || []).filter((r) => r.kind === 'ConfigMap').map((r) => r.name);
244
+ return (this.value.spec.downstreamResources || []).filter((r) => r.kind === 'ConfigMap').map((r) => r.name);
245
245
  },
246
246
  },
247
247
 
@@ -446,14 +446,14 @@ export default {
446
446
  updateDownstreamResources(kind, list) {
447
447
  switch (kind) {
448
448
  case 'Secret':
449
- this.value.spec.helm.downstreamResources = [
450
- ...(this.value.spec.helm.downstreamResources || []).filter((r) => r.kind !== 'Secret'),
449
+ this.value.spec.downstreamResources = [
450
+ ...(this.value.spec.downstreamResources || []).filter((r) => r.kind !== 'Secret'),
451
451
  ...(list || []).map((name) => ({ name, kind: 'Secret' })),
452
452
  ];
453
453
  break;
454
454
  case 'ConfigMap':
455
- this.value.spec.helm.downstreamResources = [
456
- ...(this.value.spec.helm.downstreamResources || []).filter((r) => r.kind !== 'ConfigMap'),
455
+ this.value.spec.downstreamResources = [
456
+ ...(this.value.spec.downstreamResources || []).filter((r) => r.kind !== 'ConfigMap'),
457
457
  ...(list || []).map((name) => ({ name, kind: 'ConfigMap' })),
458
458
  ];
459
459
  break;
@@ -143,6 +143,7 @@ export default {
143
143
  ref="tabs"
144
144
  :side-tabs="true"
145
145
  :use-hash="useTabbedHash"
146
+ :default-tab="defaultTab"
146
147
  >
147
148
  <Questions
148
149
  v-model:value="value.spec.values"
@@ -74,6 +74,7 @@ export default {
74
74
  class="mt-15"
75
75
  :side-tabs="true"
76
76
  :use-hash="useTabbedHash"
77
+ :default-tab="defaultTab"
77
78
  >
78
79
  <Tab
79
80
  name="basics"
@@ -405,6 +405,7 @@ export default {
405
405
  <Tabbed
406
406
  :side-tabs="true"
407
407
  :use-hash="useTabbedHash"
408
+ :default-tab="defaultTab"
408
409
  @changed="tabChanged($event)"
409
410
  >
410
411
  <Tab
@@ -212,6 +212,7 @@ export default {
212
212
  ref="tabbed"
213
213
  :side-tabs="true"
214
214
  :use-hash="useTabbedHash"
215
+ :default-tab="defaultTab"
215
216
  @changed="tabChanged($event)"
216
217
  >
217
218
  <Tab
@@ -199,7 +199,7 @@ export default {
199
199
 
200
200
  <Tabbed
201
201
  :side-tabs="true"
202
- default-tab="members"
202
+ :default-tab="defaultTab || 'members'"
203
203
  :use-hash="useTabbedHash"
204
204
  >
205
205
  <!-- <Tab name="members" label-key="generic.members" :weight="2">
@@ -198,6 +198,7 @@ export default {
198
198
  <Tabbed
199
199
  :side-tabs="true"
200
200
  :use-hash="useTabbedHash"
201
+ :default-tab="defaultTab"
201
202
  >
202
203
  <Tab
203
204
  v-if="canViewMembers"
@@ -204,7 +204,10 @@ export default {
204
204
  @input="$emit('input', $event)"
205
205
  />
206
206
 
207
- <Tabbed :use-hash="useTabbedHash">
207
+ <Tabbed
208
+ :use-hash="useTabbedHash"
209
+ :default-tab="defaultTab"
210
+ >
208
211
  <Tab
209
212
  :label="t('monitoring.route.label')"
210
213
  :weight="1"
@@ -313,8 +313,9 @@ export default {
313
313
  <Tabbed
314
314
  ref="tabbed"
315
315
  :side-tabs="true"
316
- default-tab="overview"
316
+ :default-tab="defaultTab || 'overview'"
317
317
  :use-hash="useTabbedHash"
318
+
318
319
  @changed="tabChanged"
319
320
  >
320
321
  <Tab
@@ -155,6 +155,7 @@ export default {
155
155
  :side-tabs="true"
156
156
  :show-tabs-add-remove="mode !== 'view'"
157
157
  :use-hash="useTabbedHash"
158
+ :default-tab="defaultTab"
158
159
  @addTab="addRuleGroup"
159
160
  @removeTab="removeGroupRule"
160
161
  >
@@ -218,8 +218,9 @@ export default {
218
218
  <Tabbed
219
219
  ref="tabbed"
220
220
  :side-tabs="true"
221
- default-tab="overview"
221
+ :default-tab="defaultTab || 'overview'"
222
222
  :use-hash="useTabbedHash"
223
+
223
224
  @changed="tabChanged"
224
225
  >
225
226
  <Tab
@@ -102,7 +102,7 @@ export default {
102
102
  <Tabbed
103
103
  ref="tabbed"
104
104
  :side-tabs="true"
105
- default-tab="overview"
105
+ :default-tab="defaultTab || 'overview'"
106
106
  :use-hash="useTabbedHash"
107
107
  >
108
108
  <Tab
@@ -203,6 +203,7 @@ export default {
203
203
  :mode="mode"
204
204
  :side-tabs="true"
205
205
  :use-hash="useTabbedHash"
206
+ :default-tab="defaultTab"
206
207
  @update:value="$emit('input', $event)"
207
208
  >
208
209
  <Tab
@@ -69,6 +69,7 @@ export default {
69
69
  <Tabbed
70
70
  :side-tabs="true"
71
71
  :use-hash="useTabbedHash"
72
+ :default-tab="defaultTab"
72
73
  >
73
74
  <Tab
74
75
  name="subsets"
@@ -229,6 +229,7 @@ export default {
229
229
  <Tabbed
230
230
  :side-tabs="true"
231
231
  :use-hash="useTabbedHash"
232
+ :default-tab="defaultTab"
232
233
  >
233
234
  <Tab
234
235
  :label="firstTabLabel"
@@ -59,6 +59,7 @@ export default {
59
59
  :side-tabs="true"
60
60
  :show-tabs-add-remove="mode !== 'view'"
61
61
  :use-hash="useTabbedHash"
62
+ :default-tab="defaultTab"
62
63
  @addTab="addPolicyRule"
63
64
  @removeTab="removePolicyRule"
64
65
  >
@@ -178,6 +178,7 @@ export default {
178
178
  <Tabbed
179
179
  :side-tabs="true"
180
180
  :use-hash="useTabbedHash"
181
+ :default-tab="defaultTab"
181
182
  >
182
183
  <Tab
183
184
  name="ingress"
package/edit/node.vue CHANGED
@@ -51,6 +51,7 @@ export default {
51
51
  :value="value"
52
52
  :mode="mode"
53
53
  :use-hash="useTabbedHash"
54
+ :default-tab="defaultTab"
54
55
  @update:value="$emit('input', $event)"
55
56
  >
56
57
  <Tab