@rancher/shell 0.3.1 → 0.3.3
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/styles/global/_gauges.scss +1 -1
- package/assets/styles/global/_layout.scss +4 -0
- package/assets/styles/themes/_dark.scss +1 -0
- package/assets/translations/en-us.yaml +6 -1
- package/assets/translations/zh-hans.yaml +175 -44
- package/components/ActionMenu.vue +28 -7
- package/components/DetailTop.vue +14 -1
- package/components/ExtensionPanel.vue +42 -0
- package/components/IconOrSvg.vue +31 -2
- package/components/ResourceDetail/Masthead.vue +16 -3
- package/components/ResourceList/index.vue +15 -2
- package/components/ResourceTable.vue +3 -1
- package/components/SortableTable/THead.vue +6 -9
- package/components/SortableTable/filtering.js +1 -1
- package/components/SortableTable/selection.js +15 -3
- package/components/Tabbed/Tab.vue +1 -1
- package/components/form/InputWithSelect.vue +1 -0
- package/components/form/ResourceTabs/index.vue +23 -0
- package/components/nav/Header.vue +69 -5
- package/config/harvester-manager-types.js +1 -0
- package/config/product/backup.js +1 -1
- package/config/query-params.js +1 -0
- package/config/uiplugins.js +3 -3
- package/core/plugin-helpers.js +171 -0
- package/core/plugin.ts +61 -1
- package/core/plugins.js +33 -0
- package/core/types.ts +128 -2
- package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
- package/edit/fleet.cattle.io.gitrepo.vue +12 -3
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +14 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +21 -18
- package/package.json +2 -1
- package/pages/c/_cluster/apps/charts/index.vue +17 -0
- package/pages/c/_cluster/explorer/index.vue +39 -0
- package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +17 -3
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
- package/pages/c/_cluster/uiplugins/index.vue +18 -4
- package/plugins/dashboard-store/resource-class.js +16 -1
- package/rancher-components/components/Banner/Banner.vue +1 -0
- package/store/action-menu.js +4 -3
- package/store/prefs.js +19 -12
- package/store/type-map.js +26 -0
- package/types/shell/index.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -138,6 +138,7 @@
|
|
|
138
138
|
"vue-server-renderer": "2.6.14",
|
|
139
139
|
"vue-shortkey": "3.1.7",
|
|
140
140
|
"vue-template-compiler": "2.6.14",
|
|
141
|
+
"vue-virtual-scroll-list": "^2.3.4",
|
|
141
142
|
"vue2-transitions": "0.3.0",
|
|
142
143
|
"vuedraggable": "2.24.3",
|
|
143
144
|
"vuex": "3.6.2",
|
|
@@ -21,6 +21,7 @@ import { CATALOG } from '@shell/config/labels-annotations';
|
|
|
21
21
|
import { isUIPlugin } from '@shell/config/uiplugins';
|
|
22
22
|
|
|
23
23
|
export default {
|
|
24
|
+
name: 'Charts',
|
|
24
25
|
components: {
|
|
25
26
|
AsyncButton,
|
|
26
27
|
Banner,
|
|
@@ -53,6 +54,7 @@ export default {
|
|
|
53
54
|
searchQuery: null,
|
|
54
55
|
showDeprecated: null,
|
|
55
56
|
showHidden: null,
|
|
57
|
+
isPspLegacy: false,
|
|
56
58
|
chartOptions: [
|
|
57
59
|
{
|
|
58
60
|
label: 'Browse',
|
|
@@ -239,6 +241,14 @@ export default {
|
|
|
239
241
|
}
|
|
240
242
|
},
|
|
241
243
|
|
|
244
|
+
created() {
|
|
245
|
+
const release = this.currentCluster?.status?.version.gitVersion || '';
|
|
246
|
+
const isRKE2 = release.includes('rke2');
|
|
247
|
+
const version = release.match(/\d+/g);
|
|
248
|
+
|
|
249
|
+
this.isPspLegacy = version?.length ? isRKE2 && (+version[0] === 1 && +version[1] < 25) : false;
|
|
250
|
+
},
|
|
251
|
+
|
|
242
252
|
methods: {
|
|
243
253
|
colorForChart(chart) {
|
|
244
254
|
const repos = this.repoOptions;
|
|
@@ -363,6 +373,13 @@ export default {
|
|
|
363
373
|
@clicked="(row) => selectChart(row)"
|
|
364
374
|
/>
|
|
365
375
|
</div>
|
|
376
|
+
|
|
377
|
+
<Banner
|
|
378
|
+
v-if="isPspLegacy"
|
|
379
|
+
color="warning"
|
|
380
|
+
:label="t('catalog.chart.banner.legacy')"
|
|
381
|
+
/>
|
|
382
|
+
|
|
366
383
|
<TypeDescription resource="chart" />
|
|
367
384
|
<div class="left-right-split">
|
|
368
385
|
<Select
|
|
@@ -40,6 +40,9 @@ import { isEmpty } from '@shell/utils/object';
|
|
|
40
40
|
import ConfigBadge from './ConfigBadge';
|
|
41
41
|
import EventsTable from './EventsTable';
|
|
42
42
|
import { fetchClusterResources } from './explorer-utils';
|
|
43
|
+
import SimpleBox from '@shell/components/SimpleBox';
|
|
44
|
+
import { ExtensionPoint, CardLocation } from '@shell/core/types';
|
|
45
|
+
import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
|
|
43
46
|
|
|
44
47
|
export const RESOURCES = [NAMESPACE, INGRESS, PV, WORKLOAD_TYPES.DEPLOYMENT, WORKLOAD_TYPES.STATEFUL_SET, WORKLOAD_TYPES.JOB, WORKLOAD_TYPES.DAEMON_SET, SERVICE];
|
|
45
48
|
|
|
@@ -71,6 +74,7 @@ export default {
|
|
|
71
74
|
EmberPage,
|
|
72
75
|
ConfigBadge,
|
|
73
76
|
EventsTable,
|
|
77
|
+
SimpleBox,
|
|
74
78
|
},
|
|
75
79
|
|
|
76
80
|
mixins: [metricPoller],
|
|
@@ -126,6 +130,7 @@ export default {
|
|
|
126
130
|
ETCD_METRICS_SUMMARY_URL,
|
|
127
131
|
clusterCounts,
|
|
128
132
|
selectedTab: 'cluster-events',
|
|
133
|
+
extensionCards: getApplicableExtensionEnhancements(this, ExtensionPoint.CARD, CardLocation.CLUSTER_DASHBOARD_CARD, this.$route),
|
|
129
134
|
};
|
|
130
135
|
},
|
|
131
136
|
|
|
@@ -492,6 +497,27 @@ export default {
|
|
|
492
497
|
/>
|
|
493
498
|
</div>
|
|
494
499
|
|
|
500
|
+
<!-- extension cards -->
|
|
501
|
+
<div
|
|
502
|
+
v-if="extensionCards.length"
|
|
503
|
+
class="extension-card-container mt-20"
|
|
504
|
+
>
|
|
505
|
+
<SimpleBox
|
|
506
|
+
v-for="item, i in extensionCards"
|
|
507
|
+
:key="`extensionCards${i}`"
|
|
508
|
+
class="extension-card"
|
|
509
|
+
:style="item.style"
|
|
510
|
+
>
|
|
511
|
+
<h3>
|
|
512
|
+
{{ item.label }}
|
|
513
|
+
</h3>
|
|
514
|
+
<component
|
|
515
|
+
:is="item.component"
|
|
516
|
+
:resource="currentCluster"
|
|
517
|
+
/>
|
|
518
|
+
</SimpleBox>
|
|
519
|
+
</div>
|
|
520
|
+
|
|
495
521
|
<h3
|
|
496
522
|
v-if="!hasV1Monitoring && hasStats"
|
|
497
523
|
class="mt-40"
|
|
@@ -631,6 +657,19 @@ export default {
|
|
|
631
657
|
</template>
|
|
632
658
|
|
|
633
659
|
<style lang="scss" scoped>
|
|
660
|
+
.extension-card-container {
|
|
661
|
+
display: grid;
|
|
662
|
+
grid-template-columns: repeat(auto-fit, minmax(calc((100%/3) - 40px), 1fr));
|
|
663
|
+
grid-column-gap: 15px;
|
|
664
|
+
grid-row-gap: 20px;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
@media only screen and (max-width: map-get($breakpoints, "--viewport-9")) {
|
|
668
|
+
.extension-card-container {
|
|
669
|
+
grid-template-columns: 1fr !important;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
634
673
|
.cluster-dashboard-glance {
|
|
635
674
|
border-top: 1px solid var(--border);
|
|
636
675
|
border-bottom: 1px solid var(--border);
|
|
@@ -181,12 +181,14 @@ export default {
|
|
|
181
181
|
<div class="dialog-buttons mt-20">
|
|
182
182
|
<button
|
|
183
183
|
class="btn role-secondary"
|
|
184
|
+
data-testid="dev-install-ext-modal-cancel-btn"
|
|
184
185
|
@click="closeDialog()"
|
|
185
186
|
>
|
|
186
187
|
{{ t('generic.cancel') }}
|
|
187
188
|
</button>
|
|
188
189
|
<AsyncButton
|
|
189
190
|
mode="load"
|
|
191
|
+
data-testid="dev-install-ext-modal-install-btn"
|
|
190
192
|
@click="loadPlugin"
|
|
191
193
|
/>
|
|
192
194
|
</div>
|
|
@@ -243,6 +243,7 @@ export default {
|
|
|
243
243
|
label-key="plugins.install.version"
|
|
244
244
|
:options="versionOptions"
|
|
245
245
|
class="version-selector mt-10"
|
|
246
|
+
data-testid="install-ext-modal-select-version"
|
|
246
247
|
/>
|
|
247
248
|
<div v-else>
|
|
248
249
|
{{ t('plugins.install.version') }} {{ version }}
|
|
@@ -252,12 +253,14 @@ export default {
|
|
|
252
253
|
<button
|
|
253
254
|
:disabled="busy"
|
|
254
255
|
class="btn role-secondary"
|
|
256
|
+
data-testid="install-ext-modal-cancel-btn"
|
|
255
257
|
@click="closeDialog(false)"
|
|
256
258
|
>
|
|
257
259
|
{{ t('generic.cancel') }}
|
|
258
260
|
</button>
|
|
259
261
|
<AsyncButton
|
|
260
262
|
:mode="buttonMode"
|
|
263
|
+
data-testid="install-ext-modal-install-btn"
|
|
261
264
|
@click="install"
|
|
262
265
|
/>
|
|
263
266
|
</div>
|
|
@@ -113,10 +113,12 @@ export default {
|
|
|
113
113
|
<div
|
|
114
114
|
v-if="showSlideIn"
|
|
115
115
|
class="glass"
|
|
116
|
+
data-testid="extension-details-bg"
|
|
116
117
|
@click="hide()"
|
|
117
118
|
/>
|
|
118
119
|
<div
|
|
119
120
|
class="slideIn"
|
|
121
|
+
data-testid="extension-details"
|
|
120
122
|
:class="{'hide': false, 'slideIn__show': showSlideIn}"
|
|
121
123
|
>
|
|
122
124
|
<div
|
|
@@ -142,8 +144,11 @@ export default {
|
|
|
142
144
|
>
|
|
143
145
|
</div>
|
|
144
146
|
<div class="plugin-title">
|
|
145
|
-
<h2
|
|
146
|
-
|
|
147
|
+
<h2
|
|
148
|
+
class="slideIn__header"
|
|
149
|
+
data-testid="extension-details-title"
|
|
150
|
+
>
|
|
151
|
+
{{ info.label }}
|
|
147
152
|
</h2>
|
|
148
153
|
<p class="plugin-description">
|
|
149
154
|
{{ info.description }}
|
|
@@ -153,6 +158,7 @@ export default {
|
|
|
153
158
|
<div class="slideIn__header__buttons">
|
|
154
159
|
<div
|
|
155
160
|
class="slideIn__header__button"
|
|
161
|
+
data-testid="extension-details-close"
|
|
156
162
|
@click="showSlideIn = false"
|
|
157
163
|
>
|
|
158
164
|
<i class="icon icon-close" />
|
|
@@ -224,8 +230,11 @@ export default {
|
|
|
224
230
|
</div>
|
|
225
231
|
<div v-if="!info.versions.length">
|
|
226
232
|
<h3>
|
|
227
|
-
{{ t('plugins.
|
|
233
|
+
{{ t('plugins.info.versions') }}
|
|
228
234
|
</h3>
|
|
235
|
+
<div class="version-link version-active version-builtin">
|
|
236
|
+
{{ info.displayVersion }}
|
|
237
|
+
</div>
|
|
229
238
|
</div>
|
|
230
239
|
</div>
|
|
231
240
|
</div>
|
|
@@ -236,6 +245,7 @@ export default {
|
|
|
236
245
|
position: fixed;
|
|
237
246
|
top: 0;
|
|
238
247
|
left: 0;
|
|
248
|
+
z-index: 1;
|
|
239
249
|
|
|
240
250
|
$slideout-width: 35%;
|
|
241
251
|
$title-height: 50px;
|
|
@@ -345,6 +355,10 @@ export default {
|
|
|
345
355
|
color: var(--link-text);
|
|
346
356
|
background: var(--link);
|
|
347
357
|
}
|
|
358
|
+
|
|
359
|
+
&.version-builtin {
|
|
360
|
+
display: inline-block;
|
|
361
|
+
}
|
|
348
362
|
}
|
|
349
363
|
|
|
350
364
|
&__header {
|
|
@@ -107,6 +107,7 @@ export default {
|
|
|
107
107
|
name="confirm-uiplugins-remove"
|
|
108
108
|
:title="t('plugins.setup.remove.title')"
|
|
109
109
|
mode="disable"
|
|
110
|
+
data-testid="disable-ext-modal"
|
|
110
111
|
@okay="doRemove"
|
|
111
112
|
>
|
|
112
113
|
<template>
|
|
@@ -121,6 +122,7 @@ export default {
|
|
|
121
122
|
v-model="removeRepo"
|
|
122
123
|
:primary="true"
|
|
123
124
|
label-key="plugins.setup.remove.registry.title"
|
|
125
|
+
data-testid="disable-ext-modal-remove-repo"
|
|
124
126
|
/>
|
|
125
127
|
<div class="checkbox-info">
|
|
126
128
|
{{ t('plugins.setup.remove.registry.prompt') }}
|
|
@@ -84,12 +84,14 @@ export default {
|
|
|
84
84
|
<button
|
|
85
85
|
:disabled="busy"
|
|
86
86
|
class="btn role-secondary"
|
|
87
|
+
data-testid="uninstall-ext-modal-cancel-btn"
|
|
87
88
|
@click="closeDialog(false)"
|
|
88
89
|
>
|
|
89
90
|
{{ t('generic.cancel') }}
|
|
90
91
|
</button>
|
|
91
92
|
<AsyncButton
|
|
92
93
|
mode="uninstall"
|
|
94
|
+
data-testid="uninstall-ext-modal-uninstall-btn"
|
|
93
95
|
@click="uninstall()"
|
|
94
96
|
/>
|
|
95
97
|
</div>
|
|
@@ -221,10 +221,12 @@ export default {
|
|
|
221
221
|
const chart = all.find(c => c.name === p.name);
|
|
222
222
|
|
|
223
223
|
if (!chart) {
|
|
224
|
-
// A
|
|
224
|
+
// A plugin is loaded, but there is no chart, so add an item so that it shows up
|
|
225
|
+
const rancher = typeof p.metadata?.rancher === 'object' ? p.metadata.rancher : {};
|
|
226
|
+
const label = rancher[UI_PLUGIN_CHART_ANNOTATIONS.DISPLAY_NAME] || p.name;
|
|
225
227
|
const item = {
|
|
226
228
|
name: p.name,
|
|
227
|
-
label
|
|
229
|
+
label,
|
|
228
230
|
description: p.metadata?.description,
|
|
229
231
|
icon: p.metadata?.icon,
|
|
230
232
|
id: p.id,
|
|
@@ -492,10 +494,13 @@ export default {
|
|
|
492
494
|
<template>
|
|
493
495
|
<div class="plugins">
|
|
494
496
|
<div class="plugin-header">
|
|
495
|
-
<h2
|
|
497
|
+
<h2 data-testid="extensions-page-title">
|
|
498
|
+
{{ t('plugins.title') }}
|
|
499
|
+
</h2>
|
|
496
500
|
<div
|
|
497
501
|
v-if="reloadRequired"
|
|
498
502
|
class="plugin-reload-banner mr-20"
|
|
503
|
+
data-testid="extension-reload-banner"
|
|
499
504
|
>
|
|
500
505
|
<i class="icon icon-checkmark mr-10" />
|
|
501
506
|
<span>
|
|
@@ -503,6 +508,7 @@ export default {
|
|
|
503
508
|
</span>
|
|
504
509
|
<button
|
|
505
510
|
class="ml-10 btn btn-sm role-primary"
|
|
511
|
+
data-testid="extension-reload-banner-reload-btn"
|
|
506
512
|
@click="reload()"
|
|
507
513
|
>
|
|
508
514
|
{{ t('generic.reload') }}
|
|
@@ -514,6 +520,7 @@ export default {
|
|
|
514
520
|
aria-haspopup="true"
|
|
515
521
|
type="button"
|
|
516
522
|
class="btn actions role-secondary"
|
|
523
|
+
data-testid="extensions-page-menu"
|
|
517
524
|
@click="setMenu"
|
|
518
525
|
>
|
|
519
526
|
<i class="icon icon-actions" />
|
|
@@ -555,15 +562,18 @@ export default {
|
|
|
555
562
|
<Tabbed
|
|
556
563
|
ref="tabs"
|
|
557
564
|
:tabs-only="true"
|
|
565
|
+
data-testid="extension-tabs"
|
|
558
566
|
@changed="filterChanged"
|
|
559
567
|
>
|
|
560
568
|
<Tab
|
|
561
569
|
name="installed"
|
|
570
|
+
data-testid="extension-tab-installed"
|
|
562
571
|
label-key="plugins.tabs.installed"
|
|
563
572
|
:weight="20"
|
|
564
573
|
/>
|
|
565
574
|
<Tab
|
|
566
575
|
name="available"
|
|
576
|
+
data-testid="extension-tab-available"
|
|
567
577
|
label-key="plugins.tabs.available"
|
|
568
578
|
:weight="19"
|
|
569
579
|
/>
|
|
@@ -606,6 +616,7 @@ export default {
|
|
|
606
616
|
v-for="plugin in list"
|
|
607
617
|
:key="plugin.name"
|
|
608
618
|
class="plugin"
|
|
619
|
+
:data-testid="`extension-card-${plugin.name}`"
|
|
609
620
|
@click="showPluginDetail(plugin)"
|
|
610
621
|
>
|
|
611
622
|
<div
|
|
@@ -709,6 +720,7 @@ export default {
|
|
|
709
720
|
<button
|
|
710
721
|
v-if="!plugin.builtin"
|
|
711
722
|
class="btn role-secondary"
|
|
723
|
+
:data-testid="`extension-card-uninstall-btn-${plugin.name}`"
|
|
712
724
|
@click="showUninstallDialog(plugin, $event)"
|
|
713
725
|
>
|
|
714
726
|
{{ t('plugins.uninstall.label') }}
|
|
@@ -716,6 +728,7 @@ export default {
|
|
|
716
728
|
<button
|
|
717
729
|
v-if="plugin.upgrade"
|
|
718
730
|
class="btn role-secondary"
|
|
731
|
+
:data-testid="`extension-card-update-btn-${plugin.name}`"
|
|
719
732
|
@click="showInstallDialog(plugin, 'update', $event)"
|
|
720
733
|
>
|
|
721
734
|
{{ t('plugins.update.label') }}
|
|
@@ -723,6 +736,7 @@ export default {
|
|
|
723
736
|
<button
|
|
724
737
|
v-if="!plugin.upgrade && plugin.versions.length > 1"
|
|
725
738
|
class="btn role-secondary"
|
|
739
|
+
:data-testid="`extension-card-rollback-btn-${plugin.name}`"
|
|
726
740
|
@click="showInstallDialog(plugin, 'rollback', $event)"
|
|
727
741
|
>
|
|
728
742
|
{{ t('plugins.rollback.label') }}
|
|
@@ -734,6 +748,7 @@ export default {
|
|
|
734
748
|
>
|
|
735
749
|
<button
|
|
736
750
|
class="btn role-secondary"
|
|
751
|
+
:data-testid="`extension-card-install-btn-${plugin.name}`"
|
|
737
752
|
@click="showInstallDialog(plugin, 'install', $event)"
|
|
738
753
|
>
|
|
739
754
|
{{ t('plugins.install.label') }}
|
|
@@ -867,7 +882,6 @@ export default {
|
|
|
867
882
|
width: 40px;
|
|
868
883
|
-o-object-fit: contain;
|
|
869
884
|
object-fit: contain;
|
|
870
|
-
position: relative;
|
|
871
885
|
top: 2px;
|
|
872
886
|
left: 2px;
|
|
873
887
|
}
|
|
@@ -37,6 +37,9 @@ import Vue from 'vue';
|
|
|
37
37
|
|
|
38
38
|
import { normalizeType } from './normalize';
|
|
39
39
|
|
|
40
|
+
import { ExtensionPoint, ActionLocation } from '@shell/core/types';
|
|
41
|
+
import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
|
|
42
|
+
|
|
40
43
|
const STRING_LIKE_TYPES = [
|
|
41
44
|
'string',
|
|
42
45
|
'date',
|
|
@@ -851,7 +854,11 @@ export default class Resource {
|
|
|
851
854
|
|
|
852
855
|
// You can add custom actions by overriding your own availableActions (and probably reading super._availableActions)
|
|
853
856
|
get _availableActions() {
|
|
854
|
-
|
|
857
|
+
// get menu actions available by plugins configuration
|
|
858
|
+
const currentRoute = this.currentRouter().app._route;
|
|
859
|
+
const extensionMenuActions = getApplicableExtensionEnhancements(this.$rootState, ExtensionPoint.ACTION, ActionLocation.TABLE, currentRoute, this);
|
|
860
|
+
|
|
861
|
+
let all = [
|
|
855
862
|
{ divider: true },
|
|
856
863
|
{
|
|
857
864
|
action: this.canUpdate ? 'goToEdit' : 'goToViewConfig',
|
|
@@ -899,6 +906,13 @@ export default class Resource {
|
|
|
899
906
|
},
|
|
900
907
|
];
|
|
901
908
|
|
|
909
|
+
// Extension actions get added to the end, so add a divider if there are any
|
|
910
|
+
if (extensionMenuActions.length) {
|
|
911
|
+
// Add a divider first
|
|
912
|
+
all.push({ divider: true });
|
|
913
|
+
all = all.concat(extensionMenuActions);
|
|
914
|
+
}
|
|
915
|
+
|
|
902
916
|
return all;
|
|
903
917
|
}
|
|
904
918
|
|
|
@@ -1051,6 +1065,7 @@ export default class Resource {
|
|
|
1051
1065
|
async _save(opt = {}) {
|
|
1052
1066
|
delete this.__rehydrate;
|
|
1053
1067
|
delete this.__clone;
|
|
1068
|
+
|
|
1054
1069
|
const forNew = !this.id;
|
|
1055
1070
|
|
|
1056
1071
|
const errors = await this.validationErrors(this, opt.ignoreFields);
|
package/store/action-menu.js
CHANGED
|
@@ -22,9 +22,10 @@ export const state = function() {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export const getters = {
|
|
25
|
-
showing:
|
|
26
|
-
elem:
|
|
27
|
-
event:
|
|
25
|
+
showing: state => state.show,
|
|
26
|
+
elem: state => state.elem,
|
|
27
|
+
event: state => state.event,
|
|
28
|
+
resources: state => state.resources,
|
|
28
29
|
|
|
29
30
|
options(state) {
|
|
30
31
|
let selected = state.resources;
|
package/store/prefs.js
CHANGED
|
@@ -136,12 +136,13 @@ export const state = function() {
|
|
|
136
136
|
return {
|
|
137
137
|
cookiesLoaded: false,
|
|
138
138
|
data: {},
|
|
139
|
+
definitions,
|
|
139
140
|
};
|
|
140
141
|
};
|
|
141
142
|
|
|
142
143
|
export const getters = {
|
|
143
144
|
get: state => (key) => {
|
|
144
|
-
const definition = definitions[key];
|
|
145
|
+
const definition = state.definitions[key];
|
|
145
146
|
|
|
146
147
|
if (!definition) {
|
|
147
148
|
throw new Error(`Unknown preference: ${ key }`);
|
|
@@ -159,7 +160,7 @@ export const getters = {
|
|
|
159
160
|
},
|
|
160
161
|
|
|
161
162
|
defaultValue: state => (key) => {
|
|
162
|
-
const definition = definitions[key];
|
|
163
|
+
const definition = state.definitions[key];
|
|
163
164
|
|
|
164
165
|
if (!definition) {
|
|
165
166
|
throw new Error(`Unknown preference: ${ key }`);
|
|
@@ -169,7 +170,7 @@ export const getters = {
|
|
|
169
170
|
},
|
|
170
171
|
|
|
171
172
|
options: state => (key) => {
|
|
172
|
-
const definition = definitions[key];
|
|
173
|
+
const definition = state.definitions[key];
|
|
173
174
|
|
|
174
175
|
if (!definition) {
|
|
175
176
|
throw new Error(`Unknown preference: ${ key }`);
|
|
@@ -252,19 +253,25 @@ export const mutations = {
|
|
|
252
253
|
},
|
|
253
254
|
|
|
254
255
|
reset(state) {
|
|
255
|
-
for (const key in definitions) {
|
|
256
|
-
if ( definitions[key]?.asCookie ) {
|
|
256
|
+
for (const key in state.definitions) {
|
|
257
|
+
if ( state.definitions[key]?.asCookie ) {
|
|
257
258
|
continue;
|
|
258
259
|
}
|
|
259
260
|
delete state.data[key];
|
|
260
261
|
}
|
|
261
|
-
}
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
setDefinition(state, { name, definition = {} }) {
|
|
265
|
+
state.definitions[name] = definition;
|
|
266
|
+
},
|
|
262
267
|
};
|
|
263
268
|
|
|
264
269
|
export const actions = {
|
|
265
|
-
async set({
|
|
270
|
+
async set({
|
|
271
|
+
dispatch, commit, rootGetters, state
|
|
272
|
+
}, opt) {
|
|
266
273
|
let { key, value } = opt; // eslint-disable-line prefer-const
|
|
267
|
-
const definition = definitions[key];
|
|
274
|
+
const definition = state.definitions[key];
|
|
268
275
|
let server;
|
|
269
276
|
|
|
270
277
|
if ( opt.val ) {
|
|
@@ -326,8 +333,8 @@ export const actions = {
|
|
|
326
333
|
return;
|
|
327
334
|
}
|
|
328
335
|
|
|
329
|
-
for (const key in definitions) {
|
|
330
|
-
const definition = definitions[key];
|
|
336
|
+
for (const key in state.definitions) {
|
|
337
|
+
const definition = state.definitions[key];
|
|
331
338
|
|
|
332
339
|
if ( !definition.asCookie ) {
|
|
333
340
|
continue;
|
|
@@ -441,8 +448,8 @@ export const actions = {
|
|
|
441
448
|
prefsBeforeLogin = {};
|
|
442
449
|
}
|
|
443
450
|
|
|
444
|
-
for (const key in definitions) {
|
|
445
|
-
const definition = definitions[key];
|
|
451
|
+
for (const key in state.definitions) {
|
|
452
|
+
const definition = state.definitions[key];
|
|
446
453
|
let value = clone(server.data[key]);
|
|
447
454
|
|
|
448
455
|
if (value === undefined && definition.inheritFrom) {
|
package/store/type-map.js
CHANGED
|
@@ -148,6 +148,8 @@ import { sortBy } from '@shell/utils/sort';
|
|
|
148
148
|
import { haveV1Monitoring, haveV2Monitoring } from '@shell/utils/monitoring';
|
|
149
149
|
import { NEU_VECTOR_NAMESPACE } from '@shell/config/product/neuvector';
|
|
150
150
|
|
|
151
|
+
import { ExtensionPoint, TableColumnLocation } from '@shell/core/types';
|
|
152
|
+
|
|
151
153
|
export const NAMESPACED = 'namespaced';
|
|
152
154
|
export const CLUSTER_LEVEL = 'cluster';
|
|
153
155
|
export const BOTH = 'both';
|
|
@@ -222,6 +224,30 @@ export function DSL(store, product, module = 'type-map') {
|
|
|
222
224
|
},
|
|
223
225
|
|
|
224
226
|
headers(type, headers) {
|
|
227
|
+
const extensionCols = store.$plugin.getUIConfig(ExtensionPoint.TABLE_COL, TableColumnLocation.RESOURCE);
|
|
228
|
+
|
|
229
|
+
// Try and insert the columns before the Age column, if that is the last column
|
|
230
|
+
let insertPosition = headers.length;
|
|
231
|
+
|
|
232
|
+
if (headers.length > 0) {
|
|
233
|
+
const lastColumn = headers[headers.length - 1];
|
|
234
|
+
|
|
235
|
+
if (lastColumn?.name === AGE.name) {
|
|
236
|
+
insertPosition--;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// adding extension defined cols to the correct header config
|
|
241
|
+
extensionCols.forEach((col) => {
|
|
242
|
+
if (col.locationConfig.resource) {
|
|
243
|
+
col.locationConfig.resource.forEach((resource) => {
|
|
244
|
+
if (resource && type === resource) {
|
|
245
|
+
headers.splice(insertPosition, 0, col);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
225
251
|
headers.forEach((header) => {
|
|
226
252
|
// If on the client, then use the value getter if there is one
|
|
227
253
|
if (header.getValue) {
|
package/types/shell/index.d.ts
CHANGED