@rancher/shell 0.3.19 → 0.3.21
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/assets/translations/en-us.yaml +4 -1
- package/components/PromptModal.vue +4 -0
- package/components/Questions/Array.vue +2 -2
- package/components/Questions/Boolean.vue +7 -1
- package/components/Questions/CloudCredential.vue +1 -0
- package/components/Questions/Enum.vue +21 -2
- package/components/Questions/Float.vue +8 -3
- package/components/Questions/Int.vue +8 -3
- package/components/Questions/Question.js +72 -0
- package/components/Questions/QuestionMap.vue +2 -1
- package/components/Questions/Radio.vue +33 -0
- package/components/Questions/Reference.vue +2 -0
- package/components/Questions/String.vue +8 -3
- package/components/Questions/Yaml.vue +46 -0
- package/components/Questions/__tests__/Boolean.test.ts +123 -0
- package/components/Questions/__tests__/Float.test.ts +123 -0
- package/components/Questions/__tests__/Int.test.ts +123 -0
- package/components/Questions/__tests__/String.test.ts +123 -0
- package/components/Questions/__tests__/Yaml.test.ts +123 -0
- package/components/Questions/index.vue +8 -1
- package/components/ResourceTable.vue +10 -13
- package/components/SideNav.vue +634 -0
- package/components/__tests__/NamespaceFilter.test.ts +3 -4
- package/components/form/UnitInput.vue +1 -0
- package/components/form/__tests__/KeyValue.test.ts +2 -1
- package/components/form/__tests__/UnitInput.test.ts +2 -2
- package/components/formatter/LinkName.vue +12 -1
- package/components/nav/WorkspaceSwitcher.vue +4 -1
- package/core/plugin-helpers.js +4 -1
- package/core/types.ts +25 -1
- package/detail/node.vue +2 -2
- package/edit/fleet.cattle.io.gitrepo.vue +7 -0
- package/layouts/default.vue +11 -597
- package/middleware/authenticated.js +2 -14
- package/models/fleet.cattle.io.gitrepo.js +3 -1
- package/package.json +1 -1
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/fleet/index.vue +4 -0
- package/pages/c/_cluster/uiplugins/index.vue +3 -3
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +8 -0
- package/rancher-components/components/Form/Radio/RadioButton.test.ts +7 -3
- package/store/auth.js +2 -0
- package/types/shell/index.d.ts +2 -0
- package/utils/auth.js +17 -0
- package/utils/object.js +0 -1
- package/utils/validators/__tests__/cidr.test.ts +33 -0
- package/utils/validators/cidr.js +5 -0
package/layouts/default.vue
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import debounce from 'lodash/debounce';
|
|
3
2
|
import { mapState, mapGetters } from 'vuex';
|
|
4
3
|
import {
|
|
5
4
|
mapPref,
|
|
6
|
-
FAVORITE_TYPES,
|
|
7
5
|
AFTER_LOGIN_ROUTE,
|
|
8
6
|
THEME_SHORTCUT
|
|
9
7
|
} from '@shell/store/prefs';
|
|
@@ -14,7 +12,6 @@ import PromptRemove from '@shell/components/PromptRemove';
|
|
|
14
12
|
import PromptRestore from '@shell/components/PromptRestore';
|
|
15
13
|
import PromptModal from '@shell/components/PromptModal';
|
|
16
14
|
import AssignTo from '@shell/components/AssignTo';
|
|
17
|
-
import Group from '@shell/components/nav/Group';
|
|
18
15
|
import Header from '@shell/components/nav/Header';
|
|
19
16
|
import Inactivity from '@shell/components/Inactivity';
|
|
20
17
|
import Brand from '@shell/mixins/brand';
|
|
@@ -22,22 +19,14 @@ import FixedBanner from '@shell/components/FixedBanner';
|
|
|
22
19
|
import AwsComplianceBanner from '@shell/components/AwsComplianceBanner';
|
|
23
20
|
import AzureWarning from '@shell/components/auth/AzureWarning';
|
|
24
21
|
import DraggableZone from '@shell/components/DraggableZone';
|
|
25
|
-
import {
|
|
26
|
-
COUNT, SCHEMA, MANAGEMENT, UI, CATALOG, HCI
|
|
27
|
-
} from '@shell/config/types';
|
|
28
|
-
import { BASIC, FAVORITE, USED } from '@shell/store/type-map';
|
|
29
|
-
import { addObjects, replaceWith, clear, addObject } from '@shell/utils/array';
|
|
30
|
-
import { NAME as EXPLORER } from '@shell/config/product/explorer';
|
|
31
|
-
import { NAME as NAVLINKS } from '@shell/config/product/navlinks';
|
|
32
|
-
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
22
|
+
import { MANAGEMENT } from '@shell/config/types';
|
|
33
23
|
import isEqual from 'lodash/isEqual';
|
|
34
|
-
import {
|
|
35
|
-
import { getVersionInfo, markSeenReleaseNotes } from '@shell/utils/version';
|
|
36
|
-
import { sortBy } from '@shell/utils/sort';
|
|
24
|
+
import { markSeenReleaseNotes } from '@shell/utils/version';
|
|
37
25
|
import PageHeaderActions from '@shell/mixins/page-actions';
|
|
38
26
|
import BrowserTabVisibility from '@shell/mixins/browser-tab-visibility';
|
|
39
27
|
import { getClusterFromRoute, getProductFromRoute } from '@shell/middleware/authenticated';
|
|
40
28
|
import { BOTTOM } from '@shell/utils/position';
|
|
29
|
+
import SideNav from '@shell/components/SideNav';
|
|
41
30
|
import { BLANK_CLUSTER } from '@shell/store/store-types.js';
|
|
42
31
|
|
|
43
32
|
const SET_LOGIN_ACTION = 'set-as-login';
|
|
@@ -51,14 +40,14 @@ export default {
|
|
|
51
40
|
PromptModal,
|
|
52
41
|
Header,
|
|
53
42
|
ActionMenu,
|
|
54
|
-
Group,
|
|
55
43
|
GrowlManager,
|
|
56
44
|
WindowManager,
|
|
57
45
|
FixedBanner,
|
|
58
46
|
AwsComplianceBanner,
|
|
59
47
|
AzureWarning,
|
|
60
48
|
DraggableZone,
|
|
61
|
-
Inactivity
|
|
49
|
+
Inactivity,
|
|
50
|
+
SideNav,
|
|
62
51
|
},
|
|
63
52
|
|
|
64
53
|
mixins: [PageHeaderActions, Brand, BrowserTabVisibility],
|
|
@@ -67,8 +56,6 @@ export default {
|
|
|
67
56
|
data() {
|
|
68
57
|
return {
|
|
69
58
|
noLocaleShortcut: process.env.dev || false,
|
|
70
|
-
groups: [],
|
|
71
|
-
gettingGroups: false,
|
|
72
59
|
wantNavSync: false,
|
|
73
60
|
unwatchPin: undefined,
|
|
74
61
|
wmPin: null,
|
|
@@ -83,22 +70,15 @@ export default {
|
|
|
83
70
|
|
|
84
71
|
computed: {
|
|
85
72
|
...mapState(['managementReady', 'clusterReady']),
|
|
86
|
-
...mapGetters(['
|
|
87
|
-
...mapGetters({ locale: 'i18n/selectedLocaleLabel', availableLocales: 'i18n/availableLocales' }),
|
|
88
|
-
...mapGetters('type-map', ['activeProducts']),
|
|
73
|
+
...mapGetters(['clusterId', 'currentProduct', 'isRancherInHarvester']),
|
|
89
74
|
|
|
90
75
|
afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
|
|
91
76
|
|
|
92
|
-
namespaces() {
|
|
93
|
-
return this.$store.getters['activeNamespaceCache'];
|
|
94
|
-
},
|
|
95
|
-
|
|
96
77
|
themeShortcut: mapPref(THEME_SHORTCUT),
|
|
97
|
-
favoriteTypes: mapPref(FAVORITE_TYPES),
|
|
98
78
|
|
|
99
79
|
pageActions() {
|
|
100
80
|
const pageActions = [];
|
|
101
|
-
const product = this
|
|
81
|
+
const product = this.currentProduct;
|
|
102
82
|
|
|
103
83
|
if ( !product ) {
|
|
104
84
|
return [];
|
|
@@ -117,90 +97,6 @@ export default {
|
|
|
117
97
|
return pageActions;
|
|
118
98
|
},
|
|
119
99
|
|
|
120
|
-
allSchemas() {
|
|
121
|
-
const managementReady = this.managementReady;
|
|
122
|
-
const product = this.$store.getters['currentProduct'];
|
|
123
|
-
|
|
124
|
-
if ( !managementReady || !product ) {
|
|
125
|
-
return [];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return this.$store.getters[`${ product.inStore }/all`](SCHEMA);
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
allNavLinks() {
|
|
132
|
-
if ( !this.clusterId || !this.$store.getters['cluster/schemaFor'](UI.NAV_LINK) ) {
|
|
133
|
-
return [];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return this.$store.getters['cluster/all'](UI.NAV_LINK);
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
counts() {
|
|
140
|
-
const managementReady = this.managementReady;
|
|
141
|
-
const product = this.$store.getters['currentProduct'];
|
|
142
|
-
|
|
143
|
-
if ( !managementReady || !product ) {
|
|
144
|
-
return {};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const inStore = product.inStore;
|
|
148
|
-
|
|
149
|
-
// So that there's something to watch for updates
|
|
150
|
-
if ( this.$store.getters[`${ inStore }/haveAll`](COUNT) ) {
|
|
151
|
-
const counts = this.$store.getters[`${ inStore }/all`](COUNT)[0].counts;
|
|
152
|
-
|
|
153
|
-
return counts;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return {};
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
showClusterTools() {
|
|
160
|
-
return this.isExplorer &&
|
|
161
|
-
this.$store.getters['cluster/canList'](CATALOG.CLUSTER_REPO) &&
|
|
162
|
-
this.$store.getters['cluster/canList'](CATALOG.APP);
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
displayVersion() {
|
|
166
|
-
if (this.isSingleProduct?.getVersionInfo) {
|
|
167
|
-
return this.isSingleProduct?.getVersionInfo(this.$store);
|
|
168
|
-
}
|
|
169
|
-
const { displayVersion } = getVersionInfo(this.$store);
|
|
170
|
-
|
|
171
|
-
return displayVersion;
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
singleProductAbout() {
|
|
175
|
-
return this.isSingleProduct?.aboutPage;
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
harvesterVersion() {
|
|
179
|
-
return this.$store.getters['cluster/byId'](HCI.SETTING, 'server-version')?.value || 'unknown';
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
showProductFooter() {
|
|
183
|
-
if (this.isVirtualProduct) {
|
|
184
|
-
return true;
|
|
185
|
-
} else {
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
isVirtualProduct() {
|
|
191
|
-
return this.$store.getters['currentProduct'].name === HARVESTER;
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
supportLink() {
|
|
195
|
-
const product = this.$store.getters['currentProduct'];
|
|
196
|
-
|
|
197
|
-
if (product?.supportRoute) {
|
|
198
|
-
return { ...product.supportRoute, params: { ...product.supportRoute.params, cluster: this.clusterId } };
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return { name: `c-cluster-${ product?.name }-support` };
|
|
202
|
-
},
|
|
203
|
-
|
|
204
100
|
unmatchedRoute() {
|
|
205
101
|
return !this.$route?.matched?.length;
|
|
206
102
|
},
|
|
@@ -224,43 +120,6 @@ export default {
|
|
|
224
120
|
},
|
|
225
121
|
|
|
226
122
|
watch: {
|
|
227
|
-
counts(a, b) {
|
|
228
|
-
if ( a !== b ) {
|
|
229
|
-
this.queueUpdate();
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
allSchemas(a, b) {
|
|
234
|
-
if ( a !== b ) {
|
|
235
|
-
this.queueUpdate();
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
allNavLinks(a, b) {
|
|
240
|
-
if ( a !== b ) {
|
|
241
|
-
this.queueUpdate();
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
favoriteTypes(a, b) {
|
|
246
|
-
if ( !isEqual(a, b) ) {
|
|
247
|
-
this.queueUpdate();
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
|
|
251
|
-
locale(a, b) {
|
|
252
|
-
if ( !isEqual(a, b) ) {
|
|
253
|
-
this.getGroups();
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
|
|
257
|
-
productId(a, b) {
|
|
258
|
-
if ( !isEqual(a, b) ) {
|
|
259
|
-
// Immediately update because you'll see it come in later
|
|
260
|
-
this.getGroups();
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
|
|
264
123
|
clusterId(a, b) {
|
|
265
124
|
if ( !isEqual(a, b) ) {
|
|
266
125
|
// Store the last visited route when the cluster changes
|
|
@@ -268,34 +127,6 @@ export default {
|
|
|
268
127
|
}
|
|
269
128
|
},
|
|
270
129
|
|
|
271
|
-
namespaceMode(a, b) {
|
|
272
|
-
if ( !isEqual(a, b) ) {
|
|
273
|
-
// Immediately update because you'll see it come in later
|
|
274
|
-
this.getGroups();
|
|
275
|
-
}
|
|
276
|
-
},
|
|
277
|
-
|
|
278
|
-
namespaces(a, b) {
|
|
279
|
-
if ( !isEqual(a, b) ) {
|
|
280
|
-
// Immediately update because you'll see it come in later
|
|
281
|
-
this.getGroups();
|
|
282
|
-
}
|
|
283
|
-
},
|
|
284
|
-
|
|
285
|
-
clusterReady(a, b) {
|
|
286
|
-
if ( !isEqual(a, b) ) {
|
|
287
|
-
// Immediately update because you'll see it come in later
|
|
288
|
-
this.getGroups();
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
|
|
292
|
-
product(a, b) {
|
|
293
|
-
if ( !isEqual(a, b) ) {
|
|
294
|
-
// Immediately update because you'll see it come in later
|
|
295
|
-
this.getGroups();
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
|
|
299
130
|
async currentProduct(a, b) {
|
|
300
131
|
if ( !isEqual(a, b) ) {
|
|
301
132
|
if ((a.inStore !== b.inStore || a.inStore !== 'cluster') && this.clusterId && a.name) {
|
|
@@ -311,25 +142,13 @@ export default {
|
|
|
311
142
|
}
|
|
312
143
|
}
|
|
313
144
|
},
|
|
314
|
-
|
|
315
|
-
$route(a, b) {
|
|
316
|
-
this.$nextTick(() => this.syncNav());
|
|
317
|
-
},
|
|
318
|
-
|
|
319
145
|
},
|
|
320
146
|
|
|
321
147
|
async created() {
|
|
322
|
-
this.queueUpdate = debounce(this.getGroups, 500);
|
|
323
|
-
|
|
324
|
-
this.getGroups();
|
|
325
|
-
|
|
326
148
|
await this.$store.dispatch('prefs/setLastVisited', this.$route);
|
|
327
149
|
},
|
|
328
150
|
|
|
329
151
|
mounted() {
|
|
330
|
-
// Sync the navigation tree on fresh load
|
|
331
|
-
this.$nextTick(() => this.syncNav());
|
|
332
|
-
|
|
333
152
|
this.wmPin = window.localStorage.getItem('wm-pin') || BOTTOM;
|
|
334
153
|
|
|
335
154
|
// two-way binding this.wmPin <-> draggableZone.pin
|
|
@@ -374,173 +193,6 @@ export default {
|
|
|
374
193
|
};
|
|
375
194
|
},
|
|
376
195
|
|
|
377
|
-
collapseAll() {
|
|
378
|
-
this.$refs.groups.forEach((grp) => {
|
|
379
|
-
grp.isExpanded = false;
|
|
380
|
-
});
|
|
381
|
-
},
|
|
382
|
-
|
|
383
|
-
getProductsGroups(out, loadProducts, namespaceMode, namespaces, productMap) {
|
|
384
|
-
const clusterId = this.$store.getters['clusterId'];
|
|
385
|
-
const currentType = this.$route.params.resource || '';
|
|
386
|
-
|
|
387
|
-
for ( const productId of loadProducts ) {
|
|
388
|
-
const modes = [BASIC];
|
|
389
|
-
|
|
390
|
-
if ( productId === NAVLINKS ) {
|
|
391
|
-
// Navlinks produce their own top-level nav items so don't need to show it as a product.
|
|
392
|
-
continue;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if ( productId === EXPLORER ) {
|
|
396
|
-
modes.push(FAVORITE);
|
|
397
|
-
modes.push(USED);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
for ( const mode of modes ) {
|
|
401
|
-
const types = this.$store.getters['type-map/allTypes'](productId, mode) || {};
|
|
402
|
-
|
|
403
|
-
const more = this.$store.getters['type-map/getTree'](productId, mode, types, clusterId, namespaceMode, namespaces, currentType);
|
|
404
|
-
|
|
405
|
-
if ( productId === EXPLORER || !this.isExplorer ) {
|
|
406
|
-
addObjects(out, more);
|
|
407
|
-
} else {
|
|
408
|
-
const root = more.find((x) => x.name === 'root');
|
|
409
|
-
const other = more.filter((x) => x.name !== 'root');
|
|
410
|
-
|
|
411
|
-
const group = {
|
|
412
|
-
name: productId,
|
|
413
|
-
label: this.$store.getters['i18n/withFallback'](`product.${ productId }`, null, ucFirst(productId)),
|
|
414
|
-
children: [...(root?.children || []), ...other],
|
|
415
|
-
weight: productMap[productId]?.weight || 0,
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
addObject(out, group);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
},
|
|
423
|
-
|
|
424
|
-
getExplorerGroups(out) {
|
|
425
|
-
if ( this.isExplorer ) {
|
|
426
|
-
const allNavLinks = this.allNavLinks;
|
|
427
|
-
const toAdd = [];
|
|
428
|
-
const haveGroup = {};
|
|
429
|
-
|
|
430
|
-
for ( const obj of allNavLinks ) {
|
|
431
|
-
if ( !obj.link ) {
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
const groupLabel = obj.spec.group;
|
|
436
|
-
const groupSlug = obj.normalizedGroup;
|
|
437
|
-
|
|
438
|
-
const entry = {
|
|
439
|
-
name: `link-${ obj._key }`,
|
|
440
|
-
link: obj.link,
|
|
441
|
-
target: obj.actualTarget,
|
|
442
|
-
label: obj.labelDisplay,
|
|
443
|
-
sideLabel: obj.spec.sideLabel,
|
|
444
|
-
iconSrc: obj.spec.iconSrc,
|
|
445
|
-
description: obj.spec.description,
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
// If there's a spec.group (groupLabel), all entries with that name go under one nav group
|
|
449
|
-
if ( groupSlug ) {
|
|
450
|
-
if ( haveGroup[groupSlug] ) {
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
haveGroup[groupSlug] = true;
|
|
455
|
-
|
|
456
|
-
toAdd.push({
|
|
457
|
-
name: `navlink-group-${ groupSlug }`,
|
|
458
|
-
label: groupLabel,
|
|
459
|
-
isRoot: true,
|
|
460
|
-
// This is the item that actually shows up in the nav, since this outer group will be invisible
|
|
461
|
-
children: [
|
|
462
|
-
{
|
|
463
|
-
name: `navlink-child-${ groupSlug }`,
|
|
464
|
-
label: groupLabel,
|
|
465
|
-
route: {
|
|
466
|
-
name: 'c-cluster-navlinks-group',
|
|
467
|
-
params: {
|
|
468
|
-
cluster: this.clusterId,
|
|
469
|
-
group: groupSlug,
|
|
470
|
-
}
|
|
471
|
-
},
|
|
472
|
-
}
|
|
473
|
-
],
|
|
474
|
-
weight: -100,
|
|
475
|
-
});
|
|
476
|
-
} else {
|
|
477
|
-
toAdd.push({
|
|
478
|
-
name: `navlink-${ entry.name }`,
|
|
479
|
-
label: entry.label,
|
|
480
|
-
isRoot: true,
|
|
481
|
-
// This is the item that actually shows up in the nav, since this outer group will be invisible
|
|
482
|
-
children: [entry],
|
|
483
|
-
weight: -100,
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
addObjects(out, toAdd);
|
|
489
|
-
}
|
|
490
|
-
},
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Fetch navigation by creating groups from product schemas
|
|
494
|
-
*/
|
|
495
|
-
getGroups() {
|
|
496
|
-
if ( this.gettingGroups ) {
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
this.gettingGroups = true;
|
|
500
|
-
|
|
501
|
-
if ( !this.clusterReady ) {
|
|
502
|
-
clear(this.groups);
|
|
503
|
-
this.gettingGroups = false;
|
|
504
|
-
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
const currentProduct = this.$store.getters['productId'];
|
|
509
|
-
let namespaces = null;
|
|
510
|
-
|
|
511
|
-
if ( !this.$store.getters['isAllNamespaces'] ) {
|
|
512
|
-
const namespacesObject = this.$store.getters['namespaces']();
|
|
513
|
-
|
|
514
|
-
namespaces = Object.keys(namespacesObject);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Always show cluster-level types, regardless of the namespace filter
|
|
518
|
-
const namespaceMode = 'both';
|
|
519
|
-
const out = [];
|
|
520
|
-
const loadProducts = this.isExplorer ? [EXPLORER] : [];
|
|
521
|
-
|
|
522
|
-
const productMap = this.activeProducts.reduce((acc, p) => {
|
|
523
|
-
return { ...acc, [p.name]: p };
|
|
524
|
-
}, {});
|
|
525
|
-
|
|
526
|
-
if ( this.isExplorer ) {
|
|
527
|
-
for ( const product of this.activeProducts ) {
|
|
528
|
-
if ( product.inStore === 'cluster' ) {
|
|
529
|
-
addObject(loadProducts, product.name);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// This should already have come into the list from above, but in case it hasn't...
|
|
535
|
-
addObject(loadProducts, currentProduct);
|
|
536
|
-
|
|
537
|
-
this.getProductsGroups(out, loadProducts, namespaceMode, namespaces, productMap);
|
|
538
|
-
this.getExplorerGroups(out);
|
|
539
|
-
|
|
540
|
-
replaceWith(this.groups, ...sortBy(out, ['weight:desc', 'label']));
|
|
541
|
-
this.gettingGroups = false;
|
|
542
|
-
},
|
|
543
|
-
|
|
544
196
|
toggleNoneLocale() {
|
|
545
197
|
this.$store.dispatch('i18n/toggleNone');
|
|
546
198
|
},
|
|
@@ -549,14 +201,6 @@ export default {
|
|
|
549
201
|
this.$store.dispatch('prefs/toggleTheme');
|
|
550
202
|
},
|
|
551
203
|
|
|
552
|
-
groupSelected(selected) {
|
|
553
|
-
this.$refs.groups.forEach((grp) => {
|
|
554
|
-
if (grp.canCollapse) {
|
|
555
|
-
grp.isExpanded = (grp.group.name === selected.name);
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
},
|
|
559
|
-
|
|
560
204
|
wheresMyDebugger() {
|
|
561
205
|
// vue-shortkey is preventing F8 from passing through to the browser... this works for now.
|
|
562
206
|
// eslint-disable-next-line no-debugger
|
|
@@ -581,41 +225,6 @@ export default {
|
|
|
581
225
|
|
|
582
226
|
cluster.openShell();
|
|
583
227
|
},
|
|
584
|
-
|
|
585
|
-
syncNav() {
|
|
586
|
-
const refs = this.$refs.groups;
|
|
587
|
-
|
|
588
|
-
if (refs) {
|
|
589
|
-
// Only expand one group - so after the first has been expanded, no more will
|
|
590
|
-
// This prevents the 'More Resources' group being expanded in addition to the normal group
|
|
591
|
-
let canExpand = true;
|
|
592
|
-
const expanded = refs.filter((grp) => grp.isExpanded)[0];
|
|
593
|
-
|
|
594
|
-
if (expanded && expanded.hasActiveRoute()) {
|
|
595
|
-
this.$nextTick(() => expanded.syncNav());
|
|
596
|
-
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
refs.forEach((grp) => {
|
|
600
|
-
if (!grp.group.isRoot) {
|
|
601
|
-
grp.isExpanded = false;
|
|
602
|
-
if (canExpand) {
|
|
603
|
-
const isActive = grp.hasActiveRoute();
|
|
604
|
-
|
|
605
|
-
if (isActive) {
|
|
606
|
-
grp.isExpanded = true;
|
|
607
|
-
canExpand = false;
|
|
608
|
-
this.$nextTick(() => grp.syncNav());
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
},
|
|
615
|
-
|
|
616
|
-
switchLocale(locale) {
|
|
617
|
-
this.$store.dispatch('i18n/switchTo', locale);
|
|
618
|
-
},
|
|
619
228
|
}
|
|
620
229
|
};
|
|
621
230
|
</script>
|
|
@@ -631,110 +240,10 @@ export default {
|
|
|
631
240
|
:class="{[pinClass]: true}"
|
|
632
241
|
>
|
|
633
242
|
<Header />
|
|
634
|
-
<
|
|
243
|
+
<SideNav
|
|
635
244
|
v-if="clusterReady"
|
|
636
|
-
class="side-nav"
|
|
637
|
-
|
|
638
|
-
<div class="nav">
|
|
639
|
-
<template v-for="(g) in groups">
|
|
640
|
-
<Group
|
|
641
|
-
ref="groups"
|
|
642
|
-
:key="g.name"
|
|
643
|
-
id-prefix=""
|
|
644
|
-
class="package"
|
|
645
|
-
:group="g"
|
|
646
|
-
:can-collapse="!g.isRoot"
|
|
647
|
-
:show-header="!g.isRoot"
|
|
648
|
-
@selected="groupSelected($event)"
|
|
649
|
-
@expand="groupSelected($event)"
|
|
650
|
-
/>
|
|
651
|
-
</template>
|
|
652
|
-
</div>
|
|
653
|
-
<n-link
|
|
654
|
-
v-if="showClusterTools"
|
|
655
|
-
tag="div"
|
|
656
|
-
class="tools"
|
|
657
|
-
:to="{name: 'c-cluster-explorer-tools', params: {cluster: clusterId}}"
|
|
658
|
-
>
|
|
659
|
-
<a
|
|
660
|
-
class="tools-button"
|
|
661
|
-
@click="collapseAll()"
|
|
662
|
-
>
|
|
663
|
-
<i class="icon icon-gear" />
|
|
664
|
-
<span>{{ t('nav.clusterTools') }}</span>
|
|
665
|
-
</a>
|
|
666
|
-
</n-link>
|
|
667
|
-
<div
|
|
668
|
-
v-if="showProductFooter"
|
|
669
|
-
class="footer"
|
|
670
|
-
>
|
|
671
|
-
<nuxt-link
|
|
672
|
-
:to="supportLink"
|
|
673
|
-
class="pull-right"
|
|
674
|
-
>
|
|
675
|
-
{{ t('nav.support', {hasSupport: true}) }}
|
|
676
|
-
</nuxt-link>
|
|
677
|
-
|
|
678
|
-
<span
|
|
679
|
-
v-clean-tooltip="{content: displayVersion, placement: 'top'}"
|
|
680
|
-
class="clip version text-muted"
|
|
681
|
-
>
|
|
682
|
-
{{ displayVersion }}
|
|
683
|
-
</span>
|
|
684
|
-
|
|
685
|
-
<span v-if="isSingleProduct">
|
|
686
|
-
<v-popover
|
|
687
|
-
popover-class="localeSelector"
|
|
688
|
-
placement="top"
|
|
689
|
-
trigger="click"
|
|
690
|
-
>
|
|
691
|
-
<a
|
|
692
|
-
data-testid="locale-selector"
|
|
693
|
-
class="locale-chooser"
|
|
694
|
-
>
|
|
695
|
-
{{ locale }}
|
|
696
|
-
</a>
|
|
697
|
-
|
|
698
|
-
<template slot="popover">
|
|
699
|
-
<ul
|
|
700
|
-
class="list-unstyled dropdown"
|
|
701
|
-
style="margin: -1px;"
|
|
702
|
-
>
|
|
703
|
-
<li
|
|
704
|
-
v-for="(label, name) in availableLocales"
|
|
705
|
-
:key="name"
|
|
706
|
-
class="hand"
|
|
707
|
-
@click="switchLocale(name)"
|
|
708
|
-
>
|
|
709
|
-
{{ label }}
|
|
710
|
-
</li>
|
|
711
|
-
</ul>
|
|
712
|
-
</template>
|
|
713
|
-
</v-popover>
|
|
714
|
-
</span>
|
|
715
|
-
</div>
|
|
716
|
-
<div
|
|
717
|
-
v-else
|
|
718
|
-
class="version text-muted flex"
|
|
719
|
-
>
|
|
720
|
-
<nuxt-link
|
|
721
|
-
v-if="singleProductAbout"
|
|
722
|
-
:to="singleProductAbout"
|
|
723
|
-
>
|
|
724
|
-
{{ displayVersion }}
|
|
725
|
-
</nuxt-link>
|
|
726
|
-
<template v-else>
|
|
727
|
-
<span>{{ displayVersion }}</span>
|
|
728
|
-
<span
|
|
729
|
-
v-if="isVirtualCluster && isExplorer"
|
|
730
|
-
v-tooltip="{content: harvesterVersion, placement: 'top'}"
|
|
731
|
-
class="clip text-muted ml-5"
|
|
732
|
-
>
|
|
733
|
-
(Harvester-{{ harvesterVersion }})
|
|
734
|
-
</span>
|
|
735
|
-
</template>
|
|
736
|
-
</div>
|
|
737
|
-
</nav>
|
|
245
|
+
class="default-side-nav"
|
|
246
|
+
/>
|
|
738
247
|
<main
|
|
739
248
|
v-if="clusterAndRouteReady"
|
|
740
249
|
class="main-layout"
|
|
@@ -795,20 +304,6 @@ export default {
|
|
|
795
304
|
<DraggableZone ref="draggableZone" />
|
|
796
305
|
</div>
|
|
797
306
|
</template>
|
|
798
|
-
<style lang="scss" scoped>
|
|
799
|
-
.side-nav {
|
|
800
|
-
display: flex;
|
|
801
|
-
flex-direction: column;
|
|
802
|
-
.nav {
|
|
803
|
-
flex: 1;
|
|
804
|
-
overflow-y: auto;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
.flex {
|
|
809
|
-
display: flex;
|
|
810
|
-
}
|
|
811
|
-
</style>
|
|
812
307
|
<style lang="scss">
|
|
813
308
|
.dashboard-root {
|
|
814
309
|
display: flex;
|
|
@@ -852,89 +347,8 @@ export default {
|
|
|
852
347
|
grid-area: header;
|
|
853
348
|
}
|
|
854
349
|
|
|
855
|
-
|
|
350
|
+
.default-side-nav {
|
|
856
351
|
grid-area: nav;
|
|
857
|
-
position: relative;
|
|
858
|
-
background-color: var(--nav-bg);
|
|
859
|
-
border-right: var(--nav-border-size) solid var(--nav-border);
|
|
860
|
-
overflow-y: auto;
|
|
861
|
-
|
|
862
|
-
H6, .root.child .label {
|
|
863
|
-
margin: 0;
|
|
864
|
-
letter-spacing: normal;
|
|
865
|
-
line-height: initial;
|
|
866
|
-
|
|
867
|
-
A { padding-left: 0; }
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
NAV .tools {
|
|
872
|
-
display: flex;
|
|
873
|
-
margin: 10px;
|
|
874
|
-
text-align: center;
|
|
875
|
-
|
|
876
|
-
A {
|
|
877
|
-
align-items: center;
|
|
878
|
-
border: 1px solid var(--border);
|
|
879
|
-
border-radius: 5px;
|
|
880
|
-
color: var(--body-text);
|
|
881
|
-
display: flex;
|
|
882
|
-
justify-content: center;
|
|
883
|
-
outline: 0;
|
|
884
|
-
flex: 1;
|
|
885
|
-
padding: 10px;
|
|
886
|
-
|
|
887
|
-
&:hover {
|
|
888
|
-
background: var(--nav-hover);
|
|
889
|
-
text-decoration: none;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
> I {
|
|
893
|
-
margin-right: 4px;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
&.nuxt-link-active:not(:hover) {
|
|
898
|
-
A {
|
|
899
|
-
background-color: var(--nav-active);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
NAV .version {
|
|
905
|
-
cursor: default;
|
|
906
|
-
margin: 0 10px 10px 10px;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
NAV .footer {
|
|
910
|
-
margin: 20px;
|
|
911
|
-
|
|
912
|
-
display: flex;
|
|
913
|
-
flex: 0;
|
|
914
|
-
flex-direction: row;
|
|
915
|
-
> * {
|
|
916
|
-
flex: 1;
|
|
917
|
-
color: var(--link);
|
|
918
|
-
|
|
919
|
-
&:last-child {
|
|
920
|
-
text-align: right;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
&:first-child {
|
|
924
|
-
text-align: left;
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
text-align: center;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
.version {
|
|
931
|
-
cursor: default;
|
|
932
|
-
margin: 0px;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
.locale-chooser {
|
|
936
|
-
cursor: pointer;
|
|
937
|
-
}
|
|
938
352
|
}
|
|
939
353
|
}
|
|
940
354
|
|