@rancher/shell 3.0.8-rc.9 → 3.0.9-rc.1

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 (154) hide show
  1. package/apis/impl/apis.ts +61 -0
  2. package/apis/index.ts +40 -0
  3. package/apis/intf/modal.ts +128 -0
  4. package/apis/intf/shell.ts +36 -0
  5. package/apis/intf/slide-in.ts +100 -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 +90 -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 +37 -0
  15. package/apis/shell/system.ts +65 -0
  16. package/apis/vue-shim.d.ts +11 -0
  17. package/assets/styles/global/_tooltip.scss +6 -1
  18. package/assets/translations/en-us.yaml +5 -0
  19. package/components/ActionMenuShell.vue +3 -1
  20. package/components/CruResource.vue +8 -1
  21. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +50 -1
  22. package/components/Drawer/ResourceDetailDrawer/composables.ts +19 -0
  23. package/components/Drawer/ResourceDetailDrawer/index.vue +3 -1
  24. package/components/LocaleSelector.vue +2 -2
  25. package/components/ModalManager.vue +11 -1
  26. package/components/Questions/__tests__/Yaml.test.ts +1 -1
  27. package/components/RelatedResources.vue +5 -0
  28. package/components/Resource/Detail/ResourcePopover/index.vue +5 -1
  29. package/components/ResourceDetail/Masthead/latest.vue +23 -21
  30. package/components/ResourceDetail/index.vue +3 -0
  31. package/components/ResourceTable.vue +54 -21
  32. package/components/SlideInPanelManager.vue +16 -11
  33. package/components/SortableTable/THead.vue +2 -1
  34. package/components/SortableTable/index.vue +20 -2
  35. package/components/Tabbed/index.vue +37 -2
  36. package/components/__tests__/NamespaceFilter.test.ts +49 -0
  37. package/components/auth/SelectPrincipal.vue +4 -0
  38. package/components/auth/login/ldap.vue +3 -3
  39. package/components/fleet/FleetSecretSelector.vue +1 -1
  40. package/components/form/KeyValue.vue +1 -1
  41. package/components/form/NameNsDescription.vue +1 -1
  42. package/components/form/NodeScheduling.vue +2 -2
  43. package/components/form/ResourceTabs/composable.ts +2 -2
  44. package/components/form/ResourceTabs/index.vue +0 -2
  45. package/components/form/__tests__/NameNsDescription.test.ts +42 -0
  46. package/components/formatter/LinkName.vue +5 -0
  47. package/components/nav/Group.vue +25 -7
  48. package/components/nav/Header.vue +1 -1
  49. package/components/nav/NamespaceFilter.vue +1 -0
  50. package/components/nav/Type.vue +17 -6
  51. package/components/nav/WindowManager/panels/TabBodyContainer.vue +1 -1
  52. package/components/nav/__tests__/Type.test.ts +59 -0
  53. package/composables/cruResource.ts +27 -0
  54. package/composables/focusTrap.ts +3 -1
  55. package/composables/resourceDetail.ts +15 -0
  56. package/composables/useLabeledFormElement.ts +3 -4
  57. package/config/product/fleet.js +1 -1
  58. package/config/router/navigation-guards/clusters.js +3 -3
  59. package/config/router/navigation-guards/products.js +1 -1
  60. package/config/router/routes.js +1 -5
  61. package/core/__tests__/extension-manager-impl.test.js +437 -0
  62. package/core/extension-manager-impl.js +6 -27
  63. package/core/plugin-helpers.ts +2 -2
  64. package/core/plugin.ts +9 -1
  65. package/core/plugins-loader.js +2 -2
  66. package/core/types-provisioning.ts +4 -0
  67. package/core/types.ts +35 -0
  68. package/detail/catalog.cattle.io.app.vue +1 -0
  69. package/detail/provisioning.cattle.io.cluster.vue +8 -6
  70. package/dialog/DeveloperLoadExtensionDialog.vue +1 -1
  71. package/dialog/MoveNamespaceDialog.vue +20 -4
  72. package/dialog/SearchDialog.vue +1 -0
  73. package/dialog/__tests__/MoveNamespaceDialog.test.ts +249 -0
  74. package/directives/__tests__/clean-tooltip.test.ts +298 -0
  75. package/directives/clean-tooltip.ts +234 -0
  76. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -2
  77. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +98 -1
  78. package/edit/fleet.cattle.io.helmop.vue +5 -0
  79. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +21 -21
  80. package/edit/provisioning.cattle.io.cluster/index.vue +5 -5
  81. package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -8
  82. package/edit/resources.cattle.io.restore.vue +1 -1
  83. package/edit/workload/Job.vue +2 -2
  84. package/edit/workload/__tests__/index.test.ts +123 -85
  85. package/edit/workload/index.vue +2 -2
  86. package/edit/workload/mixins/workload.js +19 -1
  87. package/initialize/install-plugins.js +4 -5
  88. package/machine-config/azure.vue +1 -1
  89. package/machine-config/components/GCEImage.vue +1 -1
  90. package/mixins/__tests__/brand.spec.ts +18 -13
  91. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +16 -0
  92. package/models/chart.js +70 -74
  93. package/models/management.cattle.io.cluster.js +1 -1
  94. package/models/provisioning.cattle.io.cluster.js +11 -3
  95. package/package.json +7 -7
  96. package/pages/auth/login.vue +3 -3
  97. package/pages/auth/setup.vue +1 -1
  98. package/pages/auth/verify.vue +3 -3
  99. package/pages/c/_cluster/apps/charts/index.vue +122 -24
  100. package/pages/c/_cluster/apps/charts/install.vue +33 -0
  101. package/pages/c/_cluster/explorer/__tests__/index.test.ts +1 -1
  102. package/pages/c/_cluster/fleet/index.vue +7 -10
  103. package/pages/c/_cluster/settings/index.vue +5 -0
  104. package/pkg/auto-import.js +3 -3
  105. package/pkg/dynamic-importer.lib.js +1 -1
  106. package/pkg/import.js +1 -1
  107. package/plugins/__tests__/mutations.tests.ts +179 -0
  108. package/plugins/dashboard-store/getters.js +1 -1
  109. package/plugins/dashboard-store/model-loader.js +1 -1
  110. package/plugins/dashboard-store/mutations.js +23 -2
  111. package/plugins/dashboard-store/resource-class.js +8 -3
  112. package/plugins/plugin.js +2 -2
  113. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +301 -128
  114. package/plugins/steve/mutations.js +9 -0
  115. package/plugins/steve/steve-class.js +1 -1
  116. package/plugins/steve/steve-pagination-utils.ts +108 -43
  117. package/plugins/steve/subscribe.js +23 -2
  118. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  119. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  120. package/rancher-components/RcDropdown/useDropdownContext.ts +2 -4
  121. package/rancher-components/RcItemCard/RcItemCard.vue +1 -1
  122. package/scripts/publish-shell.sh +25 -0
  123. package/store/__tests__/catalog.test.ts +1 -1
  124. package/store/__tests__/type-map.test.ts +164 -2
  125. package/store/auth.js +23 -11
  126. package/store/i18n.js +3 -3
  127. package/store/index.js +5 -3
  128. package/store/notifications.ts +2 -0
  129. package/store/prefs.js +2 -2
  130. package/store/type-map.js +17 -7
  131. package/types/internal-api/shell/modal.d.ts +6 -6
  132. package/types/notifications/index.ts +126 -15
  133. package/types/rancher/index.d.ts +9 -0
  134. package/types/shell/index.d.ts +16 -1
  135. package/types/store/dashboard-store.types.ts +29 -7
  136. package/types/vue-shim.d.ts +5 -4
  137. package/utils/__tests__/router.test.js +238 -0
  138. package/utils/cluster.js +4 -1
  139. package/utils/cspAdaptor.ts +32 -14
  140. package/utils/fleet.ts +8 -1
  141. package/utils/pagination-utils.ts +2 -2
  142. package/utils/pagination-wrapper.ts +4 -4
  143. package/utils/router.js +50 -0
  144. package/utils/unit-tests/pagination-utils.spec.ts +8 -8
  145. package/vue.config.js +3 -3
  146. package/composables/useExtensionManager.ts +0 -17
  147. package/core/__test__/extension-manager-impl.test.js +0 -236
  148. package/core/plugins.js +0 -38
  149. package/directives/clean-tooltip.js +0 -32
  150. package/plugins/internal-api/index.ts +0 -37
  151. package/plugins/internal-api/shared/base-api.ts +0 -13
  152. package/plugins/internal-api/shell/shell.api.ts +0 -108
  153. package/types/internal-api/shell/growl.d.ts +0 -25
  154. package/types/internal-api/shell/slideIn.d.ts +0 -15
@@ -1,236 +0,0 @@
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
- });
package/core/plugins.js DELETED
@@ -1,38 +0,0 @@
1
- import { throttle } from 'lodash';
2
- import { initExtensionManager } from './extension-manager-impl';
3
-
4
- export default function(context, inject) {
5
- const extensionManager = initExtensionManager(context);
6
- const deprecationMessage = '[DEPRECATED] `this.$plugin` is deprecated and will be removed in a future version. Use `this.$extension` instead.';
7
-
8
- inject('plugin', deprecationProxy(extensionManager, deprecationMessage));
9
- inject('extension', extensionManager);
10
- }
11
-
12
- /**
13
- * Proxy to log a deprecation warning when target is accessed. Only prints
14
- * deprecation warnings in dev builds.
15
- * @param {*} target the object to proxy
16
- * @param {*} message the deprecation warning to print to the console
17
- * @returns The proxied target that prints a deprecation warning when target is
18
- * accessed
19
- */
20
- const deprecationProxy = (target, message) => {
21
- const logWarning = throttle(() => {
22
- // eslint-disable-next-line no-console
23
- console.warn(message);
24
- }, 150);
25
-
26
- const deprecationHandler = {
27
- get(target, prop) {
28
- logWarning();
29
-
30
- return Reflect.get(target, prop);
31
- }
32
- };
33
-
34
- // an empty handler allows the proxy to behave just like the original target
35
- const proxyHandler = !!process.env.dev ? deprecationHandler : {};
36
-
37
- return new Proxy(target, proxyHandler);
38
- };
@@ -1,32 +0,0 @@
1
- import { VTooltip } from 'floating-vue';
2
- import { purifyHTML } from '@shell/plugins/clean-html';
3
-
4
- function purifyContent(value) {
5
- const type = typeof value;
6
-
7
- if (type === 'string') {
8
- return purifyHTML(value);
9
- } else if (value && type === 'object' && typeof value.content === 'string') {
10
- return { ...value, content: purifyHTML(value.content) };
11
- } else {
12
- return value;
13
- }
14
- }
15
-
16
- function beforeMount(el, { value, oldValue, modifiers }) {
17
- const purifiedValue = purifyContent(value);
18
-
19
- VTooltip.beforeMount(
20
- el,
21
- {
22
- value: purifiedValue, oldValue, modifiers
23
- });
24
- }
25
-
26
- const cleanTooltipDirective = {
27
- ...VTooltip,
28
- beforeMount,
29
- updated: beforeMount,
30
- };
31
-
32
- export default cleanTooltipDirective;
@@ -1,37 +0,0 @@
1
- import { Store } from 'vuex';
2
-
3
- interface PluginContext {
4
- store: Store<any>;
5
- [key: string]: any;
6
- }
7
-
8
- export default function(context: PluginContext, inject: (key: string, value: any) => void) {
9
- const { store } = context;
10
-
11
- // Load all API modules
12
- const apiContext = (require as any).context(
13
- '@shell/plugins/internal-api', // the base directory
14
- true, // whether to search subdirectories
15
- /\.api\.ts$/ // only .api.ts files
16
- );
17
-
18
- apiContext.keys().forEach((relativePath: string) => {
19
- const mod = apiContext(relativePath);
20
- const ApiClass = mod.default;
21
-
22
- if (typeof ApiClass === 'function') {
23
- // Check for a static `apiName` property, or fallback to filename
24
- let apiName: string = ApiClass.apiName();
25
-
26
- if (!apiName) {
27
- // fallback to filename (strip leading ‘./’ and extension)
28
- apiName = `$${ relativePath.replace(/^\.\//, '').replace(/\.\w+$/, '') }`;
29
- }
30
-
31
- const instance = new ApiClass(store);
32
-
33
- // The inject() method automatically adds the `$` prefix
34
- inject(apiName, instance);
35
- }
36
- });
37
- }
@@ -1,13 +0,0 @@
1
- export abstract class BaseApi {
2
- // The Vuex store, available to all API classes
3
- protected $store: any;
4
-
5
- // Documented requirement: each API should define its static apiName.
6
- static apiName(): string {
7
- throw new Error('apiName() static method has not been implemented');
8
- }
9
-
10
- constructor(store: any) {
11
- this.$store = store;
12
- }
13
- }
@@ -1,108 +0,0 @@
1
- import { GrowlConfig } from '@shell/types/internal-api/shell/growl';
2
- import { ModalConfig } from '@shell/types/internal-api/shell/modal';
3
- import { SlideInConfig } from '@shell/types/internal-api/shell/slideIn';
4
-
5
- import { BaseApi } from '@shell/plugins/internal-api/shared/base-api';
6
-
7
- export default class ShellApi extends BaseApi {
8
- static apiName() {
9
- return 'shell';
10
- }
11
-
12
- /**
13
- * Dispatches a growl notification.
14
- *
15
- * @param config - Configuration for the growl notification.
16
- * - If `message` is a string, it is treated as the main content of the notification.
17
- * - If `message` is a `DetailedMessage` object, `title` and `description` are extracted.
18
- *
19
- * Example:
20
- * ```ts
21
- * this.$shell.growl({ message: 'Operation successful!', type: 'success' });
22
- * this.$shell.growl({ message: { title: 'Warning', description: 'Check your input.' }, type: 'warning' });
23
- * ```
24
- */
25
- protected growl(config: GrowlConfig): void {
26
- const { type = 'error', timeout = 5000 } = config;
27
-
28
- let title = '';
29
- let description = '';
30
-
31
- if (typeof config.message === 'string') {
32
- description = config.message;
33
- } else {
34
- title = config.message.title || '';
35
- description = config.message.description;
36
- }
37
-
38
- this.$store.dispatch(
39
- `growl/${ type }`,
40
- {
41
- title,
42
- message: description,
43
- timeout,
44
- },
45
- { root: true }
46
- );
47
- }
48
-
49
- /**
50
- * Opens a modal by committing to the Vuex store.
51
- *
52
- * This method updates the store's `modal` module to show a modal with the
53
- * specified configuration. The modal is rendered using the `ModalManager` component,
54
- * and its content is dynamically loaded based on the `component` field in the configuration.
55
- *
56
- * @param config A `ModalConfig` object defining the modal’s content and behavior.
57
- *
58
- * Example:
59
- * ```ts
60
- * this.$shell.modal({
61
- * component: MyCustomModal,
62
- * componentProps: { title: 'Hello Modal' },
63
- * resources: [someResource],
64
- * modalWidth: '800px',
65
- * closeOnClickOutside: false
66
- * });
67
- * ```
68
- */
69
- protected modal(config: ModalConfig): void {
70
- this.$store.commit('modal/openModal', {
71
- component: config.component,
72
- componentProps: config.componentProps || {},
73
- resources: config.resources || [],
74
- modalWidth: config.modalWidth || '600px',
75
- closeOnClickOutside: config.closeOnClickOutside ?? true,
76
- // modalSticky: config.modalSticky ?? false // Not implemented yet
77
- });
78
- }
79
-
80
- /**
81
- * Opens the slide-in panel with the specified component and props.
82
- *
83
- * This method commits the `open` mutation to the `slideInPanel` Vuex module,
84
- * which sets the current component to be rendered and its associated props.
85
- * The slide-in panel becomes visible after the mutation.
86
- *
87
- * @param config - The configuration object for the slide-in panel.
88
- *
89
- * Example Usage:
90
- * ```ts
91
- * import MyComponent from '@/components/MyComponent.vue';
92
- *
93
- * this.$shell.slideInPanel({
94
- * component: MyComponent,
95
- * componentProps: { foo: 'bar' }
96
- * });
97
- * ```
98
- *
99
- * @param config.component - A Vue component (imported SFC, functional component, etc.) to be rendered in the panel.
100
- * @param config.componentProps - (Optional) Props to pass to the component. These should align with the component's defined props.
101
- */
102
- protected slideInPanel(config: SlideInConfig): void {
103
- this.$store.commit('slideInPanel/open', {
104
- component: config.component,
105
- componentProps: config.componentProps || {}
106
- });
107
- }
108
- }
@@ -1,25 +0,0 @@
1
- export interface DetailedMessage {
2
- title?: string;
3
- description: string;
4
- }
5
-
6
- export interface GrowlConfig {
7
- /**
8
- * The content of the notification message.
9
- * Either a simple string or an object with `title` and `description` for detailed notifications.
10
- */
11
- message: string | DetailedMessage;
12
-
13
- /**
14
- * Optional type of the growl notification.
15
- * Determines the visual style of the notification.
16
- * Defaults to `'error'` if not provided.
17
- */
18
- type?: 'success' | 'info' | 'warning' | 'error';
19
-
20
- /**
21
- * Optional duration (in milliseconds) for which the notification should be displayed.
22
- * Defaults to `5000` milliseconds. A value of `0` keeps the notification indefinitely.
23
- */
24
- timeout?: number;
25
- }
@@ -1,15 +0,0 @@
1
- import type { Component } from 'vue';
2
-
3
- /**
4
- * Configuration object for opening a slide-in panel.
5
- *
6
- * @property component - The Vue component to render in the slide-in panel.
7
- * This should be a valid Vue Component, such as an imported SFC or functional component.
8
- *
9
- * @property componentProps - (Optional) An object containing props to be passed to the component rendered in the slide-in panel.
10
- * Keys should match the props defined in the provided component.
11
- */
12
- export interface SlideInConfig {
13
- component: Component | null;
14
- componentProps?: Record<string, any>;
15
- }