@rancher/shell 0.3.23 → 0.3.25
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/base/_variables.scss +1 -0
- package/assets/styles/themes/_dark.scss +1 -0
- package/assets/styles/themes/_light.scss +6 -5
- package/assets/translations/en-us.yaml +44 -17
- package/assets/translations/zh-hans.yaml +2 -2
- package/components/ClusterIconMenu.vue +143 -0
- package/components/CruResource.vue +7 -1
- package/components/ExplorerProjectsNamespaces.vue +11 -1
- package/components/FixedBanner.vue +17 -1
- package/components/Loading.vue +1 -1
- package/components/Markdown.vue +1 -1
- package/components/Questions/__tests__/Yaml.test.ts +3 -2
- package/components/SideNav.vue +1 -1
- package/components/SortableTable/index.vue +3 -2
- package/components/auth/RoleDetailEdit.vue +15 -2
- package/components/auth/login/saml.vue +12 -1
- package/components/form/LabeledSelect.vue +12 -5
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/Members/MembershipEditor.vue +6 -1
- package/components/form/SelectOrCreateAuthSecret.vue +7 -0
- package/components/form/__tests__/KeyValue.test.ts +6 -3
- package/components/form/__tests__/LabeledSelect.test.ts +18 -0
- package/components/formatter/PodsUsage.vue +11 -36
- package/components/formatter/PrincipalGroupBindings.vue +8 -5
- package/components/formatter/__tests__/PodsUsage.test.ts +36 -19
- package/components/nav/Group.vue +62 -34
- package/components/nav/Header.vue +13 -6
- package/components/nav/Pinned.vue +47 -0
- package/components/nav/TopLevelMenu.vue +673 -325
- package/components/nav/Type.vue +88 -8
- package/config/home-links.js +1 -1
- package/config/product/istio.js +15 -5
- package/config/router.js +3 -9
- package/config/table-headers.js +5 -6
- package/config/uiplugins.js +1 -0
- package/core/plugin-helpers.js +3 -0
- package/core/types.ts +6 -1
- package/creators/app/files/.vscode/settings.json +0 -1
- package/creators/pkg/init +2 -2
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +118 -0
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +4 -4
- package/detail/provisioning.cattle.io.cluster.vue +7 -5
- package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +58 -0
- package/edit/__tests__/namespace.test.ts +5 -3
- package/edit/fleet.cattle.io.gitrepo.vue +43 -15
- package/edit/logging.banzaicloud.io.output/index.vue +7 -0
- package/edit/management.cattle.io.clusterroletemplatebinding.vue +3 -11
- package/edit/namespace.vue +8 -4
- package/edit/provisioning.cattle.io.cluster/Basics.vue +662 -0
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +9 -8
- package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +13 -8
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -2
- package/edit/provisioning.cattle.io.cluster/MemberRoles.vue +40 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +71 -23
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +52 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +65 -142
- package/edit/provisioning.cattle.io.cluster/rke2.vue +253 -582
- package/edit/workload/storage/ContainerMountPaths.vue +7 -5
- package/edit/workload/storage/__tests__/Storage.test.ts +2 -2
- package/edit/workload/storage/persistentVolumeClaim/__tests__/persistentvolumeclaim.test.ts +36 -0
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +15 -7
- package/initialize/App.js +2 -0
- package/initialize/client.js +63 -51
- package/initialize/index.js +7 -5
- package/layouts/default.vue +10 -2
- package/layouts/home.vue +6 -2
- package/layouts/plain.vue +9 -2
- package/list/fleet.cattle.io.cluster.vue +2 -2
- package/list/management.cattle.io.feature.vue +1 -1
- package/machine-config/amazonec2.vue +1 -0
- package/machine-config/vmwarevsphere.vue +48 -7
- package/mixins/brand.js +0 -8
- package/mixins/child-hook.js +2 -2
- package/mixins/create-edit-view/impl.js +3 -3
- package/mixins/fetch.client.js +3 -3
- package/models/__tests__/management.cattle.io.node.ts +96 -0
- package/models/__tests__/node.ts +74 -0
- package/models/cluster/node.js +6 -5
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -2
- package/models/management.cattle.io.cluster.js +22 -1
- package/models/management.cattle.io.clusterroletemplatebinding.js +3 -3
- package/models/management.cattle.io.globalrole.js +17 -2
- package/models/management.cattle.io.node.js +6 -4
- package/models/management.cattle.io.projectroletemplatebinding.js +3 -3
- package/models/management.cattle.io.roletemplate.js +17 -2
- package/package.json +2 -6
- package/pages/__tests__/prefs.test.ts +1 -1
- package/pages/about.vue +2 -0
- package/pages/auth/setup.vue +5 -4
- package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -0
- package/pages/c/_cluster/monitoring/index.vue +8 -3
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +9 -66
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +182 -0
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +15 -32
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +8 -46
- package/pages/c/_cluster/uiplugins/index.vue +64 -64
- package/pages/diagnostic.vue +0 -39
- package/pages/home.vue +1 -1
- package/pages/prefs.vue +3 -13
- package/plugins/dashboard-store/normalize.js +4 -4
- package/plugins/dashboard-store/resource-class.js +1 -1
- package/plugins/int-number.js +5 -2
- package/plugins/positive-int-number.js +19 -0
- package/plugins/steve/__tests__/getters.spec.ts +15 -0
- package/plugins/steve/getters.js +22 -10
- package/public/index.html +4 -2
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -1
- package/rancher-components/Banner/Banner.vue +134 -53
- package/rancher-components/Card/Card.test.ts +37 -0
- package/rancher-components/Card/Card.vue +24 -7
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
- package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +22 -10
- package/rancher-components/Form/Radio/RadioButton.test.ts +31 -0
- package/rancher-components/Form/Radio/RadioButton.vue +30 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
- package/rancher-components/StringList/StringList.test.ts +453 -49
- package/rancher-components/StringList/StringList.vue +92 -58
- package/scripts/extension/parse-tag-name +0 -0
- package/store/index.js +4 -0
- package/store/prefs.js +4 -4
- package/store/type-map.js +2 -16
- package/types/shell/index.d.ts +26 -14
- package/utils/__tests__/cluster.test.ts +55 -0
- package/utils/__tests__/object.test.ts +21 -2
- package/utils/__tests__/sort.test.ts +61 -0
- package/utils/cluster.js +47 -1
- package/utils/object.js +12 -5
- package/utils/string.js +12 -0
- package/utils/validators/formRules/__tests__/index.test.ts +13 -1
- package/utils/validators/formRules/index.ts +4 -0
- package/utils/validators/role-template.js +9 -1
- package/utils/version.js +1 -1
- package/vue.config.js +1 -4
- package/yarn-error.log +200 -0
- package/content/docs/en-us/getting-started.md +0 -224
- package/content/docs/en-us/whats-new.md +0 -29
- package/content/docs/zh-hans/getting-started.md +0 -224
- package/content/docs/zh-hans/whats-new.md +0 -28
- package/pages/docs/_doc.vue +0 -345
- package/pages/docs/toc.js +0 -27
- package/plugins/console.js +0 -34
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { mapGetters } from 'vuex';
|
|
3
|
+
|
|
4
|
+
import { CATALOG, UI_PLUGIN, SERVICE, WORKLOAD_TYPES } from '@shell/config/types';
|
|
5
|
+
import { UI_PLUGIN_LABELS, UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
|
|
6
|
+
import { allHash } from '@shell/utils/promise';
|
|
7
|
+
|
|
8
|
+
import AsyncButton from '@shell/components/AsyncButton';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
components: { AsyncButton },
|
|
12
|
+
|
|
13
|
+
async fetch() {
|
|
14
|
+
if ( this.$store.getters['management/schemaFor'](UI_PLUGIN) ) {
|
|
15
|
+
const plugins = this.$store.dispatch('management/findAll', { type: UI_PLUGIN });
|
|
16
|
+
|
|
17
|
+
this.plugins = plugins || [];
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
data() {
|
|
22
|
+
return {
|
|
23
|
+
catalog: undefined, busy: false, plugins: null
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
computed: {
|
|
28
|
+
...mapGetters({ allCharts: 'catalog/charts' }),
|
|
29
|
+
|
|
30
|
+
pluginsFromCatalogImage() {
|
|
31
|
+
return this.plugins.filter((p) => p.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE]);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
methods: {
|
|
36
|
+
showDialog(catalog) {
|
|
37
|
+
this.catalog = catalog;
|
|
38
|
+
this.busy = false;
|
|
39
|
+
this.$modal.show('uninstallCatalogDialog');
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
closeDialog(result) {
|
|
43
|
+
this.$modal.hide('uninstallCatalogDialog');
|
|
44
|
+
this.$emit('closed', result);
|
|
45
|
+
|
|
46
|
+
if ( result ) {
|
|
47
|
+
this.$emit('refresh');
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async uninstall() {
|
|
52
|
+
this.busy = true;
|
|
53
|
+
|
|
54
|
+
const catalog = this.catalog;
|
|
55
|
+
const apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
|
|
56
|
+
const pluginApps = apps.filter((app) => {
|
|
57
|
+
if ( app.namespace === UI_PLUGIN_NAMESPACE ) {
|
|
58
|
+
// Find the related apps from the deployed helm repository
|
|
59
|
+
const charts = this.allCharts.filter((chart) => chart.repoName === catalog.repo?.metadata?.name);
|
|
60
|
+
|
|
61
|
+
return charts.some((chart) => chart.chartName === app.metadata.name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return false;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await this.removeCatalogResources(catalog);
|
|
68
|
+
|
|
69
|
+
if ( pluginApps.length ) {
|
|
70
|
+
try {
|
|
71
|
+
pluginApps.forEach((app) => {
|
|
72
|
+
this.$emit('update', app.name, 'uninstall');
|
|
73
|
+
app.remove();
|
|
74
|
+
});
|
|
75
|
+
} catch (e) {
|
|
76
|
+
this.$store.dispatch('growl/error', {
|
|
77
|
+
title: this.t('plugins.error.generic'),
|
|
78
|
+
message: e.message ? e.message : e,
|
|
79
|
+
timeout: 10000
|
|
80
|
+
}, { root: true });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await this.$store.dispatch('management/findAll', { type: CATALOG.OPERATION });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.closeDialog(catalog);
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
async removeCatalogResources(catalog) {
|
|
90
|
+
const selector = `${ UI_PLUGIN_LABELS.CATALOG_IMAGE }=${ catalog.name }`;
|
|
91
|
+
const namespace = UI_PLUGIN_NAMESPACE;
|
|
92
|
+
|
|
93
|
+
if ( selector ) {
|
|
94
|
+
const hash = await allHash({
|
|
95
|
+
deployment: this.$store.dispatch('management/findMatching', {
|
|
96
|
+
type: WORKLOAD_TYPES.DEPLOYMENT, selector, namespace
|
|
97
|
+
}),
|
|
98
|
+
service: this.$store.dispatch('management/findMatching', {
|
|
99
|
+
type: SERVICE, selector, namespace
|
|
100
|
+
}),
|
|
101
|
+
repo: this.$store.dispatch('management/findMatching', { type: CATALOG.CLUSTER_REPO, selector })
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
for ( const resource of Object.keys(hash) ) {
|
|
105
|
+
if ( hash[resource] ) {
|
|
106
|
+
hash[resource].forEach((r) => r.remove());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<template>
|
|
116
|
+
<modal
|
|
117
|
+
name="uninstallCatalogDialog"
|
|
118
|
+
height="auto"
|
|
119
|
+
:scrollable="true"
|
|
120
|
+
>
|
|
121
|
+
<div
|
|
122
|
+
v-if="catalog"
|
|
123
|
+
class="plugin-install-dialog"
|
|
124
|
+
>
|
|
125
|
+
<h4 class="mt-10">
|
|
126
|
+
{{ t('plugins.uninstall.title', { name: catalog.name }) }}
|
|
127
|
+
</h4>
|
|
128
|
+
<div class="mt-10 dialog-panel">
|
|
129
|
+
<div class="dialog-info">
|
|
130
|
+
<p>
|
|
131
|
+
{{ t('plugins.uninstall.catalog') }}
|
|
132
|
+
</p>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="dialog-buttons">
|
|
135
|
+
<button
|
|
136
|
+
:disabled="busy"
|
|
137
|
+
class="btn role-secondary"
|
|
138
|
+
data-testid="uninstall-ext-modal-cancel-btn"
|
|
139
|
+
@click="closeDialog(false)"
|
|
140
|
+
>
|
|
141
|
+
{{ t('generic.cancel') }}
|
|
142
|
+
</button>
|
|
143
|
+
<AsyncButton
|
|
144
|
+
mode="uninstall"
|
|
145
|
+
data-testid="uninstall-ext-modal-uninstall-btn"
|
|
146
|
+
@click="uninstall()"
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</modal>
|
|
152
|
+
</template>
|
|
153
|
+
|
|
154
|
+
<style lang="scss" scoped>
|
|
155
|
+
.plugin-install-dialog {
|
|
156
|
+
padding: 10px;
|
|
157
|
+
|
|
158
|
+
h4 {
|
|
159
|
+
font-weight: bold;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.dialog-panel {
|
|
163
|
+
display: flex;
|
|
164
|
+
flex-direction: column;
|
|
165
|
+
min-height: 100px;
|
|
166
|
+
|
|
167
|
+
.dialog-info {
|
|
168
|
+
flex: 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.dialog-buttons {
|
|
173
|
+
display: flex;
|
|
174
|
+
justify-content: flex-end;
|
|
175
|
+
margin-top: 10px;
|
|
176
|
+
|
|
177
|
+
> *:not(:last-child) {
|
|
178
|
+
margin-right: 10px;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
</style>
|
|
@@ -13,13 +13,6 @@ import ResourceTable from '@shell/components/ResourceTable';
|
|
|
13
13
|
export default {
|
|
14
14
|
name: 'CatalogList',
|
|
15
15
|
|
|
16
|
-
props: {
|
|
17
|
-
plugins: {
|
|
18
|
-
type: Array,
|
|
19
|
-
required: true
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
|
|
23
16
|
components: { ActionMenu, ResourceTable },
|
|
24
17
|
|
|
25
18
|
mixins: [ResourceManager],
|
|
@@ -27,7 +20,7 @@ export default {
|
|
|
27
20
|
data() {
|
|
28
21
|
const actions = [
|
|
29
22
|
{
|
|
30
|
-
action: '
|
|
23
|
+
action: 'showCatalogUninstallDialog',
|
|
31
24
|
label: this.t('plugins.uninstall.label'),
|
|
32
25
|
icon: 'icon icon-trash',
|
|
33
26
|
enabled: true,
|
|
@@ -57,36 +50,26 @@ export default {
|
|
|
57
50
|
catalogRows() {
|
|
58
51
|
const rows = [];
|
|
59
52
|
|
|
60
|
-
if (this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
const pluginName = plugin.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE];
|
|
53
|
+
if ( !isEmpty(this.namespacedDeployments) ) {
|
|
54
|
+
this.namespacedDeployments.forEach((deploy) => {
|
|
55
|
+
const resources = [this.namespacedServices, this.allRepos];
|
|
56
|
+
const deployName = deploy.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE];
|
|
65
57
|
|
|
66
|
-
if (
|
|
58
|
+
if ( deployName ) {
|
|
67
59
|
const out = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
version: plugin.spec?.plugin?.version,
|
|
74
|
-
deployment: null,
|
|
75
|
-
deploymentImage: null,
|
|
76
|
-
service: null,
|
|
77
|
-
repo: null
|
|
60
|
+
name: deployName,
|
|
61
|
+
state: deploy.metadata?.state?.name,
|
|
62
|
+
image: deploy.spec?.template?.spec?.containers[0]?.image,
|
|
63
|
+
service: null,
|
|
64
|
+
repo: null
|
|
78
65
|
};
|
|
79
|
-
const keys = ['
|
|
66
|
+
const keys = ['service', 'repo'];
|
|
80
67
|
|
|
81
68
|
resources.forEach((resource, i) => {
|
|
82
|
-
out[keys[i]] = resource?.filter((item) => item.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE] ===
|
|
69
|
+
out[keys[i]] = resource?.filter((item) => item.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE] === deployName)[0];
|
|
83
70
|
});
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
out.deploymentImage = out.deployment.spec?.template?.spec?.containers[0]?.image;
|
|
87
|
-
|
|
88
|
-
rows.push(out);
|
|
89
|
-
}
|
|
72
|
+
rows.push(out);
|
|
90
73
|
}
|
|
91
74
|
});
|
|
92
75
|
}
|
|
@@ -153,7 +136,7 @@ export default {
|
|
|
153
136
|
:custom-target-element="menuTargetElement"
|
|
154
137
|
:custom-target-event="menuTargetEvent"
|
|
155
138
|
@close="setMenu(false)"
|
|
156
|
-
@
|
|
139
|
+
@showCatalogUninstallDialog="e => $emit('showCatalogUninstallDialog', row, e.event)"
|
|
157
140
|
/>
|
|
158
141
|
</template>
|
|
159
142
|
</ResourceTable>
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
3
|
|
|
4
4
|
import AsyncButton from '@shell/components/AsyncButton';
|
|
5
|
-
import { CATALOG
|
|
6
|
-
import {
|
|
7
|
-
import { allHash } from '@shell/utils/promise';
|
|
5
|
+
import { CATALOG } from '@shell/config/types';
|
|
6
|
+
import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
|
|
8
7
|
|
|
9
8
|
export default {
|
|
10
9
|
components: { AsyncButton },
|
|
@@ -33,7 +32,7 @@ export default {
|
|
|
33
32
|
this.$emit('update', plugin.name, 'uninstall');
|
|
34
33
|
|
|
35
34
|
// Delete the CR if this is a developer plugin (there is no Helm App, so need to remove the CRD ourselves)
|
|
36
|
-
if (plugin.uiplugin?.isDeveloper
|
|
35
|
+
if (plugin.uiplugin?.isDeveloper) {
|
|
37
36
|
// Delete the custom resource
|
|
38
37
|
await plugin.uiplugin.remove();
|
|
39
38
|
}
|
|
@@ -41,28 +40,13 @@ export default {
|
|
|
41
40
|
// Find the app for this plugin
|
|
42
41
|
const apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
|
|
43
42
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
// Find the related apps from the deployed helm repository
|
|
47
|
-
const charts = this.allCharts.filter((chart) => chart.repoName === plugin.repo?.metadata?.name);
|
|
48
|
-
|
|
49
|
-
return charts.some((chart) => chart.chartName === app.metadata.name);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (app.namespace === UI_PLUGIN_NAMESPACE && app.name === plugin.name) {
|
|
53
|
-
return app;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return false;
|
|
43
|
+
const pluginApp = apps.find((app) => {
|
|
44
|
+
return app.namespace === UI_PLUGIN_NAMESPACE && app.name === plugin.name;
|
|
57
45
|
});
|
|
58
46
|
|
|
59
|
-
if (
|
|
60
|
-
await this.removePluginImageResources(plugin.uiplugin);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (pluginApps.length) {
|
|
47
|
+
if (pluginApp) {
|
|
64
48
|
try {
|
|
65
|
-
|
|
49
|
+
await pluginApp.remove();
|
|
66
50
|
} catch (e) {
|
|
67
51
|
this.$store.dispatch('growl/error', {
|
|
68
52
|
title: this.t('plugins.error.generic'),
|
|
@@ -75,28 +59,6 @@ export default {
|
|
|
75
59
|
}
|
|
76
60
|
|
|
77
61
|
this.closeDialog(plugin);
|
|
78
|
-
},
|
|
79
|
-
async removePluginImageResources(plugin) {
|
|
80
|
-
const selector = `${ UI_PLUGIN_LABELS.CATALOG_IMAGE }=${ plugin.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE] }`;
|
|
81
|
-
const namespace = UI_PLUGIN_NAMESPACE;
|
|
82
|
-
|
|
83
|
-
if (selector) {
|
|
84
|
-
const hash = await allHash({
|
|
85
|
-
deployment: this.$store.dispatch('management/findMatching', {
|
|
86
|
-
type: WORKLOAD_TYPES.DEPLOYMENT, selector, namespace
|
|
87
|
-
}),
|
|
88
|
-
service: this.$store.dispatch('management/findMatching', {
|
|
89
|
-
type: SERVICE, selector, namespace
|
|
90
|
-
}),
|
|
91
|
-
repo: this.$store.dispatch('management/findMatching', { type: CATALOG.CLUSTER_REPO, selector })
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
for (const resource of Object.keys(hash)) {
|
|
95
|
-
if (hash[resource]) {
|
|
96
|
-
hash[resource].forEach((r) => r.remove());
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
62
|
}
|
|
101
63
|
}
|
|
102
64
|
};
|
|
@@ -118,7 +80,7 @@ export default {
|
|
|
118
80
|
<div class="mt-10 dialog-panel">
|
|
119
81
|
<div class="dialog-info">
|
|
120
82
|
<p>
|
|
121
|
-
{{
|
|
83
|
+
{{ t('plugins.uninstall.prompt') }}
|
|
122
84
|
</p>
|
|
123
85
|
</div>
|
|
124
86
|
<div class="dialog-buttons">
|
|
@@ -19,6 +19,7 @@ import { BadgeState } from '@components/BadgeState';
|
|
|
19
19
|
import UninstallDialog from './UninstallDialog.vue';
|
|
20
20
|
import InstallDialog from './InstallDialog.vue';
|
|
21
21
|
import CatalogLoadDialog from './CatalogList/CatalogLoadDialog.vue';
|
|
22
|
+
import CatalogUninstallDialog from './CatalogList/CatalogUninstallDialog.vue';
|
|
22
23
|
import DeveloperInstallDialog from './DeveloperInstallDialog.vue';
|
|
23
24
|
import PluginInfoPanel from './PluginInfoPanel.vue';
|
|
24
25
|
import SetupUIPlugins from './SetupUIPlugins';
|
|
@@ -35,7 +36,6 @@ import {
|
|
|
35
36
|
isChartVersionHigher,
|
|
36
37
|
UI_PLUGIN_NAMESPACE,
|
|
37
38
|
UI_PLUGIN_CHART_ANNOTATIONS,
|
|
38
|
-
UI_PLUGIN_LABELS,
|
|
39
39
|
UI_PLUGINS_REPO_URL,
|
|
40
40
|
UI_PLUGINS_PARTNERS_REPO_URL
|
|
41
41
|
} from '@shell/config/uiplugins';
|
|
@@ -58,6 +58,7 @@ export default {
|
|
|
58
58
|
CatalogList,
|
|
59
59
|
Banner,
|
|
60
60
|
CatalogLoadDialog,
|
|
61
|
+
CatalogUninstallDialog,
|
|
61
62
|
InstallDialog,
|
|
62
63
|
LazyImage,
|
|
63
64
|
PluginInfoPanel,
|
|
@@ -318,7 +319,11 @@ export default {
|
|
|
318
319
|
builtin: !!p.builtin,
|
|
319
320
|
};
|
|
320
321
|
|
|
321
|
-
|
|
322
|
+
// Built-in plugins can chose to be hidden - used where we implement as extensions
|
|
323
|
+
// but don't want to shows them individually on the extensions page
|
|
324
|
+
if (!(item.builtin && rancher[UI_PLUGIN_CHART_ANNOTATIONS.HIDDEN_BUILTIN])) {
|
|
325
|
+
all.push(item);
|
|
326
|
+
}
|
|
322
327
|
}
|
|
323
328
|
});
|
|
324
329
|
|
|
@@ -326,11 +331,6 @@ export default {
|
|
|
326
331
|
this.plugins.forEach((p) => {
|
|
327
332
|
const chart = all.find((c) => c.name === p.name);
|
|
328
333
|
|
|
329
|
-
// Plugin is a container image, do not add to charts
|
|
330
|
-
if (p.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE]) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
334
|
if (chart) {
|
|
335
335
|
chart.installed = true;
|
|
336
336
|
chart.uiplugin = p;
|
|
@@ -409,10 +409,6 @@ export default {
|
|
|
409
409
|
|
|
410
410
|
// Sort by name
|
|
411
411
|
return sortBy(all, 'name', false);
|
|
412
|
-
},
|
|
413
|
-
|
|
414
|
-
pluginsFromCatalogImage() {
|
|
415
|
-
return this.plugins.filter((p) => p.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE]);
|
|
416
412
|
}
|
|
417
413
|
},
|
|
418
414
|
|
|
@@ -464,15 +460,11 @@ export default {
|
|
|
464
460
|
|
|
465
461
|
neu.forEach((plugin) => {
|
|
466
462
|
const existing = installed.find((p) => !p.removed && p.name === plugin.name && p.version === plugin.version);
|
|
467
|
-
const isCustomImage = plugin.metadata?.labels?.[UI_PLUGIN_LABELS.CATALOG_IMAGE];
|
|
468
463
|
|
|
469
464
|
if (!existing && plugin.isCached) {
|
|
470
|
-
if (!this.uiErrors[plugin.name]
|
|
465
|
+
if (!this.uiErrors[plugin.name]) {
|
|
471
466
|
changes++;
|
|
472
467
|
}
|
|
473
|
-
if (isCustomImage) {
|
|
474
|
-
this.refreshCharts(true);
|
|
475
|
-
}
|
|
476
468
|
|
|
477
469
|
this.updatePluginInstallStatus(plugin.name, false);
|
|
478
470
|
}
|
|
@@ -481,7 +473,7 @@ export default {
|
|
|
481
473
|
if (changes > 0) {
|
|
482
474
|
Vue.set(this, 'reloadRequired', true);
|
|
483
475
|
}
|
|
484
|
-
}
|
|
476
|
+
}
|
|
485
477
|
},
|
|
486
478
|
|
|
487
479
|
// Forget the types when we leave the page
|
|
@@ -550,6 +542,10 @@ export default {
|
|
|
550
542
|
this.$refs.catalogLoadDialog.showDialog();
|
|
551
543
|
},
|
|
552
544
|
|
|
545
|
+
showCatalogUninstallDialog(ev) {
|
|
546
|
+
this.$refs.catalogUninstallDialog.showDialog(ev);
|
|
547
|
+
},
|
|
548
|
+
|
|
553
549
|
showInstallDialog(plugin, mode, ev) {
|
|
554
550
|
ev.target?.blur();
|
|
555
551
|
ev.preventDefault();
|
|
@@ -667,50 +663,49 @@ export default {
|
|
|
667
663
|
{{ t('plugins.title') }}
|
|
668
664
|
</h2>
|
|
669
665
|
</template>
|
|
670
|
-
<div
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
<i class="icon icon-checkmark mr-10" />
|
|
676
|
-
<span>
|
|
677
|
-
{{ t('plugins.reload') }}
|
|
678
|
-
</span>
|
|
679
|
-
<button
|
|
680
|
-
class="ml-10 btn btn-sm role-primary"
|
|
681
|
-
data-testid="extension-reload-banner-reload-btn"
|
|
682
|
-
@click="reload()"
|
|
683
|
-
>
|
|
684
|
-
{{ t('generic.reload') }}
|
|
685
|
-
</button>
|
|
686
|
-
</div>
|
|
687
|
-
<div
|
|
688
|
-
v-if="hasService && hasMenuActions"
|
|
689
|
-
class="actions-container"
|
|
690
|
-
>
|
|
691
|
-
<button
|
|
692
|
-
ref="actions"
|
|
693
|
-
aria-haspopup="true"
|
|
694
|
-
type="button"
|
|
695
|
-
class="btn role-multi-action actions"
|
|
696
|
-
data-testid="extensions-page-menu"
|
|
697
|
-
@click="setMenu"
|
|
666
|
+
<div class="actions-container">
|
|
667
|
+
<div
|
|
668
|
+
v-if="reloadRequired"
|
|
669
|
+
class="plugin-reload-banner mr-20"
|
|
670
|
+
data-testid="extension-reload-banner"
|
|
698
671
|
>
|
|
699
|
-
<i class="icon icon-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
672
|
+
<i class="icon icon-checkmark mr-10" />
|
|
673
|
+
<span>
|
|
674
|
+
{{ t('plugins.reload') }}
|
|
675
|
+
</span>
|
|
676
|
+
<button
|
|
677
|
+
class="ml-10 btn btn-sm role-primary"
|
|
678
|
+
data-testid="extension-reload-banner-reload-btn"
|
|
679
|
+
@click="reload()"
|
|
680
|
+
>
|
|
681
|
+
{{ t('generic.reload') }}
|
|
682
|
+
</button>
|
|
683
|
+
</div>
|
|
684
|
+
<div v-if="hasService && hasMenuActions">
|
|
685
|
+
<button
|
|
686
|
+
ref="actions"
|
|
687
|
+
aria-haspopup="true"
|
|
688
|
+
type="button"
|
|
689
|
+
class="btn role-multi-action actions"
|
|
690
|
+
data-testid="extensions-page-menu"
|
|
691
|
+
@click="setMenu"
|
|
692
|
+
>
|
|
693
|
+
<i class="icon icon-actions" />
|
|
694
|
+
</button>
|
|
695
|
+
<ActionMenu
|
|
696
|
+
:custom-actions="menuActions"
|
|
697
|
+
:open="menuOpen"
|
|
698
|
+
:use-custom-target-element="true"
|
|
699
|
+
:custom-target-element="menuTargetElement"
|
|
700
|
+
:custom-target-event="menuTargetEvent"
|
|
701
|
+
@close="setMenu(false)"
|
|
702
|
+
@devLoad="showDeveloperLoadDialog"
|
|
703
|
+
@removePluginSupport="removePluginSupport"
|
|
704
|
+
@manageRepos="manageRepos"
|
|
705
|
+
@addRancherRepos="showAddExtensionReposDialog"
|
|
706
|
+
@manageExtensionView="manageExtensionView"
|
|
707
|
+
/>
|
|
708
|
+
</div>
|
|
714
709
|
</div>
|
|
715
710
|
</div>
|
|
716
711
|
|
|
@@ -737,9 +732,8 @@ export default {
|
|
|
737
732
|
<div v-else>
|
|
738
733
|
<template v-if="showCatalogList">
|
|
739
734
|
<CatalogList
|
|
740
|
-
:plugins="pluginsFromCatalogImage"
|
|
741
735
|
@showCatalogLoadDialog="showCatalogLoadDialog"
|
|
742
|
-
@
|
|
736
|
+
@showCatalogUninstallDialog="showCatalogUninstallDialog($event)"
|
|
743
737
|
/>
|
|
744
738
|
</template>
|
|
745
739
|
<template v-else>
|
|
@@ -814,8 +808,8 @@ export default {
|
|
|
814
808
|
/>
|
|
815
809
|
<template v-else>
|
|
816
810
|
<div
|
|
817
|
-
v-for="plugin in list"
|
|
818
|
-
:key="plugin.name"
|
|
811
|
+
v-for="(plugin, i) in list"
|
|
812
|
+
:key="plugin.name + i"
|
|
819
813
|
class="plugin"
|
|
820
814
|
:data-testid="`extension-card-${plugin.name}`"
|
|
821
815
|
@click="showPluginDetail(plugin)"
|
|
@@ -999,6 +993,12 @@ export default {
|
|
|
999
993
|
<CatalogLoadDialog
|
|
1000
994
|
ref="catalogLoadDialog"
|
|
1001
995
|
@closed="didInstall"
|
|
996
|
+
@refresh="() => reloadRequired = true"
|
|
997
|
+
/>
|
|
998
|
+
<CatalogUninstallDialog
|
|
999
|
+
ref="catalogUninstallDialog"
|
|
1000
|
+
@closed="didUninstall"
|
|
1001
|
+
@refresh="() => reloadRequired = true"
|
|
1002
1002
|
/>
|
|
1003
1003
|
<DeveloperInstallDialog
|
|
1004
1004
|
ref="developerInstallDialog"
|
package/pages/diagnostic.vue
CHANGED
|
@@ -120,9 +120,6 @@ export default {
|
|
|
120
120
|
systemInformation.jsMemory.value += `, ${ this.t('about.diagnostic.systemInformation.memUsedJsHeapSize', { usedJSHeapSize: window?.performance?.memory?.usedJSHeapSize }) }`;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// scroll logs container to the bottom
|
|
124
|
-
this.scrollLogsToBottom();
|
|
125
|
-
|
|
126
123
|
return {
|
|
127
124
|
systemInformation,
|
|
128
125
|
topFifteenForResponseTime: null,
|
|
@@ -130,16 +127,9 @@ export default {
|
|
|
130
127
|
finalCounts: null,
|
|
131
128
|
includeResponseTimes: true,
|
|
132
129
|
storeMapping: this.$store?._modules?.root?.state,
|
|
133
|
-
latestLogs: console.logs // eslint-disable-line no-console
|
|
134
130
|
};
|
|
135
131
|
},
|
|
136
132
|
|
|
137
|
-
watch: {
|
|
138
|
-
latestLogs() {
|
|
139
|
-
this.scrollLogsToBottom();
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
|
|
143
133
|
computed: {
|
|
144
134
|
clusterCount() {
|
|
145
135
|
return this.finalCounts?.length;
|
|
@@ -147,14 +137,6 @@ export default {
|
|
|
147
137
|
},
|
|
148
138
|
|
|
149
139
|
methods: {
|
|
150
|
-
scrollLogsToBottom() {
|
|
151
|
-
this.$nextTick(() => {
|
|
152
|
-
const logsContainer = document.querySelector('.logs-container');
|
|
153
|
-
|
|
154
|
-
logsContainer.scrollTop = logsContainer.scrollHeight;
|
|
155
|
-
});
|
|
156
|
-
},
|
|
157
|
-
|
|
158
140
|
generateKey(data) {
|
|
159
141
|
const randomize = Math.random() * 10000;
|
|
160
142
|
|
|
@@ -166,7 +148,6 @@ export default {
|
|
|
166
148
|
const fileName = 'rancher-diagnostic-data.json';
|
|
167
149
|
const data = {
|
|
168
150
|
systemInformation: this.systemInformation,
|
|
169
|
-
logs: this.latestLogs,
|
|
170
151
|
storeMapping: this.parseStoreData(this.storeMapping),
|
|
171
152
|
resourceCounts: this.finalCounts,
|
|
172
153
|
responseTimes: this.responseTimes
|
|
@@ -411,26 +392,6 @@ export default {
|
|
|
411
392
|
</div>
|
|
412
393
|
</div>
|
|
413
394
|
|
|
414
|
-
<!-- Logs -->
|
|
415
|
-
<div class="mb-40">
|
|
416
|
-
<h2 class="mb-20">
|
|
417
|
-
{{ t('about.diagnostic.logs.subtitle') }}
|
|
418
|
-
</h2>
|
|
419
|
-
<ul class="logs-container">
|
|
420
|
-
<li
|
|
421
|
-
v-for="logEntry in latestLogs"
|
|
422
|
-
:key="generateKey(logEntry.timestamp)"
|
|
423
|
-
:class="logEntry.type"
|
|
424
|
-
>
|
|
425
|
-
<span class="log-entry-type">{{ logEntry.type }} :: </span>
|
|
426
|
-
<span
|
|
427
|
-
v-for="(arg, i) in logEntry.data"
|
|
428
|
-
:key="i"
|
|
429
|
-
>{{ arg }}</span>
|
|
430
|
-
</li>
|
|
431
|
-
</ul>
|
|
432
|
-
</div>
|
|
433
|
-
|
|
434
395
|
<PromptModal />
|
|
435
396
|
</div>
|
|
436
397
|
</template>
|
package/pages/home.vue
CHANGED
|
@@ -192,7 +192,7 @@ export default {
|
|
|
192
192
|
label: this.t('tableHeaders.pods'),
|
|
193
193
|
name: 'pods',
|
|
194
194
|
value: '',
|
|
195
|
-
sort: ['status.allocatable.pods', 'status.
|
|
195
|
+
sort: ['status.allocatable.pods', 'status.requested.pods'],
|
|
196
196
|
formatter: 'PodsUsage',
|
|
197
197
|
delayLoading: true
|
|
198
198
|
},
|