@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
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { PVC } from '@shell/config/types';
|
|
3
|
+
import ButtonDropdown from '@shell/components/ButtonDropdown';
|
|
4
|
+
import Mount from '@shell/edit/workload/storage/Mount';
|
|
5
|
+
import { _VIEW } from '@shell/config/query-params';
|
|
6
|
+
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
7
|
+
import { randomStr } from '@shell/utils/string';
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
name: 'ContainerMountPaths',
|
|
11
|
+
components: {
|
|
12
|
+
ArrayListGrouped, ButtonDropdown, Mount
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
props: {
|
|
16
|
+
mode: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: 'create',
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// pod spec
|
|
22
|
+
value: {
|
|
23
|
+
type: Object,
|
|
24
|
+
default: () => {
|
|
25
|
+
return {};
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
container: {
|
|
30
|
+
type: Object,
|
|
31
|
+
default: () => {
|
|
32
|
+
return {};
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async fetch() {
|
|
38
|
+
if ( this.$store.getters['cluster/schemaFor'](PVC) ) {
|
|
39
|
+
this.pvcs = await this.$store.dispatch('cluster/findAll', { type: PVC });
|
|
40
|
+
} else {
|
|
41
|
+
this.pvcs = [];
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
data() {
|
|
46
|
+
this.initializeStorage();
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
containerVolumes: [],
|
|
50
|
+
pvcs: [],
|
|
51
|
+
storageVolumes: this.getStorageVolumes(),
|
|
52
|
+
selectedContainerVolumes: this.getSelectedContainerVolumes()
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
computed: {
|
|
57
|
+
isView() {
|
|
58
|
+
return this.mode === _VIEW;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
availableVolumeOptions() {
|
|
62
|
+
const containerVolumes = this.container.volumeMounts.map(item => item.name);
|
|
63
|
+
|
|
64
|
+
return this.value.volumes.filter(vol => !containerVolumes.includes(vol.name)).map((item) => {
|
|
65
|
+
return {
|
|
66
|
+
label: `${ item.name } (${ this.headerFor(item) })`,
|
|
67
|
+
action: this.selectVolume,
|
|
68
|
+
value: item.name
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
watch: {
|
|
75
|
+
value(neu, old) {
|
|
76
|
+
this.selectedVolumes = this.getSelectedContainerVolumes();
|
|
77
|
+
},
|
|
78
|
+
storageVolumes(neu, old) {
|
|
79
|
+
// removeObjects(this.value.volumes, old);
|
|
80
|
+
// addObjects(this.value.volumes, neu);
|
|
81
|
+
const names = neu.reduce((all, each) => {
|
|
82
|
+
all.push(each.name);
|
|
83
|
+
|
|
84
|
+
return all;
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
this.container.volumeMounts = this.container.volumeMounts.filter(mount => names.includes(mount.name));
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
selectedContainerVolumes(neu, old) {
|
|
91
|
+
// removeObjects(this.value.volumes, old);
|
|
92
|
+
// addObjects(this.value.volumes, neu);
|
|
93
|
+
const names = neu.map(item => item.name);
|
|
94
|
+
|
|
95
|
+
this.container.volumeMounts = this.container.volumeMounts.filter(mount => names.includes(mount.name));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
methods: {
|
|
101
|
+
/**
|
|
102
|
+
* Initialize missing values for the container
|
|
103
|
+
*/
|
|
104
|
+
initializeStorage() {
|
|
105
|
+
if (!this.container.volumeMounts) {
|
|
106
|
+
this.$set(this.container, 'volumeMounts', []);
|
|
107
|
+
}
|
|
108
|
+
if (!this.value.volumes) {
|
|
109
|
+
this.$set(this.value, 'volumes', []);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get existing paired storage volumes
|
|
115
|
+
*/
|
|
116
|
+
getStorageVolumes() {
|
|
117
|
+
// Extract volume mounts to map storage volumes
|
|
118
|
+
const { volumeMounts = [] } = this.container;
|
|
119
|
+
const names = volumeMounts.map(({ name }) => name);
|
|
120
|
+
|
|
121
|
+
// Extract storage volumes to allow mutation, if matches mount map
|
|
122
|
+
return this.value.volumes.filter(volume => names.includes(volume.name));
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
getSelectedContainerVolumes() {
|
|
126
|
+
// Extract volume mounts to map storage volumes
|
|
127
|
+
const { volumeMounts = [] } = this.container;
|
|
128
|
+
const names = volumeMounts.map(({ name }) => name);
|
|
129
|
+
|
|
130
|
+
// Extract storage volumes to allow mutation, if matches mount map
|
|
131
|
+
return this.value.volumes.filter(volume => names.includes(volume.name));
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Remove all mounts for given storage volume
|
|
136
|
+
*/
|
|
137
|
+
removeVolume(volume) {
|
|
138
|
+
const removeName = volume.row.value.name;
|
|
139
|
+
|
|
140
|
+
this.selectedContainerVolumes = this.selectedContainerVolumes.filter(({ name }) => name !== removeName);
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
selectVolume(event) {
|
|
144
|
+
const selectedVolume = this.value.volumes.find(vol => vol.name === event.value);
|
|
145
|
+
|
|
146
|
+
this.selectedContainerVolumes.push(selectedVolume);
|
|
147
|
+
|
|
148
|
+
const { name } = selectedVolume;
|
|
149
|
+
|
|
150
|
+
this.container.volumeMounts.push(name);
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
addVolume(type) {
|
|
154
|
+
const name = `vol-${ randomStr(5).toLowerCase() }`;
|
|
155
|
+
|
|
156
|
+
if (type === 'createPVC') {
|
|
157
|
+
this.storageVolumes.push({
|
|
158
|
+
_type: 'createPVC',
|
|
159
|
+
persistentVolumeClaim: {},
|
|
160
|
+
name,
|
|
161
|
+
});
|
|
162
|
+
} else if (type === 'csi') {
|
|
163
|
+
this.storageVolumes.push({
|
|
164
|
+
_type: type,
|
|
165
|
+
csi: { volumeAttributes: {} },
|
|
166
|
+
name,
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
this.storageVolumes.push({
|
|
170
|
+
_type: type,
|
|
171
|
+
[type]: {},
|
|
172
|
+
name,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
this.container.volumeMounts.push({ name });
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
headerFor(value) {
|
|
180
|
+
const type = Object.keys(value).filter(
|
|
181
|
+
key => typeof value[key] === 'object'
|
|
182
|
+
)[0];
|
|
183
|
+
|
|
184
|
+
if (
|
|
185
|
+
this.$store.getters['i18n/exists'](`workload.storage.subtypes.${ type }`)
|
|
186
|
+
) {
|
|
187
|
+
return this.t(`workload.storage.subtypes.${ type }`);
|
|
188
|
+
} else {
|
|
189
|
+
return type;
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
openPopover() {
|
|
194
|
+
const button = this.$refs.buttonDropdown;
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
button.togglePopover();
|
|
198
|
+
} catch (e) {}
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
</script>
|
|
203
|
+
|
|
204
|
+
<template>
|
|
205
|
+
<div>
|
|
206
|
+
<!-- Storage Volumes -->
|
|
207
|
+
<ArrayListGrouped
|
|
208
|
+
:key="selectedContainerVolumes.length"
|
|
209
|
+
v-model="selectedContainerVolumes"
|
|
210
|
+
:mode="mode"
|
|
211
|
+
@remove="removeVolume"
|
|
212
|
+
>
|
|
213
|
+
<!-- Custom/default storage volume form -->
|
|
214
|
+
<template #default="props">
|
|
215
|
+
<h3>{{ props.row.value.name }} ({{ headerFor(props.row.value) }})</h3>
|
|
216
|
+
<Mount
|
|
217
|
+
:container="container"
|
|
218
|
+
:name="props.row.value.name"
|
|
219
|
+
:mode="mode"
|
|
220
|
+
/>
|
|
221
|
+
</template>
|
|
222
|
+
|
|
223
|
+
<!-- Add Storage Volume -->
|
|
224
|
+
<template #add>
|
|
225
|
+
<ButtonDropdown
|
|
226
|
+
v-if="!isView"
|
|
227
|
+
id="add-volume"
|
|
228
|
+
:button-label="t('workload.storage.selectVolume')"
|
|
229
|
+
:dropdown-options="availableVolumeOptions"
|
|
230
|
+
size="sm"
|
|
231
|
+
@click-action="e=>selectVolume(e)"
|
|
232
|
+
>
|
|
233
|
+
<template #no-options>
|
|
234
|
+
{{ t('workload.storage.noVolumes') }}
|
|
235
|
+
</template>
|
|
236
|
+
</ButtonDropdown>
|
|
237
|
+
</template>
|
|
238
|
+
</ArrayListGrouped>
|
|
239
|
+
</div>
|
|
240
|
+
</template>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
|
+
|
|
3
5
|
import { mapGetters } from 'vuex';
|
|
4
6
|
|
|
5
7
|
export default {
|
|
6
|
-
components: { LabeledInput },
|
|
8
|
+
components: { LabeledInput, Checkbox },
|
|
7
9
|
props: {
|
|
8
10
|
// volumeAttributes object
|
|
9
11
|
value: {
|
|
@@ -24,6 +26,23 @@ export default {
|
|
|
24
26
|
|
|
25
27
|
<template>
|
|
26
28
|
<div>
|
|
29
|
+
<div class="row mb-10">
|
|
30
|
+
<div class="col span-6">
|
|
31
|
+
<LabeledInput
|
|
32
|
+
v-model="value.name"
|
|
33
|
+
:required="true"
|
|
34
|
+
:mode="mode"
|
|
35
|
+
:label="t('workload.storage.volumeName')"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="col span-6">
|
|
39
|
+
<Checkbox
|
|
40
|
+
v-model="value.awsElasticBlockStore.readOnly"
|
|
41
|
+
:mode="mode"
|
|
42
|
+
:label="t('workload.storage.readOnly')"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
27
46
|
<div class="row mb-10">
|
|
28
47
|
<div class="col span-6">
|
|
29
48
|
<LabeledInput
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { mapGetters } from 'vuex';
|
|
2
3
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
4
|
import { RadioGroup } from '@components/Form/Radio';
|
|
4
|
-
import {
|
|
5
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
|
-
components: {
|
|
8
|
+
components: {
|
|
9
|
+
LabeledInput, RadioGroup, Checkbox
|
|
10
|
+
},
|
|
8
11
|
props: {
|
|
9
12
|
// volumeAttributes object
|
|
10
13
|
value: {
|
|
@@ -31,6 +34,23 @@ export default {
|
|
|
31
34
|
|
|
32
35
|
<template>
|
|
33
36
|
<div>
|
|
37
|
+
<div class="row mb-10">
|
|
38
|
+
<div class="col span-6">
|
|
39
|
+
<LabeledInput
|
|
40
|
+
v-model="value.name"
|
|
41
|
+
:required="true"
|
|
42
|
+
:mode="mode"
|
|
43
|
+
:label="t('workload.storage.volumeName')"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="col span-6">
|
|
47
|
+
<Checkbox
|
|
48
|
+
v-model="value.azureDisk.readOnly"
|
|
49
|
+
:mode="mode"
|
|
50
|
+
:label="t('workload.storage.readOnly')"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
34
54
|
<div class="row mb-10">
|
|
35
55
|
<div class="col span-6">
|
|
36
56
|
<LabeledInput
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
2
|
import { mapGetters } from 'vuex';
|
|
3
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
|
-
components: { LabeledInput },
|
|
7
|
+
components: { LabeledInput, Checkbox },
|
|
7
8
|
|
|
8
9
|
props: {
|
|
9
10
|
value: {
|
|
@@ -25,6 +26,23 @@ export default {
|
|
|
25
26
|
|
|
26
27
|
<template>
|
|
27
28
|
<div>
|
|
29
|
+
<div class="row mb-10">
|
|
30
|
+
<div class="col span-6">
|
|
31
|
+
<LabeledInput
|
|
32
|
+
v-model="value.name"
|
|
33
|
+
:required="true"
|
|
34
|
+
:mode="mode"
|
|
35
|
+
:label="t('workload.storage.volumeName')"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="col span-6">
|
|
39
|
+
<Checkbox
|
|
40
|
+
v-model="value.azureFile.readOnly"
|
|
41
|
+
:mode="mode"
|
|
42
|
+
:label="t('workload.storage.readOnly')"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
28
46
|
<div class="row mb-10">
|
|
29
47
|
<div class="col span-6">
|
|
30
48
|
<LabeledInput
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
3
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
5
|
+
|
|
3
6
|
import { mapGetters } from 'vuex';
|
|
4
7
|
|
|
5
8
|
export default {
|
|
6
|
-
components: {
|
|
9
|
+
components: {
|
|
10
|
+
LabeledSelect, Checkbox, LabeledInput
|
|
11
|
+
},
|
|
7
12
|
|
|
8
13
|
props: {
|
|
9
14
|
podSpec: {
|
|
@@ -45,6 +50,23 @@ export default {
|
|
|
45
50
|
<template>
|
|
46
51
|
<div>
|
|
47
52
|
<div>
|
|
53
|
+
<div class="row mb-10">
|
|
54
|
+
<div class="col span-6">
|
|
55
|
+
<LabeledInput
|
|
56
|
+
v-model="value.name"
|
|
57
|
+
:required="true"
|
|
58
|
+
:mode="mode"
|
|
59
|
+
:label="t('workload.storage.volumeName')"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="col span-6">
|
|
63
|
+
<Checkbox
|
|
64
|
+
v-model="value.csi.readOnly"
|
|
65
|
+
:mode="mode"
|
|
66
|
+
:label="t('workload.storage.readOnly')"
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
48
70
|
<div class="row mb-10">
|
|
49
71
|
<div class="col span-6">
|
|
50
72
|
<LabeledSelect
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
2
|
import { mapGetters } from 'vuex';
|
|
3
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
|
-
components: { LabeledInput },
|
|
7
|
+
components: { LabeledInput, Checkbox },
|
|
7
8
|
|
|
8
9
|
props: {
|
|
9
10
|
value: {
|
|
@@ -25,6 +26,23 @@ export default {
|
|
|
25
26
|
|
|
26
27
|
<template>
|
|
27
28
|
<div>
|
|
29
|
+
<div class="row mb-10">
|
|
30
|
+
<div class="col span-6">
|
|
31
|
+
<LabeledInput
|
|
32
|
+
v-model="value.name"
|
|
33
|
+
:required="true"
|
|
34
|
+
:mode="mode"
|
|
35
|
+
:label="t('workload.storage.volumeName')"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="col span-6">
|
|
39
|
+
<Checkbox
|
|
40
|
+
v-model="value.gcePersistentDisk.readOnly"
|
|
41
|
+
:mode="mode"
|
|
42
|
+
:label="t('workload.storage.readOnly')"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
28
46
|
<div class="row mb-10">
|
|
29
47
|
<div class="col span-6">
|
|
30
48
|
<LabeledInput
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { PVC } from '@shell/config/types';
|
|
3
|
-
import { removeObjects, addObjects } from '@shell/utils/array';
|
|
4
3
|
import ButtonDropdown from '@shell/components/ButtonDropdown';
|
|
5
4
|
import Mount from '@shell/edit/workload/storage/Mount';
|
|
6
5
|
import { _VIEW } from '@shell/config/query-params';
|
|
@@ -33,13 +32,6 @@ export default {
|
|
|
33
32
|
default: null,
|
|
34
33
|
},
|
|
35
34
|
|
|
36
|
-
container: {
|
|
37
|
-
type: Object,
|
|
38
|
-
default: () => {
|
|
39
|
-
return {};
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
|
|
43
35
|
savePvcHookName: {
|
|
44
36
|
type: String,
|
|
45
37
|
required: true,
|
|
@@ -73,10 +65,7 @@ export default {
|
|
|
73
65
|
data() {
|
|
74
66
|
this.initializeStorage();
|
|
75
67
|
|
|
76
|
-
return {
|
|
77
|
-
pvcs: [],
|
|
78
|
-
storageVolumes: this.getStorageVolumes(),
|
|
79
|
-
};
|
|
68
|
+
return { pvcs: [] };
|
|
80
69
|
},
|
|
81
70
|
|
|
82
71
|
computed: {
|
|
@@ -94,7 +83,7 @@ export default {
|
|
|
94
83
|
* Generated list of volumes
|
|
95
84
|
*/
|
|
96
85
|
volumeTypeOptions() {
|
|
97
|
-
const excludedFiles = ['index', 'Mount', 'PVC'];
|
|
86
|
+
const excludedFiles = ['index', 'Mount', 'PVC', 'ContainerMountPaths'];
|
|
98
87
|
const defaultVolumeTypes = [
|
|
99
88
|
'csi',
|
|
100
89
|
'configMap',
|
|
@@ -125,78 +114,63 @@ export default {
|
|
|
125
114
|
},
|
|
126
115
|
},
|
|
127
116
|
|
|
128
|
-
watch: {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
117
|
+
// watch: {
|
|
118
|
+
// storageVolumes(neu, old) {
|
|
119
|
+
// removeObjects(this.value.volumes, old);
|
|
120
|
+
// addObjects(this.value.volumes, neu);
|
|
121
|
+
// const names = neu.reduce((all, each) => {
|
|
122
|
+
// all.push(each.name);
|
|
134
123
|
|
|
135
|
-
|
|
136
|
-
|
|
124
|
+
// return all;
|
|
125
|
+
// }, []);
|
|
137
126
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
},
|
|
127
|
+
// this.container.volumeMounts = this.container.volumeMounts.filter(mount => names.includes(mount.name));
|
|
128
|
+
// }
|
|
129
|
+
// },
|
|
141
130
|
|
|
142
131
|
methods: {
|
|
143
132
|
/**
|
|
144
133
|
* Initialize missing values for the container
|
|
145
134
|
*/
|
|
146
135
|
initializeStorage() {
|
|
147
|
-
if (!this.container.volumeMounts) {
|
|
148
|
-
this.$set(this.container, 'volumeMounts', []);
|
|
149
|
-
}
|
|
150
136
|
if (!this.value.volumes) {
|
|
151
137
|
this.$set(this.value, 'volumes', []);
|
|
152
138
|
}
|
|
153
139
|
},
|
|
154
140
|
|
|
155
|
-
/**
|
|
156
|
-
* Get existing paired storage volumes
|
|
157
|
-
*/
|
|
158
|
-
getStorageVolumes() {
|
|
159
|
-
// Extract volume mounts to map storage volumes
|
|
160
|
-
const { volumeMounts = [] } = this.container;
|
|
161
|
-
const names = volumeMounts.map(({ name }) => name);
|
|
162
|
-
|
|
163
|
-
// Extract storage volumes to allow mutation, if matches mount map
|
|
164
|
-
return this.value.volumes.filter(volume => names.includes(volume.name));
|
|
165
|
-
},
|
|
166
|
-
|
|
167
141
|
/**
|
|
168
142
|
* Remove all mounts for given storage volume
|
|
169
143
|
*/
|
|
170
144
|
removeVolume(volume) {
|
|
171
145
|
const removeName = volume.row.value.name;
|
|
172
146
|
|
|
173
|
-
this.
|
|
147
|
+
this.value.volumes = this.value.volumes.filter(({ name }) => name !== removeName);
|
|
174
148
|
},
|
|
175
149
|
|
|
176
150
|
addVolume(type) {
|
|
177
151
|
const name = `vol-${ randomStr(5).toLowerCase() }`;
|
|
178
152
|
|
|
179
153
|
if (type === 'createPVC') {
|
|
180
|
-
this.
|
|
154
|
+
this.value.volumes.push({
|
|
181
155
|
_type: 'createPVC',
|
|
182
156
|
persistentVolumeClaim: {},
|
|
183
157
|
name,
|
|
184
158
|
});
|
|
185
159
|
} else if (type === 'csi') {
|
|
186
|
-
this.
|
|
160
|
+
this.value.volumes.push({
|
|
187
161
|
_type: type,
|
|
188
162
|
csi: { volumeAttributes: {} },
|
|
189
163
|
name,
|
|
190
164
|
});
|
|
191
165
|
} else {
|
|
192
|
-
this.
|
|
166
|
+
this.value.volumes.push({
|
|
193
167
|
_type: type,
|
|
194
168
|
[type]: {},
|
|
195
169
|
name,
|
|
196
170
|
});
|
|
197
171
|
}
|
|
198
172
|
|
|
199
|
-
this.container.volumeMounts.push({ name });
|
|
173
|
+
// this.container.volumeMounts.push({ name });
|
|
200
174
|
},
|
|
201
175
|
|
|
202
176
|
volumeType(vol) {
|
|
@@ -275,8 +249,8 @@ export default {
|
|
|
275
249
|
<div>
|
|
276
250
|
<!-- Storage Volumes -->
|
|
277
251
|
<ArrayListGrouped
|
|
278
|
-
:key="
|
|
279
|
-
v-model="
|
|
252
|
+
:key="value.volumes.length"
|
|
253
|
+
v-model="value.volumes"
|
|
280
254
|
:mode="mode"
|
|
281
255
|
@remove="removeVolume"
|
|
282
256
|
>
|
|
@@ -307,19 +281,19 @@ export default {
|
|
|
307
281
|
</div>
|
|
308
282
|
</div>
|
|
309
283
|
|
|
310
|
-
<!-- Mount point list to be mapped to volume
|
|
284
|
+
<!-- Mount point list to be mapped to volume
|
|
311
285
|
<Mount
|
|
312
286
|
:container="container"
|
|
313
287
|
:name="props.row.value.name"
|
|
314
288
|
:mode="mode"
|
|
315
|
-
/>
|
|
289
|
+
/> -->
|
|
316
290
|
</template>
|
|
317
291
|
|
|
318
292
|
<!-- Add Storage Volume -->
|
|
319
293
|
<template #add>
|
|
320
294
|
<ButtonDropdown
|
|
321
295
|
v-if="!isView"
|
|
322
|
-
id="
|
|
296
|
+
id="select-volume"
|
|
323
297
|
:button-label="t('workload.storage.addVolume')"
|
|
324
298
|
:dropdown-options="volumeTypeOptions"
|
|
325
299
|
size="sm"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
3
2
|
import { mapGetters } from 'vuex';
|
|
3
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
components: { LabeledInput },
|
|
@@ -25,6 +25,16 @@ export default {
|
|
|
25
25
|
|
|
26
26
|
<template>
|
|
27
27
|
<div>
|
|
28
|
+
<div class="row mb-10">
|
|
29
|
+
<div class="col span-6">
|
|
30
|
+
<LabeledInput
|
|
31
|
+
v-model="value.name"
|
|
32
|
+
:required="true"
|
|
33
|
+
:mode="mode"
|
|
34
|
+
:label="t('workload.storage.volumeName')"
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
28
38
|
<div class="row mb-10">
|
|
29
39
|
<div class="col span-6">
|
|
30
40
|
<LabeledInput
|
package/layouts/default.vue
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import debounce from 'lodash/debounce';
|
|
3
3
|
import { mapState, mapGetters } from 'vuex';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
mapPref,
|
|
6
|
+
FAVORITE_TYPES,
|
|
7
|
+
AFTER_LOGIN_ROUTE,
|
|
8
|
+
THEME_SHORTCUT
|
|
9
|
+
} from '@shell/store/prefs';
|
|
5
10
|
import ActionMenu from '@shell/components/ActionMenu';
|
|
6
11
|
import GrowlManager from '@shell/components/GrowlManager';
|
|
7
12
|
import WindowManager from '@shell/components/nav/WindowManager';
|
|
@@ -55,9 +60,10 @@ export default {
|
|
|
55
60
|
// Note - This will not run on route change
|
|
56
61
|
data() {
|
|
57
62
|
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
noLocaleShortcut: process.env.dev || false,
|
|
64
|
+
groups: [],
|
|
65
|
+
gettingGroups: false,
|
|
66
|
+
wantNavSync: false,
|
|
61
67
|
};
|
|
62
68
|
},
|
|
63
69
|
|
|
@@ -78,8 +84,8 @@ export default {
|
|
|
78
84
|
return this.$store.getters['activeNamespaceCache'];
|
|
79
85
|
},
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
favoriteTypes:
|
|
87
|
+
themeShortcut: mapPref(THEME_SHORTCUT),
|
|
88
|
+
favoriteTypes: mapPref(FAVORITE_TYPES),
|
|
83
89
|
|
|
84
90
|
pageActions() {
|
|
85
91
|
const pageActions = [];
|
|
@@ -647,8 +653,8 @@ export default {
|
|
|
647
653
|
<PromptRestore />
|
|
648
654
|
<AssignTo />
|
|
649
655
|
<PromptModal />
|
|
650
|
-
<button v-if="
|
|
651
|
-
<button v-if="
|
|
656
|
+
<button v-if="noLocaleShortcut" v-shortkey.once="['shift','l']" class="hide" @shortkey="toggleNoneLocale()" />
|
|
657
|
+
<button v-if="themeShortcut" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
|
|
652
658
|
<button v-shortkey.once="['f8']" class="hide" @shortkey="wheresMyDebugger()" />
|
|
653
659
|
<button v-shortkey.once="['`']" class="hide" @shortkey="toggleShell" />
|
|
654
660
|
</main>
|