@rancher/shell 0.1.3 → 0.1.4
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/brand/suse/dark/rancher-logo.svg +1 -148
- package/assets/brand/suse/rancher-logo.svg +1 -130
- package/assets/images/featured/img1.jpg +0 -0
- package/assets/images/featured.jpg +0 -0
- package/assets/images/generic-plugin.svg +7 -0
- package/assets/styles/themes/_dark.scss +3 -0
- package/assets/styles/themes/_light.scss +3 -0
- package/assets/styles/themes/_suse.scss +1 -1
- package/assets/translations/en-us.yaml +183 -45
- package/assets/translations/zh-hans.yaml +21 -24
- package/components/AsyncButton.vue +17 -2
- package/components/ButtonDropdown.vue +4 -0
- package/components/Carousel.vue +291 -0
- package/components/CommunityLinks.vue +69 -18
- package/components/CruResource.vue +11 -3
- package/components/Dialog.vue +102 -0
- package/components/ExplorerMembers.vue +2 -4
- package/components/ExplorerProjectsNamespaces.vue +6 -7
- package/components/IconMessage.vue +9 -1
- package/components/LocaleSelector.vue +62 -29
- package/components/ResourceTable.vue +7 -2
- package/components/SimpleBox.vue +6 -4
- package/components/SortableTable/index.vue +11 -21
- package/components/Tabbed/Tab.vue +5 -0
- package/components/Tabbed/index.vue +29 -2
- package/components/auth/Principal.vue +1 -0
- package/components/fleet/FleetBundles.vue +8 -3
- package/components/fleet/FleetSummary.vue +6 -0
- package/components/form/KeyValue.vue +80 -58
- package/components/form/NameNsDescription.vue +10 -4
- package/components/form/ResourceTabs/index.vue +5 -1
- package/components/formatter/ClusterLink.vue +3 -7
- package/components/nav/NamespaceFilter.vue +3 -3
- package/components/nav/TopLevelMenu.vue +10 -28
- package/config/footer.js +13 -14
- package/config/labels-annotations.js +2 -1
- package/config/product/explorer.js +5 -4
- package/config/product/legacy.js +0 -47
- package/config/product/multi-cluster-apps.js +0 -12
- package/config/product/settings.js +12 -1
- package/config/product/uiplugins.js +17 -0
- package/config/settings.js +21 -2
- package/config/types.js +5 -1
- package/config/uiplugins.js +60 -0
- package/content/docs/en-us/getting-started.md +1 -26
- package/core/plugins.js +12 -0
- package/detail/provisioning.cattle.io.cluster.vue +3 -3
- package/detail/workload/index.vue +2 -2
- package/dialog/DiagnosticTimingsDialog.vue +116 -0
- package/dialog/RotateCertificatesDialog.vue +9 -3
- package/edit/auth/azuread.vue +28 -9
- package/edit/networking.k8s.io.ingress/index.vue +2 -2
- package/edit/persistentvolume/index.vue +3 -0
- package/edit/pod.vue +27 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +76 -5
- package/edit/service.vue +7 -5
- package/edit/workload/__tests__/Upgrading.test.ts +1 -0
- package/edit/workload/index.vue +13 -1
- package/edit/workload/mixins/workload.js +13 -13
- package/edit/workload/storage/ContainerMountPaths.vue +240 -0
- package/edit/workload/storage/Mount.vue +1 -0
- package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
- package/edit/workload/storage/azureDisk.vue +22 -2
- package/edit/workload/storage/azureFile.vue +20 -2
- package/edit/workload/storage/csi/index.vue +23 -1
- package/edit/workload/storage/gcePersistentDisk.vue +20 -2
- package/edit/workload/storage/index.vue +23 -49
- package/edit/workload/storage/vsphereVolume.vue +11 -1
- package/layouts/default.vue +14 -8
- package/layouts/home.vue +9 -4
- package/layouts/plain.vue +10 -5
- package/list/management.cattle.io.setting.vue +3 -3
- package/list/provisioning.cattle.io.cluster.vue +1 -1
- package/machine-config/harvester.vue +5 -3
- package/models/catalog.cattle.io.uiplugin.js +34 -0
- package/models/cluster/node.js +25 -2
- package/models/fleet.cattle.io.bundle.js +1 -1
- package/models/harvesterhci.io.management.cluster.js +11 -5
- package/models/provisioning.cattle.io.cluster.js +12 -6
- package/models/workload.js +5 -3
- package/nuxt.config.js +69 -25
- package/package.json +108 -109
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/index.vue +46 -1
- package/pages/c/_cluster/apps/charts/install.vue +10 -9
- package/pages/c/_cluster/explorer/index.vue +72 -9
- package/pages/c/_cluster/explorer/tools/index.vue +12 -5
- package/pages/c/_cluster/mcapps/index.vue +1 -1
- package/pages/c/_cluster/settings/brand.vue +0 -40
- package/pages/c/_cluster/settings/links.vue +200 -0
- package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +242 -0
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +284 -0
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +130 -0
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +253 -0
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +115 -0
- package/pages/c/_cluster/uiplugins/index.vue +694 -0
- package/pages/diagnostic.vue +185 -101
- package/pages/docs/_doc.vue +3 -1
- package/pages/home.vue +21 -56
- package/pages/prefs.vue +108 -88
- package/pages/safeMode.vue +17 -0
- package/pages/support/index.vue +23 -15
- package/pkg/dynamic-importer.lib.js +4 -0
- package/plugins/dashboard-store/resource-class.js +2 -2
- package/plugins/formatters.js +15 -0
- package/plugins/plugin.js +56 -4
- package/plugins/steve/mutations.js +1 -1
- package/plugins/steve/subscribe.js +94 -72
- package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
- package/promptRemove/management.cattle.io.globalrole.vue +47 -0
- package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
- package/promptRemove/mixin/roleDeletionCheck.js +97 -0
- package/scripts/publish-shell.sh +1 -1
- package/scripts/sync-shell-deps +37 -0
- package/store/catalog.js +9 -8
- package/store/i18n.js +10 -1
- package/store/prefs.js +16 -0
- package/store/type-map.js +32 -5
- package/store/uiplugins.ts +15 -61
- package/utils/__tests__/object.test.ts +0 -24
- package/utils/__tests__/selector.test.ts +1 -1
- package/utils/dynamic-importer.js +4 -0
- package/utils/grafana.js +2 -6
- package/utils/socket.js +41 -20
- package/utils/string.js +1 -7
- package/utils/validators/formRules/__tests__/index.test.ts +108 -0
- package/utils/validators/formRules/index.ts +9 -1
- package/yarn-error.log +195 -0
- package/pages/plugins.vue +0 -387
- package/server/verdaccio-middleware.js +0 -56
|
@@ -1,12 +1,35 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
|
+
import Select from '@shell/components/form/Select.vue';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
name: 'LocalSelector',
|
|
6
7
|
|
|
8
|
+
components: { Select },
|
|
9
|
+
|
|
10
|
+
props: {
|
|
11
|
+
mode: {
|
|
12
|
+
type: String,
|
|
13
|
+
default: ''
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
|
|
7
17
|
computed: {
|
|
8
18
|
...mapGetters('i18n', ['selectedLocaleLabel', 'availableLocales']),
|
|
9
19
|
|
|
20
|
+
localesOptions() {
|
|
21
|
+
return Object.keys(this.availableLocales).map((value) => {
|
|
22
|
+
return {
|
|
23
|
+
label: this.t(`locale.${ value }`),
|
|
24
|
+
value
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
selectedOption() {
|
|
30
|
+
return Object.keys(this.availableLocales)[Object.values(this.availableLocales).indexOf(this.selectedLocaleLabel)];
|
|
31
|
+
},
|
|
32
|
+
|
|
10
33
|
showLocale() {
|
|
11
34
|
return (this.availableLocales && Object.keys(this.availableLocales).length > 1) || this.dev;
|
|
12
35
|
},
|
|
@@ -17,42 +40,52 @@ export default {
|
|
|
17
40
|
},
|
|
18
41
|
|
|
19
42
|
methods: {
|
|
20
|
-
switchLocale(
|
|
21
|
-
this.$store.dispatch('i18n/switchTo',
|
|
43
|
+
switchLocale($event) {
|
|
44
|
+
this.$store.dispatch('i18n/switchTo', $event);
|
|
22
45
|
},
|
|
23
46
|
}
|
|
24
47
|
};
|
|
25
48
|
</script>
|
|
26
49
|
|
|
27
50
|
<template>
|
|
28
|
-
<div
|
|
29
|
-
<v-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<i class="icon icon-fw icon-sort-down" />
|
|
40
|
-
</a>
|
|
41
|
-
|
|
42
|
-
<template slot="popover">
|
|
43
|
-
<ul class="list-unstyled dropdown" style="margin: -1px;">
|
|
44
|
-
<li v-if="showNone" v-t="'locale.none'" class="hand" @click="switchLocale('none')" />
|
|
45
|
-
<li
|
|
46
|
-
v-for="(label, name) in availableLocales"
|
|
47
|
-
:key="name"
|
|
48
|
-
class="hand"
|
|
49
|
-
@click="switchLocale(name)"
|
|
51
|
+
<div>
|
|
52
|
+
<div v-if="mode === 'login'">
|
|
53
|
+
<div v-if="showLocale">
|
|
54
|
+
<v-popover
|
|
55
|
+
popover-class="localeSelector"
|
|
56
|
+
placement="top"
|
|
57
|
+
trigger="click"
|
|
58
|
+
>
|
|
59
|
+
<a
|
|
60
|
+
data-testid="locale-selector"
|
|
61
|
+
class="locale-chooser"
|
|
50
62
|
>
|
|
51
|
-
{{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
{{ selectedLocaleLabel }}
|
|
64
|
+
<i class="icon icon-fw icon-sort-down" />
|
|
65
|
+
</a>
|
|
66
|
+
<template slot="popover">
|
|
67
|
+
<ul class="list-unstyled dropdown" style="margin: -1px;">
|
|
68
|
+
<li v-if="showNone" v-t="'locale.none'" class="hand" @click="switchLocale('none')" />
|
|
69
|
+
<li
|
|
70
|
+
v-for="(label, name) in availableLocales"
|
|
71
|
+
:key="name"
|
|
72
|
+
class="hand"
|
|
73
|
+
@click="switchLocale(name)"
|
|
74
|
+
>
|
|
75
|
+
{{ label }}
|
|
76
|
+
</li>
|
|
77
|
+
</ul>
|
|
78
|
+
</template>
|
|
79
|
+
</v-popover>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div v-else>
|
|
83
|
+
<Select
|
|
84
|
+
:value="selectedOption"
|
|
85
|
+
:options="localesOptions"
|
|
86
|
+
@input="switchLocale($event)"
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
56
89
|
</div>
|
|
57
90
|
</template>
|
|
58
91
|
|
|
@@ -116,7 +116,12 @@ export default {
|
|
|
116
116
|
getCustomDetailLink: {
|
|
117
117
|
type: Function,
|
|
118
118
|
default: null
|
|
119
|
-
}
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
ignoreFilter: {
|
|
122
|
+
type: Boolean,
|
|
123
|
+
default: false
|
|
124
|
+
},
|
|
120
125
|
},
|
|
121
126
|
|
|
122
127
|
data() {
|
|
@@ -197,7 +202,7 @@ export default {
|
|
|
197
202
|
const isAll = this.$store.getters['isAllNamespaces'];
|
|
198
203
|
|
|
199
204
|
// If the resources isn't namespaced or we want ALL of them, there's nothing to do.
|
|
200
|
-
if ( !this.isNamespaced || (isAll && !this.currentProduct?.hideSystemResources)) {
|
|
205
|
+
if ( !this.isNamespaced || (isAll && !this.currentProduct?.hideSystemResources) || this.ignoreFilter) {
|
|
201
206
|
return this.rows || [];
|
|
202
207
|
}
|
|
203
208
|
|
package/components/SimpleBox.vue
CHANGED
|
@@ -29,10 +29,12 @@ export default {
|
|
|
29
29
|
|
|
30
30
|
<template>
|
|
31
31
|
<div v-if="shown" class="simple-box" v-on="$listeners">
|
|
32
|
-
<div v-if="title || canClose" class="top">
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
<div v-if="title || canClose || $slots.title" class="top">
|
|
33
|
+
<slot name="title">
|
|
34
|
+
<h2 v-if="title">
|
|
35
|
+
{{ title }}
|
|
36
|
+
</h2>
|
|
37
|
+
</slot>
|
|
36
38
|
<div v-if="canClose || pref" class="close-button" @click="closeBox($event)">
|
|
37
39
|
<i class="icon icon-close" />
|
|
38
40
|
</div>
|
|
@@ -20,6 +20,11 @@ import actions from './actions';
|
|
|
20
20
|
// Uncomment for table performance debugging
|
|
21
21
|
// import tableDebug from './debug';
|
|
22
22
|
|
|
23
|
+
// Its quicker to render if we directly supply the components for the formatters
|
|
24
|
+
// rather than just the name of a global component - so create a map of the formatter comoponents
|
|
25
|
+
// NOTE: This is populated by a plugin (formatters.js) to avoid issues with plugins
|
|
26
|
+
export const FORMATTERS = {};
|
|
27
|
+
|
|
23
28
|
export const COLUMN_BREAKPOINTS = {
|
|
24
29
|
/**
|
|
25
30
|
* Only show column if at tablet width or wider
|
|
@@ -35,19 +40,6 @@ export const COLUMN_BREAKPOINTS = {
|
|
|
35
40
|
DESKTOP: 'desktop'
|
|
36
41
|
};
|
|
37
42
|
|
|
38
|
-
// Its quicker to render if we directly supply the components for the formatters
|
|
39
|
-
// rather than just the name of a global component - so create a map of the formatter comoponents
|
|
40
|
-
const FORMATTERS = {};
|
|
41
|
-
|
|
42
|
-
const components = require.context('@shell/components/formatter', false, /[A-Z]\w+\.(vue)$/);
|
|
43
|
-
|
|
44
|
-
components.keys().forEach((fileName) => {
|
|
45
|
-
const componentConfig = components(fileName);
|
|
46
|
-
const componentName = fileName.split('/').pop().split('.')[0];
|
|
47
|
-
|
|
48
|
-
FORMATTERS[componentName] = componentConfig.default || componentConfig;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
43
|
// @TODO:
|
|
52
44
|
// Fixed header/scrolling
|
|
53
45
|
|
|
@@ -334,6 +326,7 @@ export default {
|
|
|
334
326
|
clearTimeout(this._loadingDelayTimer);
|
|
335
327
|
clearTimeout(this._liveColumnsTimer);
|
|
336
328
|
clearTimeout(this._delayedColumnsTimer);
|
|
329
|
+
clearTimeout(this.manualRefreshTimer);
|
|
337
330
|
|
|
338
331
|
const $main = $('main');
|
|
339
332
|
|
|
@@ -348,23 +341,18 @@ export default {
|
|
|
348
341
|
descending(neu, old) {
|
|
349
342
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
350
343
|
},
|
|
351
|
-
|
|
352
344
|
searchQuery(neu, old) {
|
|
353
345
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
354
346
|
},
|
|
355
|
-
|
|
356
347
|
sortFields(neu, old) {
|
|
357
348
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
358
349
|
},
|
|
359
|
-
|
|
360
350
|
groupBy(neu, old) {
|
|
361
351
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
362
352
|
},
|
|
363
|
-
|
|
364
353
|
namespaces(neu, old) {
|
|
365
354
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
366
355
|
},
|
|
367
|
-
|
|
368
356
|
page(neu, old) {
|
|
369
357
|
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
370
358
|
},
|
|
@@ -385,9 +373,11 @@ export default {
|
|
|
385
373
|
|
|
386
374
|
// setTimeout is needed so that this is pushed further back on the JS computing queue
|
|
387
375
|
// because nextTick isn't enough to capture the DOM update for the manual refresh only scenario
|
|
388
|
-
|
|
389
|
-
this.
|
|
390
|
-
|
|
376
|
+
if (old && !neu) {
|
|
377
|
+
this.manualRefreshTimer = setTimeout(() => {
|
|
378
|
+
this.watcherUpdateLiveAndDelayed(neu, old);
|
|
379
|
+
}, 1000);
|
|
380
|
+
}
|
|
391
381
|
}
|
|
392
382
|
},
|
|
393
383
|
|
|
@@ -38,6 +38,11 @@ export default {
|
|
|
38
38
|
noContent: {
|
|
39
39
|
type: Boolean,
|
|
40
40
|
default: false,
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
tabsOnly: {
|
|
44
|
+
type: Boolean,
|
|
45
|
+
default: false,
|
|
41
46
|
}
|
|
42
47
|
},
|
|
43
48
|
|
|
@@ -207,7 +212,7 @@ export default {
|
|
|
207
212
|
</script>
|
|
208
213
|
|
|
209
214
|
<template>
|
|
210
|
-
<div :class="{'side-tabs': !!sideTabs }">
|
|
215
|
+
<div :class="{'side-tabs': !!sideTabs, 'tabs-only': tabsOnly }">
|
|
211
216
|
<ul
|
|
212
217
|
ref="tablist"
|
|
213
218
|
role="tablist"
|
|
@@ -233,6 +238,7 @@ export default {
|
|
|
233
238
|
@click.prevent="select(tab.name, $event)"
|
|
234
239
|
>
|
|
235
240
|
<span>{{ tab.labelDisplay }}</span>
|
|
241
|
+
<span v-if="tab.badge" class="tab-badge">{{ tab.badge }}</span>
|
|
236
242
|
<i v-if="hasIcon(tab)" v-tooltip="t('validation.tab')" class="conditions-alert-icon icon-error icon-lg" />
|
|
237
243
|
</a>
|
|
238
244
|
</li>
|
|
@@ -326,6 +332,15 @@ export default {
|
|
|
326
332
|
color: var(--error);
|
|
327
333
|
}
|
|
328
334
|
}
|
|
335
|
+
|
|
336
|
+
.tab-badge {
|
|
337
|
+
margin-left: 5px;
|
|
338
|
+
background-color: var(--link);
|
|
339
|
+
color: #fff;
|
|
340
|
+
border-radius: 6px;
|
|
341
|
+
padding: 1px 7px;
|
|
342
|
+
font-size: 11px;
|
|
343
|
+
}
|
|
329
344
|
}
|
|
330
345
|
}
|
|
331
346
|
|
|
@@ -337,6 +352,19 @@ export default {
|
|
|
337
352
|
}
|
|
338
353
|
}
|
|
339
354
|
|
|
355
|
+
.tabs-only {
|
|
356
|
+
margin-bottom: 20px;
|
|
357
|
+
|
|
358
|
+
.tab-container {
|
|
359
|
+
display: none;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.tabs {
|
|
363
|
+
border: 0;
|
|
364
|
+
border-bottom: 2px solid var(--border);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
340
368
|
.side-tabs {
|
|
341
369
|
display: flex;
|
|
342
370
|
box-shadow: 0 0 20px var(--shadow);
|
|
@@ -349,7 +377,6 @@ export default {
|
|
|
349
377
|
|
|
350
378
|
// Tabbed component within a tabbed component
|
|
351
379
|
.tab-container & {
|
|
352
|
-
margin: -20px;
|
|
353
380
|
box-shadow: unset;
|
|
354
381
|
}
|
|
355
382
|
|
|
@@ -103,9 +103,14 @@ export default {
|
|
|
103
103
|
return out;
|
|
104
104
|
},
|
|
105
105
|
},
|
|
106
|
+
|
|
107
|
+
methods: {
|
|
108
|
+
displayWarning(row) {
|
|
109
|
+
return !!row.status?.summary && (row.status.summary.desiredReady !== row.status.summary.ready);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
106
112
|
};
|
|
107
113
|
</script>
|
|
108
|
-
|
|
109
114
|
<template>
|
|
110
115
|
<div>
|
|
111
116
|
<Loading v-if="$fetchState.pending" />
|
|
@@ -117,9 +122,9 @@ export default {
|
|
|
117
122
|
:rows="bundles"
|
|
118
123
|
>
|
|
119
124
|
<template #cell:deploymentsReady="{row}">
|
|
120
|
-
<span v-if="row
|
|
125
|
+
<span v-if="displayWarning(row)" class="text-warning">
|
|
121
126
|
{{ row.status.summary.ready }}/{{ row.status.summary.desiredReady }}</span>
|
|
122
|
-
<span v-else>{{ row.status.summary.desiredReady }}</span>
|
|
127
|
+
<span v-else-if="row.status">{{ row.status.summary.desiredReady }}</span>
|
|
123
128
|
</template>
|
|
124
129
|
</ResourceTable>
|
|
125
130
|
</div>
|
|
@@ -84,6 +84,12 @@ export default {
|
|
|
84
84
|
const out = { ...getResourceDefaultState(this.$store.getters['i18n/withFallback'], this.stateKey) };
|
|
85
85
|
|
|
86
86
|
resources.forEach(({ status, metadata }) => {
|
|
87
|
+
if (!status) {
|
|
88
|
+
out[STATES_ENUM.UNKNOWN].count += 1;
|
|
89
|
+
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
const k = status?.summary.ready > 0 && status?.summary.desiredReady === status.summary.ready;
|
|
88
94
|
|
|
89
95
|
if (k) {
|
|
@@ -12,6 +12,8 @@ import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
|
12
12
|
import { asciiLike } from '@shell/utils/string';
|
|
13
13
|
|
|
14
14
|
export default {
|
|
15
|
+
name: 'KeyValue',
|
|
16
|
+
|
|
15
17
|
components: {
|
|
16
18
|
Select,
|
|
17
19
|
TextAreaAutoGrow,
|
|
@@ -22,6 +24,10 @@ export default {
|
|
|
22
24
|
type: [Array, Object],
|
|
23
25
|
default: null,
|
|
24
26
|
},
|
|
27
|
+
defaultValue: {
|
|
28
|
+
type: [Array, Object],
|
|
29
|
+
default: null,
|
|
30
|
+
},
|
|
25
31
|
// If the user supplies this array, then it indicates which keys should be shown as binary
|
|
26
32
|
binaryValueKeys: {
|
|
27
33
|
type: [Array, Object],
|
|
@@ -223,68 +229,13 @@ export default {
|
|
|
223
229
|
}
|
|
224
230
|
},
|
|
225
231
|
data() {
|
|
226
|
-
const rows =
|
|
227
|
-
|
|
228
|
-
if ( this.asMap ) {
|
|
229
|
-
const input = this.value || {};
|
|
230
|
-
|
|
231
|
-
Object.keys(input).forEach((key) => {
|
|
232
|
-
let value = input[key];
|
|
233
|
-
const decodedValue = base64Decode(input[key]);
|
|
234
|
-
const asciiValue = asciiLike(decodedValue);
|
|
235
|
-
|
|
236
|
-
if ( this.handleBase64 && asciiValue) {
|
|
237
|
-
value = base64Decode(value);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
rows.push({
|
|
241
|
-
key,
|
|
242
|
-
value,
|
|
243
|
-
binary: this.displayValuesAsBinary || (this.handleBase64 && !asciiValue),
|
|
244
|
-
canEncode: this.handleBase64 && asciiValue,
|
|
245
|
-
supported: true,
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
} else {
|
|
249
|
-
const input = this.value || [];
|
|
250
|
-
|
|
251
|
-
for ( const row of input ) {
|
|
252
|
-
let value = row[this.valueName] || '';
|
|
253
|
-
const decodedValue = base64Decode(row[this.valueName]);
|
|
254
|
-
const asciiValue = asciiLike(decodedValue);
|
|
255
|
-
|
|
256
|
-
if ( this.handleBase64 && asciiValue) {
|
|
257
|
-
value = base64Decode(value);
|
|
258
|
-
}
|
|
259
|
-
const entry = {
|
|
260
|
-
[this.keyName]: row[this.keyName] || '',
|
|
261
|
-
[this.valueName]: value,
|
|
262
|
-
binary: this.displayValuesAsBinary || (this.handleBase64 && !asciiValue),
|
|
263
|
-
canEncode: this.handleBase64 && asciiValue,
|
|
264
|
-
supported: this.supported(row),
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
this.preserveKeys?.map((k) => {
|
|
268
|
-
if ( typeof row[k] !== 'undefined' ) {
|
|
269
|
-
entry[k] = row[k];
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
rows.push(entry);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
if ( !rows.length && this.initialEmptyRow ) {
|
|
276
|
-
rows.push({
|
|
277
|
-
[this.keyName]: '',
|
|
278
|
-
[this.valueName]: '',
|
|
279
|
-
binary: false,
|
|
280
|
-
canEncode: this.handleBase64,
|
|
281
|
-
supported: true
|
|
282
|
-
});
|
|
283
|
-
}
|
|
232
|
+
const rows = this.getRows(this.value);
|
|
284
233
|
|
|
285
234
|
return { rows };
|
|
286
235
|
},
|
|
236
|
+
|
|
287
237
|
computed: {
|
|
238
|
+
|
|
288
239
|
isView() {
|
|
289
240
|
return this.mode === _VIEW;
|
|
290
241
|
},
|
|
@@ -315,7 +266,78 @@ export default {
|
|
|
315
266
|
created() {
|
|
316
267
|
this.queueUpdate = debounce(this.update, 500);
|
|
317
268
|
},
|
|
269
|
+
watch: {
|
|
270
|
+
defaultValue(neu) {
|
|
271
|
+
if (Array.isArray(neu)) {
|
|
272
|
+
this.rows = this.getRows(neu);
|
|
273
|
+
this.$emit('input', neu);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
318
277
|
methods: {
|
|
278
|
+
getRows(value) {
|
|
279
|
+
const rows = [];
|
|
280
|
+
|
|
281
|
+
if ( this.asMap ) {
|
|
282
|
+
const input = value || {};
|
|
283
|
+
|
|
284
|
+
Object.keys(input).forEach((key) => {
|
|
285
|
+
let value = input[key];
|
|
286
|
+
const decodedValue = base64Decode(input[key]);
|
|
287
|
+
const asciiValue = asciiLike(decodedValue);
|
|
288
|
+
|
|
289
|
+
if ( this.handleBase64 && asciiValue) {
|
|
290
|
+
value = base64Decode(value);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
rows.push({
|
|
294
|
+
key,
|
|
295
|
+
value,
|
|
296
|
+
binary: this.displayValuesAsBinary || (this.handleBase64 && !asciiValue),
|
|
297
|
+
canEncode: this.handleBase64 && asciiValue,
|
|
298
|
+
supported: true,
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
} else {
|
|
302
|
+
const input = value || [];
|
|
303
|
+
|
|
304
|
+
for ( const row of input ) {
|
|
305
|
+
let value = row[this.valueName] || '';
|
|
306
|
+
const decodedValue = base64Decode(row[this.valueName]);
|
|
307
|
+
const asciiValue = asciiLike(decodedValue);
|
|
308
|
+
|
|
309
|
+
if ( this.handleBase64 && asciiValue) {
|
|
310
|
+
value = base64Decode(value);
|
|
311
|
+
}
|
|
312
|
+
const entry = {
|
|
313
|
+
[this.keyName]: row[this.keyName] || '',
|
|
314
|
+
[this.valueName]: value,
|
|
315
|
+
binary: this.displayValuesAsBinary || (this.handleBase64 && !asciiValue),
|
|
316
|
+
canEncode: this.handleBase64 && asciiValue,
|
|
317
|
+
supported: this.supported(row),
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
this.preserveKeys?.map((k) => {
|
|
321
|
+
if ( typeof row[k] !== 'undefined' ) {
|
|
322
|
+
entry[k] = row[k];
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
rows.push(entry);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if ( !rows.length && this.initialEmptyRow ) {
|
|
329
|
+
rows.push({
|
|
330
|
+
[this.keyName]: '',
|
|
331
|
+
[this.valueName]: '',
|
|
332
|
+
binary: false,
|
|
333
|
+
canEncode: this.handleBase64,
|
|
334
|
+
supported: true
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return rows;
|
|
339
|
+
},
|
|
340
|
+
|
|
319
341
|
add(key = '', value = '') {
|
|
320
342
|
const obj = {
|
|
321
343
|
...this.defaultAddData,
|
|
@@ -5,7 +5,7 @@ import { get, set } from '@shell/utils/object';
|
|
|
5
5
|
import { sortBy } from '@shell/utils/sort';
|
|
6
6
|
import { NAMESPACE } from '@shell/config/types';
|
|
7
7
|
import { DESCRIPTION } from '@shell/config/labels-annotations';
|
|
8
|
-
import { _VIEW, _EDIT } from '@shell/config/query-params';
|
|
8
|
+
import { _VIEW, _EDIT, _CREATE } from '@shell/config/query-params';
|
|
9
9
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
10
10
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
11
11
|
|
|
@@ -224,15 +224,21 @@ export default {
|
|
|
224
224
|
const namespaces = this.namespacesOverride || this.$store.getters[`${ currentStore }/all`](this.namespaceType);
|
|
225
225
|
|
|
226
226
|
const filtered = namespaces.filter( this.namespaceFilter || ((namespace) => {
|
|
227
|
+
// By default, include the namespace in the dropdown.
|
|
228
|
+
let out = true;
|
|
229
|
+
|
|
227
230
|
if (this.currentProduct?.hideSystemResources) {
|
|
228
231
|
// Filter out the namespace
|
|
229
232
|
// if it is a system namespace or if it is managed by
|
|
230
233
|
// Fleet.
|
|
231
|
-
|
|
234
|
+
out = !namespace.isSystem && !namespace.isFleetManaged;
|
|
232
235
|
}
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
if (this.mode === _CREATE) {
|
|
238
|
+
out = out && !!namespace.links.update;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return out;
|
|
236
242
|
}));
|
|
237
243
|
|
|
238
244
|
const withLabels = filtered.map(this.namespaceMapper || ((obj) => {
|
|
@@ -85,7 +85,11 @@ export default {
|
|
|
85
85
|
showConditions() {
|
|
86
86
|
const inStore = this.$store.getters['currentStore'](this.value.type);
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
if ( this.$store.getters[`${ inStore }/schemaFor`](this.value.type) ) {
|
|
89
|
+
return this.isView && this.needConditions && this.value?.type && this.$store.getters[`${ inStore }/pathExistsInSchema`](this.value.type, 'status.conditions');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return false;
|
|
89
93
|
},
|
|
90
94
|
showEvents() {
|
|
91
95
|
return this.isView && this.needEvents && this.hasEvents && (this.events.length || this.alwaysShowEvents);
|
|
@@ -25,12 +25,8 @@ export default {
|
|
|
25
25
|
return this.row?.detailLocation;
|
|
26
26
|
},
|
|
27
27
|
|
|
28
|
-
clusterHasIssues() {
|
|
29
|
-
return this.row.status?.conditions?.some(condition => condition.error === true);
|
|
30
|
-
},
|
|
31
|
-
|
|
32
28
|
statusErrorConditions() {
|
|
33
|
-
if (this.
|
|
29
|
+
if (this.row.hasError) {
|
|
34
30
|
return this.row?.status.conditions.filter(condition => condition.error === true);
|
|
35
31
|
}
|
|
36
32
|
|
|
@@ -38,7 +34,7 @@ export default {
|
|
|
38
34
|
},
|
|
39
35
|
|
|
40
36
|
formattedConditions() {
|
|
41
|
-
if (this.
|
|
37
|
+
if (this.row.hasError) {
|
|
42
38
|
const filteredConditions = this.statusErrorConditions;
|
|
43
39
|
const formattedTooltip = [];
|
|
44
40
|
|
|
@@ -69,7 +65,7 @@ export default {
|
|
|
69
65
|
class="template-upgrade-icon icon-alert icon"
|
|
70
66
|
/>
|
|
71
67
|
<i
|
|
72
|
-
v-if="
|
|
68
|
+
v-if="row.hasError"
|
|
73
69
|
v-tooltip="{ content: `<div>${formattedConditions}</div>`, html: true }"
|
|
74
70
|
class="conditions-alert-icon icon-error icon-lg"
|
|
75
71
|
/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
|
-
import { NAMESPACE_FILTERS,
|
|
3
|
+
import { NAMESPACE_FILTERS, ALL_NAMESPACES } from '@shell/store/prefs';
|
|
4
4
|
import { NAMESPACE, MANAGEMENT } from '@shell/config/types';
|
|
5
5
|
import { sortBy } from '@shell/utils/sort';
|
|
6
6
|
import { isArray, addObjects, findBy, filterBy } from '@shell/utils/array';
|
|
@@ -322,8 +322,8 @@ export default {
|
|
|
322
322
|
|
|
323
323
|
methods: {
|
|
324
324
|
filterNamespaces(namespaces) {
|
|
325
|
-
if (this.$store.getters['prefs/get'](
|
|
326
|
-
// If
|
|
325
|
+
if (this.$store.getters['prefs/get'](ALL_NAMESPACES)) {
|
|
326
|
+
// If all namespaces options are turned on in the user preferences,
|
|
327
327
|
// return all namespaces including system namespaces and RBAC
|
|
328
328
|
// management namespaces.
|
|
329
329
|
return namespaces;
|