@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.
Files changed (131) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/rancher-logo.svg +1 -130
  3. package/assets/images/featured/img1.jpg +0 -0
  4. package/assets/images/featured.jpg +0 -0
  5. package/assets/images/generic-plugin.svg +7 -0
  6. package/assets/styles/themes/_dark.scss +3 -0
  7. package/assets/styles/themes/_light.scss +3 -0
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/translations/en-us.yaml +183 -45
  10. package/assets/translations/zh-hans.yaml +21 -24
  11. package/components/AsyncButton.vue +17 -2
  12. package/components/ButtonDropdown.vue +4 -0
  13. package/components/Carousel.vue +291 -0
  14. package/components/CommunityLinks.vue +69 -18
  15. package/components/CruResource.vue +11 -3
  16. package/components/Dialog.vue +102 -0
  17. package/components/ExplorerMembers.vue +2 -4
  18. package/components/ExplorerProjectsNamespaces.vue +6 -7
  19. package/components/IconMessage.vue +9 -1
  20. package/components/LocaleSelector.vue +62 -29
  21. package/components/ResourceTable.vue +7 -2
  22. package/components/SimpleBox.vue +6 -4
  23. package/components/SortableTable/index.vue +11 -21
  24. package/components/Tabbed/Tab.vue +5 -0
  25. package/components/Tabbed/index.vue +29 -2
  26. package/components/auth/Principal.vue +1 -0
  27. package/components/fleet/FleetBundles.vue +8 -3
  28. package/components/fleet/FleetSummary.vue +6 -0
  29. package/components/form/KeyValue.vue +80 -58
  30. package/components/form/NameNsDescription.vue +10 -4
  31. package/components/form/ResourceTabs/index.vue +5 -1
  32. package/components/formatter/ClusterLink.vue +3 -7
  33. package/components/nav/NamespaceFilter.vue +3 -3
  34. package/components/nav/TopLevelMenu.vue +10 -28
  35. package/config/footer.js +13 -14
  36. package/config/labels-annotations.js +2 -1
  37. package/config/product/explorer.js +5 -4
  38. package/config/product/legacy.js +0 -47
  39. package/config/product/multi-cluster-apps.js +0 -12
  40. package/config/product/settings.js +12 -1
  41. package/config/product/uiplugins.js +17 -0
  42. package/config/settings.js +21 -2
  43. package/config/types.js +5 -1
  44. package/config/uiplugins.js +60 -0
  45. package/content/docs/en-us/getting-started.md +1 -26
  46. package/core/plugins.js +12 -0
  47. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  48. package/detail/workload/index.vue +2 -2
  49. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  50. package/dialog/RotateCertificatesDialog.vue +9 -3
  51. package/edit/auth/azuread.vue +28 -9
  52. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  53. package/edit/persistentvolume/index.vue +3 -0
  54. package/edit/pod.vue +27 -0
  55. package/edit/provisioning.cattle.io.cluster/rke2.vue +76 -5
  56. package/edit/service.vue +7 -5
  57. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  58. package/edit/workload/index.vue +13 -1
  59. package/edit/workload/mixins/workload.js +13 -13
  60. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  61. package/edit/workload/storage/Mount.vue +1 -0
  62. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  63. package/edit/workload/storage/azureDisk.vue +22 -2
  64. package/edit/workload/storage/azureFile.vue +20 -2
  65. package/edit/workload/storage/csi/index.vue +23 -1
  66. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  67. package/edit/workload/storage/index.vue +23 -49
  68. package/edit/workload/storage/vsphereVolume.vue +11 -1
  69. package/layouts/default.vue +14 -8
  70. package/layouts/home.vue +9 -4
  71. package/layouts/plain.vue +10 -5
  72. package/list/management.cattle.io.setting.vue +3 -3
  73. package/list/provisioning.cattle.io.cluster.vue +1 -1
  74. package/machine-config/harvester.vue +5 -3
  75. package/models/catalog.cattle.io.uiplugin.js +34 -0
  76. package/models/cluster/node.js +25 -2
  77. package/models/fleet.cattle.io.bundle.js +1 -1
  78. package/models/harvesterhci.io.management.cluster.js +11 -5
  79. package/models/provisioning.cattle.io.cluster.js +12 -6
  80. package/models/workload.js +5 -3
  81. package/nuxt.config.js +69 -25
  82. package/package.json +108 -109
  83. package/pages/auth/login.vue +1 -1
  84. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  85. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  86. package/pages/c/_cluster/explorer/index.vue +72 -9
  87. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  88. package/pages/c/_cluster/mcapps/index.vue +1 -1
  89. package/pages/c/_cluster/settings/brand.vue +0 -40
  90. package/pages/c/_cluster/settings/links.vue +200 -0
  91. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  92. package/pages/c/_cluster/uiplugins/InstallDialog.vue +242 -0
  93. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +284 -0
  94. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +130 -0
  95. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +253 -0
  96. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +115 -0
  97. package/pages/c/_cluster/uiplugins/index.vue +694 -0
  98. package/pages/diagnostic.vue +185 -101
  99. package/pages/docs/_doc.vue +3 -1
  100. package/pages/home.vue +21 -56
  101. package/pages/prefs.vue +108 -88
  102. package/pages/safeMode.vue +17 -0
  103. package/pages/support/index.vue +23 -15
  104. package/pkg/dynamic-importer.lib.js +4 -0
  105. package/plugins/dashboard-store/resource-class.js +2 -2
  106. package/plugins/formatters.js +15 -0
  107. package/plugins/plugin.js +56 -4
  108. package/plugins/steve/mutations.js +1 -1
  109. package/plugins/steve/subscribe.js +94 -72
  110. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  111. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  112. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  113. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  114. package/scripts/publish-shell.sh +1 -1
  115. package/scripts/sync-shell-deps +37 -0
  116. package/store/catalog.js +9 -8
  117. package/store/i18n.js +10 -1
  118. package/store/prefs.js +16 -0
  119. package/store/type-map.js +32 -5
  120. package/store/uiplugins.ts +15 -61
  121. package/utils/__tests__/object.test.ts +0 -24
  122. package/utils/__tests__/selector.test.ts +1 -1
  123. package/utils/dynamic-importer.js +4 -0
  124. package/utils/grafana.js +2 -6
  125. package/utils/socket.js +41 -20
  126. package/utils/string.js +1 -7
  127. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  128. package/utils/validators/formRules/index.ts +9 -1
  129. package/yarn-error.log +195 -0
  130. package/pages/plugins.vue +0 -387
  131. package/server/verdaccio-middleware.js +0 -56
@@ -0,0 +1,242 @@
1
+ <script>
2
+ import AsyncButton from '@shell/components/AsyncButton';
3
+ import LabeledSelect from '@shell/components/form/LabeledSelect';
4
+ import { CATALOG } from '@shell/config/types';
5
+ import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
6
+ import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
7
+ import Banner from '@components/Banner/Banner.vue';
8
+
9
+ // Note: This dialog handles installation and update of a plugin
10
+
11
+ export default {
12
+ components: {
13
+ AsyncButton,
14
+ Banner,
15
+ LabeledSelect,
16
+ },
17
+
18
+ data() {
19
+ return {
20
+ plugin: undefined,
21
+ busy: false,
22
+ version: '',
23
+ update: false,
24
+ mode: '',
25
+ };
26
+ },
27
+
28
+ computed: {
29
+ showVersionSelector() {
30
+ return this.plugin?.versions.length > 1;
31
+ },
32
+
33
+ versionOptions() {
34
+ if (!this.plugin) {
35
+ return [];
36
+ }
37
+
38
+ return this.plugin.versions.map((version) => {
39
+ return {
40
+ label: version.version,
41
+ value: version.version,
42
+ };
43
+ });
44
+ },
45
+
46
+ buttonMode() {
47
+ return this.update ? 'update' : 'install';
48
+ }
49
+ },
50
+
51
+ methods: {
52
+ showDialog(plugin, mode) {
53
+ this.plugin = plugin;
54
+ this.mode = mode;
55
+
56
+ // Default to latest version on install (this is default on the plugin)
57
+ this.version = plugin.displayVersion;
58
+
59
+ if (mode === 'update') {
60
+ // Update to latest version, so take the first version
61
+ if (plugin.versions.length > 0) {
62
+ this.version = plugin.versions[0].version;
63
+ }
64
+ } else if (mode === 'rollback') {
65
+ // Find the newest version once we remove the current version
66
+ const versionNames = plugin.versions.filter(v => v.version !== plugin.displayVersion);
67
+
68
+ if (versionNames.length > 0) {
69
+ this.version = versionNames[0].version;
70
+ }
71
+ }
72
+
73
+ // Make sure we have the version available
74
+ const versionChart = plugin.versions?.find(v => v.version === this.version);
75
+
76
+ if (!versionChart) {
77
+ this.version = plugin.versions[0].version;
78
+ }
79
+
80
+ this.busy = false;
81
+ this.update = mode !== 'install';
82
+ this.$modal.show('installPluginDialog');
83
+ },
84
+
85
+ closeDialog(result) {
86
+ this.$modal.hide('installPluginDialog');
87
+ this.$emit('closed', result);
88
+ },
89
+
90
+ async install() {
91
+ this.busy = true;
92
+
93
+ const plugin = this.plugin;
94
+
95
+ this.$emit(plugin.name, 'install');
96
+
97
+ // Find the version that the user wants to install
98
+ const version = plugin.versions?.find(v => v.version === this.version);
99
+
100
+ if (!version) {
101
+ this.busy = false;
102
+
103
+ return;
104
+ }
105
+
106
+ const repoType = version.repoType;
107
+ const repoName = version.repoName;
108
+ const repo = this.$store.getters['catalog/repo']({ repoType, repoName });
109
+
110
+ const chart = {
111
+ chartName: plugin.chart.chartName,
112
+ version: this.version,
113
+ releaseName: plugin.chart.chartName,
114
+ annotations: {
115
+ [CATALOG_ANNOTATIONS.SOURCE_REPO_TYPE]: plugin.repoType,
116
+ [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: plugin.repoName
117
+ },
118
+ values: {}
119
+ };
120
+
121
+ const input = {
122
+ charts: [chart],
123
+ // timeout: this.cmdOptions.timeout > 0 ? `${ this.cmdOptions.timeout }s` : null,
124
+ // wait: this.cmdOptions.wait === true,
125
+ namespace: UI_PLUGIN_NAMESPACE,
126
+ };
127
+
128
+ // Helm action
129
+ const action = this.update ? 'upgrade' : 'install';
130
+
131
+ // const name = plugin.chart.chartName;
132
+
133
+ // const res = await this.repo.doAction((isUpgrade ? 'upgrade' : 'install'), input);
134
+ const res = await repo.doAction(action, input);
135
+ const operationId = `${ res.operationNamespace }/${ res.operationName }`;
136
+
137
+ // Vue.set(this.installing, this.selected.chart.chartName, operationId);
138
+
139
+ this.closeDialog(plugin);
140
+
141
+ await repo.waitForOperation(operationId);
142
+
143
+ await this.$store.dispatch(`management/find`, {
144
+ type: CATALOG.OPERATION,
145
+ id: operationId
146
+ });
147
+ }
148
+ }
149
+ };
150
+ </script>
151
+
152
+ <template>
153
+ <modal
154
+ name="installPluginDialog"
155
+ height="auto"
156
+ :scrollable="true"
157
+ >
158
+ <div v-if="plugin" class="plugin-install-dialog">
159
+ <h4 class="mt-10">
160
+ {{ t(`plugins.${ mode }.title`, { name: plugin.name }) }}
161
+ </h4>
162
+ <div class="custom mt-10">
163
+ <div class="dialog-panel">
164
+ <p>
165
+ {{ t(`plugins.${ mode }.prompt`) }}
166
+ </p>
167
+ <Banner v-if="!plugin.certified" color="warning" :label="t('plugins.install.warnNotCertified')" />
168
+ <LabeledSelect
169
+ v-if="showVersionSelector"
170
+ v-model="version"
171
+ label-key="plugins.install.version"
172
+ :options="versionOptions"
173
+ class="version-selector mt-10"
174
+ />
175
+ <div v-else>
176
+ {{ t('plugins.install.version') }} {{ version }}
177
+ </div>
178
+ </div>
179
+ <div class="dialog-buttons">
180
+ <button :disabled="busy" class="btn role-secondary" @click="closeDialog(false)">
181
+ {{ t('generic.cancel') }}
182
+ </button>
183
+ <AsyncButton
184
+ :mode="buttonMode"
185
+ @click="install"
186
+ />
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </modal>
191
+ </template>
192
+
193
+ <style lang="scss" scoped>
194
+ .plugin-install-dialog {
195
+ padding: 10px;
196
+
197
+ h4 {
198
+ font-weight: bold;
199
+ }
200
+
201
+ .dialog-panel {
202
+ display: flex;
203
+ flex-direction: column;
204
+ min-height: 100px;
205
+
206
+ p {
207
+ margin-bottom: 5px;
208
+ }
209
+
210
+ .dialog-info {
211
+ flex: 1;
212
+ }
213
+
214
+ .toggle-advanced {
215
+ display: flex;
216
+ align-items: center;
217
+ cursor: pointer;
218
+ margin: 10px 0;
219
+
220
+ &:hover {
221
+ text-decoration: none;
222
+ color: var(--link);
223
+ }
224
+ }
225
+
226
+ .version-selector {
227
+ margin: 0 10px 10px 10px;
228
+ width: auto;
229
+ }
230
+ }
231
+
232
+ .dialog-buttons {
233
+ display: flex;
234
+ justify-content: flex-end;
235
+ margin-top: 10px;
236
+
237
+ > *:not(:last-child) {
238
+ margin-right: 10px;
239
+ }
240
+ }
241
+ }
242
+ </style>
@@ -0,0 +1,284 @@
1
+ <script>
2
+ import ChartReadme from '@shell/components/ChartReadme';
3
+ import { Banner } from '@components/Banner';
4
+ import LazyImage from '@shell/components/LazyImage';
5
+
6
+ export default {
7
+ components: {
8
+ Banner,
9
+ ChartReadme,
10
+ LazyImage
11
+ },
12
+
13
+ data() {
14
+ return {
15
+ showSlideIn: false,
16
+ info: undefined,
17
+ infoVersion: undefined,
18
+ versionInfo: undefined,
19
+ versionError: undefined,
20
+ defaultIcon: require('~shell/assets/images/generic-plugin.svg'),
21
+ };
22
+ },
23
+
24
+ methods: {
25
+ show(info) {
26
+ this.info = info;
27
+ this.showSlideIn = true;
28
+ this.version = null;
29
+ this.versionInfo = null;
30
+ this.versionError = null;
31
+
32
+ this.loadPluginVersionInfo();
33
+ },
34
+
35
+ hide() {
36
+ this.showSlideIn = false;
37
+ },
38
+
39
+ async loadPluginVersionInfo(version) {
40
+ this.versionError = false;
41
+ this.versionInfo = undefined;
42
+
43
+ const versionName = version || this.info.displayVersion;
44
+
45
+ this.infoVersion = versionName;
46
+
47
+ if (!this.info.chart) {
48
+ return;
49
+ }
50
+
51
+ try {
52
+ this.versionInfo = await this.$store.dispatch('catalog/getVersionInfo', {
53
+ repoType: this.info.chart.repoType,
54
+ repoName: this.info.chart.repoName,
55
+ chartName: this.info.chart.chartName,
56
+ versionName
57
+ });
58
+ // Here we set us versionInfo. The returned
59
+ // object contains everything all info
60
+ // about a currently installed app, and it has the
61
+ // following keys:
62
+ //
63
+ // - appReadme: A short overview of what the app does. This
64
+ // forms the first few paragraphs of the chart info when
65
+ // you install a Helm chart app through Rancher.
66
+ // - chart: Metadata about the Helm chart, including the
67
+ // name and version.
68
+ // - readme: This is more detailed information that appears
69
+ // under the heading "Chart Information (Helm README)" when
70
+ // you install or upgrade a Helm chart app through Rancher,
71
+ // below the app README.
72
+ // - values: All Helm chart values for the currently installed
73
+ // app.
74
+ } catch (e) {
75
+ this.versionError = true;
76
+ console.error('Unable to fetch VersionInfo: ', e); // eslint-disable-line no-console
77
+ }
78
+ }
79
+ }
80
+ };
81
+ </script>
82
+ <template>
83
+ <div class="plugin-info-panel">
84
+ <div v-if="showSlideIn" class="glass" @click="hide()" />
85
+ <div class="slideIn" :class="{'hide': false, 'slideIn__show': showSlideIn}">
86
+ <div v-if="info">
87
+ <div class="plugin-header">
88
+ <div class="plugin-icon">
89
+ <LazyImage
90
+ v-if="info.icon"
91
+ :initial-src="defaultIcon"
92
+ :error-src="defaultIcon"
93
+ :src="info.icon"
94
+ class="icon plugin-icon-img"
95
+ />
96
+ <img
97
+ v-else
98
+ :src="defaultIcon"
99
+ class="icon plugin-icon-img"
100
+ />
101
+ </div>
102
+ <div class="plugin-title">
103
+ <h2 class="slideIn__header">
104
+ {{ info.name }}
105
+ </h2>
106
+ <p class="plugin-description">
107
+ {{ info.description }}
108
+ </p>
109
+ </div>
110
+ <div class="plugin-close">
111
+ <div class="slideIn__header__buttons">
112
+ <div class="slideIn__header__button" @click="showSlideIn = false">
113
+ <i class="icon icon-close" />
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ <div>
119
+ <Banner v-if="!info.certified" color="warning" :label="t('plugins.descriptions.third-party')" class="mt-10" />
120
+ <Banner v-if="info.experimental" color="warning" :label="t('plugins.descriptions.experimental')" class="mt-10" />
121
+ </div>
122
+
123
+ <h3 v-if="info.versions">
124
+ {{ t('plugins.info.versions') }}
125
+ </h3>
126
+ <div class="plugin-versions mb-10">
127
+ <div v-for="v in info.versions" :key="v.version">
128
+ <a
129
+ class="version-link"
130
+ :class="{'version-active': v.version === infoVersion}"
131
+ @click="loadPluginVersionInfo(v.version)"
132
+ >
133
+ {{ v.version }}
134
+ </a>
135
+ </div>
136
+ </div>
137
+
138
+ <div v-if="versionError">
139
+ {{ t('plugins.info.versionError') }}
140
+ </div>
141
+ <div v-else>
142
+ <h3>
143
+ {{ t('plugins.info.detail') }}
144
+ </h3>
145
+ <ChartReadme v-if="versionInfo" :version-info="versionInfo" />
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </template>
151
+ <style lang="scss" scoped>
152
+ .plugin-info-panel {
153
+ position: fixed;
154
+ top: 0;
155
+ left: 0;
156
+
157
+ $slideout-width: 35%;
158
+ $title-height: 50px;
159
+ $padding: 5px;
160
+ $slideout-width: 35%;
161
+ $header-height: 54px;
162
+
163
+ .glass {
164
+ z-index: 9;
165
+ position: fixed;
166
+ top: $header-height;
167
+ height: calc(100% - $header-height);
168
+ left: 0;
169
+ width: 100%;
170
+ opacity: 0;
171
+ }
172
+
173
+ .slideIn {
174
+ border-left: var(--header-border-size) solid var(--header-border);
175
+ position: fixed;
176
+ top: $header-height;
177
+ right: -$slideout-width;
178
+ height: calc(100% - $header-height);
179
+ background-color: var(--topmenu-bg);
180
+ width: $slideout-width;
181
+ z-index: 10;
182
+ display: flex;
183
+ flex-direction: column;
184
+
185
+ padding: 10px;
186
+
187
+ transition: right .5s ease;
188
+
189
+ h3 {
190
+ font-size: 14px;
191
+ margin: 15px 0 10px 0;
192
+ opacity: 0.7;
193
+ text-transform: uppercase;
194
+ }
195
+
196
+ .plugin-header {
197
+ border-bottom: 1px solid var(--border);
198
+ display: flex;
199
+ padding-bottom: 20px;
200
+
201
+ .plugin-title {
202
+ flex: 1;
203
+ }
204
+ }
205
+
206
+ .plugin-icon {
207
+ font-size: 40px;
208
+ margin-right:10px;
209
+ color: #888;
210
+
211
+ .plugin-icon-img {
212
+ height: 40px;
213
+ width: 40px;
214
+ }
215
+ }
216
+
217
+ .plugin-versions {
218
+ display: flex;
219
+ }
220
+
221
+ .plugin-description {
222
+ font-size: 15px;
223
+ }
224
+
225
+ .version-link {
226
+ cursor: pointer;
227
+ border: 1px solid var(--link);
228
+ padding: 2px 8px;
229
+ border-radius: 5px;
230
+ user-select: none;
231
+ margin-right: 5px;
232
+
233
+ &.version-active {
234
+ color: var(--link-text);
235
+ background: var(--link);
236
+ }
237
+ }
238
+
239
+ &__header {
240
+ display: flex;
241
+ align-items: center;
242
+ justify-content: space-between;
243
+
244
+ &__buttons {
245
+ display: flex;
246
+ }
247
+
248
+ &__button {
249
+ cursor: pointer;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ padding: 2px;
254
+ > i {
255
+ font-size: 20px;
256
+ opacity: 0.5;
257
+ }
258
+ &:hover {
259
+ background-color: var(--wm-closer-hover-bg);
260
+ }
261
+ }
262
+ }
263
+
264
+ .chart-content__tabs {
265
+ display: flex;
266
+ flex-direction: column;
267
+ flex: 1;
268
+
269
+ height: 0;
270
+
271
+ padding-bottom: 10px;
272
+
273
+ ::v-deep .chart-readmes {
274
+ flex: 1;
275
+ overflow: auto;
276
+ }
277
+ }
278
+
279
+ &__show {
280
+ right: 0;
281
+ }
282
+ }
283
+ }
284
+ </style>
@@ -0,0 +1,130 @@
1
+ <script>
2
+ import { CATALOG, UI_PLUGIN } from '@shell/config/types';
3
+ import Dialog from '@shell/components/Dialog.vue';
4
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
5
+ import {
6
+ UI_PLUGIN_NAMESPACE,
7
+ UI_PLUGIN_CHARTS,
8
+ UI_PLUGINS_REPO_NAME,
9
+ UI_PLUGINS_REPO_URL,
10
+ } from '@shell/config/uiplugins';
11
+
12
+ export default {
13
+ components: {
14
+ Checkbox,
15
+ Dialog,
16
+ },
17
+
18
+ async fetch() {
19
+ if (this.$store.getters['management/schemaFor'](CATALOG.CLUSTER_REPO)) {
20
+ const repos = await this.$store.dispatch('management/findAll', { type: CATALOG.CLUSTER_REPO, opt: { force: true } });
21
+
22
+ this.defaultRepo = repos.find(r => r.name === UI_PLUGINS_REPO_NAME && r.spec.gitRepo === UI_PLUGINS_REPO_URL);
23
+ }
24
+ },
25
+
26
+ data() {
27
+ return {
28
+ errors: [],
29
+ defaultRepo: undefined,
30
+ removeRepo: false,
31
+ };
32
+ },
33
+
34
+ methods: {
35
+ async removeChart(name) {
36
+ const apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
37
+ const found = apps.find((app) => {
38
+ return app.namespace === UI_PLUGIN_NAMESPACE && app.name === name;
39
+ });
40
+
41
+ if (found) {
42
+ return found.remove();
43
+ }
44
+
45
+ // TODO - Return rejected promise - error
46
+ return null;
47
+ },
48
+
49
+ showDialog() {
50
+ this.removeRepo = !!this.defaultRepo;
51
+ this.$modal.show('confirm-uiplugins-remove');
52
+ },
53
+
54
+ async doRemove(btnCb) {
55
+ this.errors = [];
56
+
57
+ // Remove the charts in the reverse order that we install them in
58
+ const uninstall = [...UI_PLUGIN_CHARTS].reverse();
59
+
60
+ for (let i = 0; i < uninstall.length; i++) {
61
+ const chart = uninstall[i];
62
+
63
+ try {
64
+ await this.removeChart(chart);
65
+ } catch (e) {
66
+ this.errors.push(e.message);
67
+ }
68
+ }
69
+
70
+ if (this.removeRepo && this.defaultRepo) {
71
+ try {
72
+ await this.defaultRepo.remove();
73
+ } catch (e) {
74
+ this.errors.push(e.message);
75
+ }
76
+ }
77
+
78
+ this.$store.dispatch('management/forgetType', UI_PLUGIN);
79
+
80
+ await new Promise(resolve => setTimeout(resolve, 5000));
81
+
82
+ btnCb(true);
83
+
84
+ this.$router.push(
85
+ {
86
+ path: this.$route.path,
87
+ force: true,
88
+ },
89
+ );
90
+ },
91
+ }
92
+ };
93
+ </script>
94
+ <template>
95
+ <Dialog
96
+ name="confirm-uiplugins-remove"
97
+ :title="t('plugins.setup.remove.title')"
98
+ mode="disable"
99
+ @okay="doRemove"
100
+ >
101
+ <template>
102
+ <p>
103
+ {{ t('plugins.setup.remove.prompt') }}
104
+ </p>
105
+ <div v-if="!!defaultRepo" class="mt-20">
106
+ <Checkbox v-model="removeRepo" :primary="true" label-key="plugins.setup.remove.registry.title" />
107
+ <div class="checkbox-info">
108
+ {{ t('plugins.setup.remove.registry.prompt') }}
109
+ </div>
110
+ </div>
111
+ </template>
112
+ </Dialog>
113
+ </template>
114
+ <style lang="scss" scoped>
115
+ .enable-plugin-support {
116
+ font-size: 14px;
117
+ margin-top: 20px;
118
+ }
119
+
120
+ .plugin-setup-error {
121
+ font-size: 14px;
122
+ color: var(--error);
123
+ margin: 10px 0 0 0;
124
+ }
125
+
126
+ .checkbox-info {
127
+ margin-left: 20px;
128
+ opacity: 0.7;
129
+ }
130
+ </style>