@rancher/shell 3.0.8-rc.10 → 3.0.8-rc.13
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.
- package/apis/impl/apis.ts +61 -0
- package/apis/index.ts +40 -0
- package/apis/intf/modal.ts +90 -0
- package/apis/intf/shell.ts +36 -0
- package/apis/intf/slide-in.ts +98 -0
- package/apis/intf/system.ts +34 -0
- package/apis/shell/__tests__/modal.test.ts +80 -0
- package/apis/shell/__tests__/notifications.test.ts +71 -0
- package/apis/shell/__tests__/slide-in.test.ts +54 -0
- package/apis/shell/__tests__/system.test.ts +129 -0
- package/apis/shell/index.ts +38 -0
- package/apis/shell/modal.ts +41 -0
- package/apis/shell/notifications.ts +65 -0
- package/apis/shell/slide-in.ts +33 -0
- package/apis/shell/system.ts +65 -0
- package/apis/vue-shim.d.ts +11 -0
- package/components/CruResource.vue +8 -1
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +50 -1
- package/components/Drawer/ResourceDetailDrawer/composables.ts +19 -0
- package/components/Drawer/ResourceDetailDrawer/index.vue +3 -1
- package/components/ModalManager.vue +11 -1
- package/components/ResourceDetail/index.vue +3 -0
- package/components/ResourceTable.vue +54 -21
- package/components/SlideInPanelManager.vue +16 -11
- package/components/SortableTable/index.vue +20 -2
- package/components/Tabbed/index.vue +37 -2
- package/components/auth/login/ldap.vue +3 -3
- package/components/form/NodeScheduling.vue +2 -2
- package/components/form/ResourceTabs/composable.ts +2 -2
- package/components/nav/Group.vue +9 -2
- package/components/nav/Header.vue +1 -1
- package/components/nav/Type.vue +8 -3
- package/components/nav/__tests__/Type.test.ts +59 -0
- package/composables/cruResource.ts +27 -0
- package/composables/focusTrap.ts +3 -1
- package/composables/resourceDetail.ts +15 -0
- package/config/router/navigation-guards/clusters.js +3 -3
- package/config/router/navigation-guards/products.js +1 -1
- package/core/__tests__/extension-manager-impl.test.js +437 -0
- package/core/extension-manager-impl.js +6 -27
- package/core/plugin-helpers.ts +2 -2
- package/core/plugin.ts +9 -1
- package/core/plugins-loader.js +2 -2
- package/core/types-provisioning.ts +4 -0
- package/core/types.ts +35 -0
- package/detail/provisioning.cattle.io.cluster.vue +8 -6
- package/dialog/DeveloperLoadExtensionDialog.vue +1 -1
- package/dialog/SearchDialog.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +21 -21
- package/edit/provisioning.cattle.io.cluster/index.vue +5 -5
- package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -8
- package/edit/workload/index.vue +1 -1
- package/initialize/install-plugins.js +4 -5
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/provisioning.cattle.io.cluster.js +1 -1
- package/package.json +3 -3
- package/pages/auth/login.vue +3 -3
- package/pages/auth/setup.vue +1 -1
- package/pages/auth/verify.vue +3 -3
- package/pages/c/_cluster/apps/charts/install.vue +33 -0
- package/pages/c/_cluster/fleet/index.vue +4 -7
- package/pkg/auto-import.js +3 -3
- package/pkg/dynamic-importer.lib.js +1 -1
- package/pkg/import.js +1 -1
- package/plugins/dashboard-store/getters.js +1 -1
- package/plugins/dashboard-store/model-loader.js +1 -1
- package/plugins/dashboard-store/resource-class.js +6 -2
- package/plugins/plugin.js +2 -2
- package/plugins/steve/__tests__/steve-pagination-utils.test.ts +301 -128
- package/plugins/steve/steve-class.js +1 -1
- package/plugins/steve/steve-pagination-utils.ts +108 -43
- package/scripts/publish-shell.sh +25 -0
- package/store/__tests__/catalog.test.ts +1 -1
- package/store/__tests__/type-map.test.ts +164 -2
- package/store/auth.js +1 -1
- package/store/i18n.js +3 -3
- package/store/index.js +5 -3
- package/store/notifications.ts +2 -0
- package/store/type-map.js +14 -5
- package/types/internal-api/shell/modal.d.ts +6 -6
- package/types/notifications/index.ts +126 -15
- package/types/rancher/index.d.ts +9 -0
- package/types/shell/index.d.ts +1 -0
- package/types/vue-shim.d.ts +5 -4
- package/utils/pagination-utils.ts +2 -2
- package/utils/pagination-wrapper.ts +1 -1
- package/utils/unit-tests/pagination-utils.spec.ts +8 -8
- package/vue.config.js +3 -3
- package/composables/useExtensionManager.ts +0 -17
- package/core/__test__/extension-manager-impl.test.js +0 -236
- package/core/plugins.js +0 -38
- package/plugins/internal-api/index.ts +0 -37
- package/plugins/internal-api/shared/base-api.ts +0 -13
- package/plugins/internal-api/shell/shell.api.ts +0 -108
- package/types/internal-api/shell/growl.d.ts +0 -25
- package/types/internal-api/shell/slideIn.d.ts +0 -15
|
@@ -112,8 +112,8 @@ describe('component: rke2', () => {
|
|
|
112
112
|
global: {
|
|
113
113
|
mocks: {
|
|
114
114
|
...defaultMocks,
|
|
115
|
-
$store:
|
|
116
|
-
$
|
|
115
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
116
|
+
$extension: { getDynamic: jest.fn(() => undefined ) }
|
|
117
117
|
},
|
|
118
118
|
|
|
119
119
|
stubs: defaultStubs,
|
|
@@ -143,8 +143,8 @@ describe('component: rke2', () => {
|
|
|
143
143
|
global: {
|
|
144
144
|
mocks: {
|
|
145
145
|
...defaultMocks,
|
|
146
|
-
$store:
|
|
147
|
-
$
|
|
146
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
147
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
148
148
|
},
|
|
149
149
|
|
|
150
150
|
stubs: defaultStubs,
|
|
@@ -174,8 +174,8 @@ describe('component: rke2', () => {
|
|
|
174
174
|
global: {
|
|
175
175
|
mocks: {
|
|
176
176
|
...defaultMocks,
|
|
177
|
-
$store:
|
|
178
|
-
$
|
|
177
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
178
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
179
179
|
},
|
|
180
180
|
|
|
181
181
|
stubs: defaultStubs,
|
|
@@ -231,7 +231,7 @@ describe('component: rke2', () => {
|
|
|
231
231
|
},
|
|
232
232
|
getters: defaultGetters
|
|
233
233
|
},
|
|
234
|
-
$
|
|
234
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
235
235
|
},
|
|
236
236
|
|
|
237
237
|
stubs: defaultStubs,
|
|
@@ -275,7 +275,7 @@ describe('component: rke2', () => {
|
|
|
275
275
|
'management/findAll': () => ([]),
|
|
276
276
|
}
|
|
277
277
|
},
|
|
278
|
-
$
|
|
278
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
279
279
|
},
|
|
280
280
|
|
|
281
281
|
stubs: defaultStubs,
|
|
@@ -324,7 +324,7 @@ describe('component: rke2', () => {
|
|
|
324
324
|
'management/findAll': () => ([]),
|
|
325
325
|
}
|
|
326
326
|
},
|
|
327
|
-
$
|
|
327
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
328
328
|
},
|
|
329
329
|
|
|
330
330
|
stubs: defaultStubs,
|
|
@@ -369,8 +369,8 @@ describe('component: rke2', () => {
|
|
|
369
369
|
global: {
|
|
370
370
|
mocks: {
|
|
371
371
|
...defaultMocks,
|
|
372
|
-
$store:
|
|
373
|
-
$
|
|
372
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
373
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
374
374
|
},
|
|
375
375
|
stubs: defaultStubs
|
|
376
376
|
}
|
|
@@ -409,8 +409,8 @@ describe('component: rke2', () => {
|
|
|
409
409
|
global: {
|
|
410
410
|
mocks: {
|
|
411
411
|
...defaultMocks,
|
|
412
|
-
$store:
|
|
413
|
-
$
|
|
412
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
413
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
414
414
|
},
|
|
415
415
|
stubs: defaultStubs
|
|
416
416
|
}
|
|
@@ -441,8 +441,8 @@ describe('component: rke2', () => {
|
|
|
441
441
|
global: {
|
|
442
442
|
mocks: {
|
|
443
443
|
...defaultMocks,
|
|
444
|
-
$store:
|
|
445
|
-
$
|
|
444
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
445
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
446
446
|
},
|
|
447
447
|
stubs: defaultStubs
|
|
448
448
|
}
|
|
@@ -489,8 +489,8 @@ describe('component: rke2', () => {
|
|
|
489
489
|
global: {
|
|
490
490
|
mocks: {
|
|
491
491
|
...defaultMocks,
|
|
492
|
-
$store:
|
|
493
|
-
$
|
|
492
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
493
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
494
494
|
},
|
|
495
495
|
stubs: defaultStubs
|
|
496
496
|
}
|
|
@@ -536,8 +536,8 @@ describe('component: rke2', () => {
|
|
|
536
536
|
global: {
|
|
537
537
|
mocks: {
|
|
538
538
|
...defaultMocks,
|
|
539
|
-
$store:
|
|
540
|
-
$
|
|
539
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
540
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
541
541
|
},
|
|
542
542
|
stubs: defaultStubs
|
|
543
543
|
}
|
|
@@ -600,8 +600,8 @@ describe('component: rke2', () => {
|
|
|
600
600
|
global: {
|
|
601
601
|
mocks: {
|
|
602
602
|
...defaultMocks,
|
|
603
|
-
$store:
|
|
604
|
-
$
|
|
603
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
604
|
+
$extension: { getDynamic: jest.fn(() => undefined ) },
|
|
605
605
|
},
|
|
606
606
|
|
|
607
607
|
stubs: defaultStubs,
|
|
@@ -332,9 +332,9 @@ export default {
|
|
|
332
332
|
// Keeping this for non Rancher-managed kontainer drivers
|
|
333
333
|
this.kontainerDrivers.filter((x) => (isImport ? x.showImport : x.showCreate)).forEach((obj) => {
|
|
334
334
|
if ( vueKontainerTypes.includes(obj.driverName) ) {
|
|
335
|
-
addType(this.$
|
|
335
|
+
addType(this.$extension, obj.driverName, 'hosted', false);
|
|
336
336
|
} else {
|
|
337
|
-
addType(this.$
|
|
337
|
+
addType(this.$extension, obj.driverName, 'hosted', false, (isImport ? obj.emberImportPath : obj.emberCreatePath));
|
|
338
338
|
}
|
|
339
339
|
});
|
|
340
340
|
if (!isImport) {
|
|
@@ -351,7 +351,7 @@ export default {
|
|
|
351
351
|
|
|
352
352
|
// If Elemental is installed, then add the elemental cluster provider
|
|
353
353
|
if (isElementalActive) {
|
|
354
|
-
addType(this.$
|
|
354
|
+
addType(this.$extension, ELEMENTAL_CLUSTER_PROVIDER, 'custom2', false);
|
|
355
355
|
}
|
|
356
356
|
|
|
357
357
|
// Only add the RKE2 options if RKE2 is enabled
|
|
@@ -359,10 +359,10 @@ export default {
|
|
|
359
359
|
machineTypes.forEach((type) => {
|
|
360
360
|
const id = type.spec.displayName || type.id;
|
|
361
361
|
|
|
362
|
-
addType(this.$
|
|
362
|
+
addType(this.$extension, id, _RKE2, false, null, undefined, type);
|
|
363
363
|
});
|
|
364
364
|
|
|
365
|
-
addType(this.$
|
|
365
|
+
addType(this.$extension, 'custom', 'custom2', false);
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
// Add from extensions
|
|
@@ -502,7 +502,7 @@ export default {
|
|
|
502
502
|
* 2) Override via hardcoded setting
|
|
503
503
|
*/
|
|
504
504
|
cloudCredentialsOverride() {
|
|
505
|
-
const cloudCredential = this.$
|
|
505
|
+
const cloudCredential = this.$extension.getDynamic('cloud-credential', this.provider);
|
|
506
506
|
|
|
507
507
|
if (cloudCredential === undefined) {
|
|
508
508
|
return CLOUD_CREDENTIAL_OVERRIDE[this.provider];
|
|
@@ -527,16 +527,16 @@ export default {
|
|
|
527
527
|
* Extension provider where being provisioned by an extension
|
|
528
528
|
*/
|
|
529
529
|
extensionProvider() {
|
|
530
|
-
const extClass = this.$
|
|
530
|
+
const extClass = this.$extension.getDynamic('provisioner', this.provider);
|
|
531
531
|
|
|
532
532
|
if (extClass) {
|
|
533
533
|
return new extClass({
|
|
534
|
-
dispatch:
|
|
535
|
-
getters:
|
|
536
|
-
axios:
|
|
537
|
-
$
|
|
538
|
-
$t:
|
|
539
|
-
isCreate:
|
|
534
|
+
dispatch: this.$store.dispatch,
|
|
535
|
+
getters: this.$store.getters,
|
|
536
|
+
axios: this.$store.$axios,
|
|
537
|
+
$extension: this.$store.app.$extension,
|
|
538
|
+
$t: this.t,
|
|
539
|
+
isCreate: this.isCreate
|
|
540
540
|
});
|
|
541
541
|
}
|
|
542
542
|
|
package/edit/workload/index.vue
CHANGED
|
@@ -19,13 +19,12 @@ import { InstallCodeMirror } from 'codemirror-editor-vue3';
|
|
|
19
19
|
import * as intNumber from '@shell/directives/int-number';
|
|
20
20
|
import dashboardClientInit from '@shell/plugins/dashboard-client-init';
|
|
21
21
|
import plugin from '@shell/plugins/plugin';
|
|
22
|
-
import plugins from '@shell/core/plugins.js';
|
|
23
22
|
import pluginsLoader from '@shell/core/plugins-loader.js';
|
|
24
23
|
import replaceAll from '@shell/plugins/replaceall';
|
|
25
24
|
import steveCreateWorker from '@shell/plugins/steve-create-worker';
|
|
26
25
|
import emberCookie from '@shell/plugins/ember-cookie';
|
|
27
26
|
import ShortKey from '@shell/plugins/shortkey';
|
|
28
|
-
import
|
|
27
|
+
import { initUiApis } from '@shell/apis/impl/apis';
|
|
29
28
|
|
|
30
29
|
import 'floating-vue/dist/style.css';
|
|
31
30
|
import { floatingVueOptions } from '@shell/plugins/floating-vue';
|
|
@@ -51,7 +50,7 @@ export async function installInjectedPlugins(app, vueApp) {
|
|
|
51
50
|
const pluginDefinitions = [
|
|
52
51
|
config,
|
|
53
52
|
axios,
|
|
54
|
-
|
|
53
|
+
initUiApis,
|
|
55
54
|
pluginsLoader,
|
|
56
55
|
axiosShell,
|
|
57
56
|
intNumber,
|
|
@@ -61,7 +60,6 @@ export async function installInjectedPlugins(app, vueApp) {
|
|
|
61
60
|
plugin,
|
|
62
61
|
steveCreateWorker,
|
|
63
62
|
emberCookie,
|
|
64
|
-
internalApiPlugin,
|
|
65
63
|
dynamicContent,
|
|
66
64
|
];
|
|
67
65
|
|
|
@@ -69,7 +67,8 @@ export async function installInjectedPlugins(app, vueApp) {
|
|
|
69
67
|
if (typeof pluginDefinition === 'function') {
|
|
70
68
|
await pluginDefinition(
|
|
71
69
|
app.context,
|
|
72
|
-
(key, value) => inject(key, value, app.context, vueApp)
|
|
70
|
+
(key, value) => inject(key, value, app.context, vueApp),
|
|
71
|
+
vueApp
|
|
73
72
|
);
|
|
74
73
|
}
|
|
75
74
|
});
|
|
@@ -255,7 +255,7 @@ export default class MgmtCluster extends SteveModel {
|
|
|
255
255
|
dispatch: this.$dispatch,
|
|
256
256
|
getters: this.$getters,
|
|
257
257
|
axios: this.$axios,
|
|
258
|
-
$extension: this.$
|
|
258
|
+
$extension: this.$extension,
|
|
259
259
|
t: (...args) => this.t.apply(this, args),
|
|
260
260
|
};
|
|
261
261
|
|
|
@@ -277,7 +277,7 @@ export default class ProvCluster extends SteveModel {
|
|
|
277
277
|
dispatch: this.$dispatch,
|
|
278
278
|
getters: this.$getters,
|
|
279
279
|
axios: this.$axios,
|
|
280
|
-
$extension: this.$
|
|
280
|
+
$extension: this.$extension,
|
|
281
281
|
t: (...args) => this.t.apply(this, args),
|
|
282
282
|
};
|
|
283
283
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "3.0.8-rc.
|
|
3
|
+
"version": "3.0.8-rc.13",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
|
-
"repository": "https://github.com/
|
|
5
|
+
"repository": "https://github.com/rancher/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "SUSE",
|
|
8
8
|
"private": false,
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
"vuedraggable": "4.1.0",
|
|
141
141
|
"vuex": "4.1.0",
|
|
142
142
|
"webpack-bundle-analyzer": "4.10.2",
|
|
143
|
-
"webpack-virtual-modules": "0.
|
|
143
|
+
"webpack-virtual-modules": "0.6.2",
|
|
144
144
|
"worker-loader": "3.0.8",
|
|
145
145
|
"xterm-addon-canvas": "0.5.0",
|
|
146
146
|
"xterm-addon-fit": "0.8.0",
|
package/pages/auth/login.vue
CHANGED
|
@@ -315,9 +315,9 @@ export default {
|
|
|
315
315
|
// so we manually load them here - other SSO auth providers bounce out and back to the Dashboard, so on the bounce-back
|
|
316
316
|
// the plugins will load via the boot-time plugin
|
|
317
317
|
await loadPlugins({
|
|
318
|
-
app:
|
|
319
|
-
store:
|
|
320
|
-
$
|
|
318
|
+
app: this.$store.app,
|
|
319
|
+
store: this.$store,
|
|
320
|
+
$extension: this.$store.$extension,
|
|
321
321
|
});
|
|
322
322
|
|
|
323
323
|
if (this.firstLogin || user[0]?.mustChangePassword) {
|
package/pages/auth/setup.vue
CHANGED
|
@@ -209,7 +209,7 @@ export default {
|
|
|
209
209
|
const promises = [];
|
|
210
210
|
|
|
211
211
|
try {
|
|
212
|
-
await applyProducts(this.$store, this.$
|
|
212
|
+
await applyProducts(this.$store, this.$extension);
|
|
213
213
|
await this.$store.dispatch('loadManagement');
|
|
214
214
|
|
|
215
215
|
if ( this.mustChangePassword ) {
|
package/pages/auth/verify.vue
CHANGED
|
@@ -119,9 +119,9 @@ export default {
|
|
|
119
119
|
|
|
120
120
|
// Load plugins
|
|
121
121
|
await loadPlugins({
|
|
122
|
-
app:
|
|
123
|
-
store:
|
|
124
|
-
$
|
|
122
|
+
app: this.$store.app,
|
|
123
|
+
store: this.$store,
|
|
124
|
+
$extension: this.$store.$extension,
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
this.$router.replace(backTo);
|
|
@@ -310,6 +310,7 @@ export default {
|
|
|
310
310
|
two different Helm chart versions is a "user value," or
|
|
311
311
|
a user-selected customization.
|
|
312
312
|
*/
|
|
313
|
+
this.preserveCustomRegistryValue();
|
|
313
314
|
userValues = diff(this.loadedVersionValues, this.chartValues);
|
|
314
315
|
} else if ( this.existing ) {
|
|
315
316
|
await this.existing.fetchValues(); // In theory this has already been called, but do again to be safe
|
|
@@ -824,6 +825,35 @@ export default {
|
|
|
824
825
|
},
|
|
825
826
|
|
|
826
827
|
methods: {
|
|
828
|
+
/**
|
|
829
|
+
* The custom registry UI fields (checkbox and input) are not directly bound to chartValues.
|
|
830
|
+
* Before calculating the diff to carry over user customizations, we must
|
|
831
|
+
* first synchronize the state of these UI fields with chartValues. This
|
|
832
|
+
* ensures any user changes to the custom registry settings are
|
|
833
|
+
* included in the diff and preserved when changing versions.
|
|
834
|
+
*/
|
|
835
|
+
preserveCustomRegistryValue() {
|
|
836
|
+
if (!this.showCustomRegistry) {
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (this.showCustomRegistryInput) {
|
|
841
|
+
set(this.chartValues, 'global.systemDefaultRegistry', this.customRegistrySetting);
|
|
842
|
+
set(this.chartValues, 'global.cattle.systemDefaultRegistry', this.customRegistrySetting);
|
|
843
|
+
} else {
|
|
844
|
+
// Note: Using `delete` here is safe because this is not a reactive property update
|
|
845
|
+
// that the UI needs to track. This is a one-time mutation before a diff.
|
|
846
|
+
if (get(this.chartValues, 'global.systemDefaultRegistry')) {
|
|
847
|
+
delete this.chartValues.global.systemDefaultRegistry;
|
|
848
|
+
}
|
|
849
|
+
if (get(this.chartValues, 'global.cattle.systemDefaultRegistry')) {
|
|
850
|
+
// It's possible `this.chartValues.global.cattle` doesn't exist,
|
|
851
|
+
// but `get` ensures we only proceed if the full path exists.
|
|
852
|
+
delete this.chartValues.global.cattle.systemDefaultRegistry;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
},
|
|
856
|
+
|
|
827
857
|
async getClusterRegistry() {
|
|
828
858
|
const hasPermissionToSeeProvCluster = this.$store.getters[`management/schemaFor`](CAPI.RANCHER_CLUSTER);
|
|
829
859
|
|
|
@@ -1367,6 +1397,7 @@ export default {
|
|
|
1367
1397
|
<!-- We have a chart for the app, let the user select a new version -->
|
|
1368
1398
|
<LabeledSelect
|
|
1369
1399
|
v-if="chart"
|
|
1400
|
+
data-testid="chart-version-selector"
|
|
1370
1401
|
:label="t('catalog.install.version')"
|
|
1371
1402
|
:value="query.versionName"
|
|
1372
1403
|
:options="filteredVersions"
|
|
@@ -1435,6 +1466,7 @@ export default {
|
|
|
1435
1466
|
v-if="showCustomRegistry"
|
|
1436
1467
|
v-model:value="showCustomRegistryInput"
|
|
1437
1468
|
class="mb-20"
|
|
1469
|
+
data-testid="custom-registry-checkbox"
|
|
1438
1470
|
:label="t('catalog.chart.registry.custom.checkBoxLabel')"
|
|
1439
1471
|
:tooltip="t('catalog.chart.registry.tooltip')"
|
|
1440
1472
|
/>
|
|
@@ -1443,6 +1475,7 @@ export default {
|
|
|
1443
1475
|
<LabeledInput
|
|
1444
1476
|
v-if="showCustomRegistryInput"
|
|
1445
1477
|
v-model:value="customRegistrySetting"
|
|
1478
|
+
data-testid="custom-registry-input"
|
|
1446
1479
|
label-key="catalog.chart.registry.custom.inputLabel"
|
|
1447
1480
|
placeholder-key="catalog.chart.registry.custom.placeholder"
|
|
1448
1481
|
:min-height="30"
|
|
@@ -321,16 +321,13 @@ export default {
|
|
|
321
321
|
|
|
322
322
|
this.selectedCard = selected;
|
|
323
323
|
|
|
324
|
-
this.$shell.
|
|
325
|
-
component: ResourceDetails,
|
|
324
|
+
this.$shell.slideIn.open(ResourceDetails, {
|
|
326
325
|
componentProps: {
|
|
326
|
+
showHeader: false,
|
|
327
|
+
width: window.innerWidth / 3 > 530 ? `${ window.innerWidth / 3 }px` : '530px',
|
|
327
328
|
value,
|
|
328
329
|
statePanel,
|
|
329
|
-
workspace
|
|
330
|
-
showHeader: false,
|
|
331
|
-
width: window.innerWidth / 3 > 530 ? `${ window.innerWidth / 3 }px` : '530px',
|
|
332
|
-
triggerFocusTrap: true,
|
|
333
|
-
returnFocusSelector: `[data-testid="resource-card-${ value.id }"]`
|
|
330
|
+
workspace
|
|
334
331
|
}
|
|
335
332
|
});
|
|
336
333
|
},
|
package/pkg/auto-import.js
CHANGED
|
@@ -15,7 +15,7 @@ function registerFile(file, type, pkg, f) {
|
|
|
15
15
|
const importType = (f === 'models') ? 'require' : 'import';
|
|
16
16
|
const chunkName = (f === 'l10n') ? '' : `/* webpackChunkName: "${ f }" */`;
|
|
17
17
|
|
|
18
|
-
return ` $
|
|
18
|
+
return ` $extension.register('${ f }', '${ type }', () => ${ importType }(${ chunkName }'${ pkg }/${ f }/${ file }'));\n`;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function register(file, pkg, f) {
|
|
@@ -29,7 +29,7 @@ function register(file, pkg, f) {
|
|
|
29
29
|
// This ensures that the webpackChunkName is respected (require.context does not support this) - so when build as a library
|
|
30
30
|
// the code splitting will be respected
|
|
31
31
|
function generateTypeImport(pkg, dir) {
|
|
32
|
-
let content = 'export function importTypes($
|
|
32
|
+
let content = 'export function importTypes($extension) { \n';
|
|
33
33
|
|
|
34
34
|
// Auto-import if the folder exists
|
|
35
35
|
contextFolders.forEach((f) => {
|
|
@@ -77,7 +77,7 @@ function generateTypeImport(pkg, dir) {
|
|
|
77
77
|
// and then restart the dev server for it to be picked up.
|
|
78
78
|
function generateDynamicTypeImport(pkg, dir) {
|
|
79
79
|
const template = fs.readFileSync(path.join(__dirname, 'import.js'), { encoding: 'utf8' });
|
|
80
|
-
let content = 'export function importTypes($
|
|
80
|
+
let content = 'export function importTypes($extension) { \n';
|
|
81
81
|
|
|
82
82
|
// Auto-import if the folder exists
|
|
83
83
|
contextFolders.forEach((f) => {
|
package/pkg/import.js
CHANGED
|
@@ -6,5 +6,5 @@ _NAME.forEach((f) => {
|
|
|
6
6
|
|
|
7
7
|
name = name.substr(0, ext);
|
|
8
8
|
|
|
9
|
-
$
|
|
9
|
+
$extension.register('DIR', name, () => REQUIRE(CHUNK`BASE/DIR/${ name }EXT`)); // eslint-disable-line no-undef
|
|
10
10
|
});
|
|
@@ -543,7 +543,7 @@ export default {
|
|
|
543
543
|
const store = state.config.namespace;
|
|
544
544
|
const resource = id || context ? { id, context } : null;
|
|
545
545
|
|
|
546
|
-
return paginationUtils.isEnabled({ rootGetters, $
|
|
546
|
+
return paginationUtils.isEnabled({ rootGetters, $extension: rootState.$extension }, { store, resource });
|
|
547
547
|
},
|
|
548
548
|
|
|
549
549
|
/**
|
|
@@ -610,7 +610,11 @@ export default class Resource {
|
|
|
610
610
|
}
|
|
611
611
|
|
|
612
612
|
get '$plugin'() {
|
|
613
|
-
return this.$ctx.rootState?.$
|
|
613
|
+
return this.$ctx.rootState?.$extension;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
get '$extension'() {
|
|
617
|
+
return this.$ctx.rootState?.$extension;
|
|
614
618
|
}
|
|
615
619
|
|
|
616
620
|
get customValidationRules() {
|
|
@@ -1777,7 +1781,7 @@ export default class Resource {
|
|
|
1777
1781
|
CustomValidators[validatorName](pathValue, this.$rootGetters, errors, validatorArgs, displayKey, data);
|
|
1778
1782
|
} else if (!isEmpty(validatorName) && !validatorExists) {
|
|
1779
1783
|
// Check if validator is imported from plugin
|
|
1780
|
-
const pluginValidator = this.$rootState.$
|
|
1784
|
+
const pluginValidator = this.$rootState.$extension?.getValidator(validatorName);
|
|
1781
1785
|
|
|
1782
1786
|
if (pluginValidator) {
|
|
1783
1787
|
pluginValidator(pathValue, this.$rootGetters, errors, validatorArgs, displayKey, data);
|
package/plugins/plugin.js
CHANGED
|
@@ -44,7 +44,7 @@ export default async function(context) {
|
|
|
44
44
|
const res = await allHashSettled(fetches);
|
|
45
45
|
|
|
46
46
|
// Initialize the built-in extensions now - this is now done here so that built-in extensions get the same, correct environment data (version etc)
|
|
47
|
-
context.$
|
|
47
|
+
context.$extension.loadBuiltinExtensions();
|
|
48
48
|
|
|
49
49
|
if (res.plugins?.status === 'rejected') {
|
|
50
50
|
throw new Error(res.reason);
|
|
@@ -60,7 +60,7 @@ export default async function(context) {
|
|
|
60
60
|
const shouldNotLoad = shouldNotLoadPlugin(plugin, { rancherVersion, kubeVersion }, context.store.getters['uiplugins/plugins'] || []); // Error key string or boolean
|
|
61
61
|
|
|
62
62
|
if (!shouldNotLoad) {
|
|
63
|
-
hash[plugin.name] = context.$
|
|
63
|
+
hash[plugin.name] = context.$extension.loadPluginAsync(plugin);
|
|
64
64
|
} else {
|
|
65
65
|
context.store.dispatch('uiplugins/setError', { name: plugin.name, error: shouldNotLoad });
|
|
66
66
|
}
|