@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,253 @@
1
+ <script>
2
+ import AsyncButton from '@shell/components/AsyncButton';
3
+ import IconMessage from '@shell/components/IconMessage.vue';
4
+ import { CATALOG, UI_PLUGIN } from '@shell/config/types';
5
+ import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
6
+ import Dialog from '@shell/components/Dialog.vue';
7
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
8
+ import { ASYNC_BUTTON_STATES } from '@shell/components/AsyncButton.vue';
9
+ import {
10
+ UI_PLUGIN_NAMESPACE,
11
+ UI_PLUGIN_CHARTS,
12
+ UI_PLUGIN_OPERATOR_REPO_NAME,
13
+ UI_PLUGINS_REPO_NAME,
14
+ UI_PLUGINS_REPO_URL,
15
+ UI_PLUGINS_REPO_BRANCH,
16
+ } from '@shell/config/uiplugins';
17
+
18
+ export default {
19
+ components: {
20
+ AsyncButton,
21
+ Checkbox,
22
+ IconMessage,
23
+ Dialog,
24
+ },
25
+
26
+ async fetch() {
27
+ // Check to see that the charts we need are available
28
+ const c = this.$store.getters['catalog/rawCharts'];
29
+ const charts = Object.values(c);
30
+ const found = [];
31
+
32
+ UI_PLUGIN_CHARTS.forEach((c) => {
33
+ const f = charts.find(chart => chart.repoName === UI_PLUGIN_OPERATOR_REPO_NAME & chart.chartName === c);
34
+
35
+ if (f) {
36
+ found.push(f);
37
+ }
38
+ });
39
+
40
+ this.haveCharts = (found.length === UI_PLUGIN_CHARTS.length);
41
+
42
+ if (this.haveCharts) {
43
+ this.installCharts = found;
44
+
45
+ if (this.$store.getters['management/schemaFor'](CATALOG.CLUSTER_REPO)) {
46
+ await this.$store.dispatch('management/findAll', { type: CATALOG.CLUSTER_REPO });
47
+ }
48
+ }
49
+
50
+ this.loading = false;
51
+ },
52
+
53
+ data() {
54
+ return {
55
+ loading: true,
56
+ haveCharts: false,
57
+ installCharts: [],
58
+ errors: [],
59
+ addRepo: true,
60
+ buttonState: ASYNC_BUTTON_STATES.ACTION,
61
+ };
62
+ },
63
+
64
+ computed: {
65
+ hasRancherUIPluginsRepo() {
66
+ // Look to see if the Rancher UI Plugins repository is already installed
67
+ const repos = this.$store.getters['catalog/repos'];
68
+
69
+ return !!repos.find(r => r.name === UI_PLUGINS_REPO_NAME);
70
+ }
71
+ },
72
+
73
+ methods: {
74
+ async installChart(installChart) {
75
+ const version = installChart.versions[0];
76
+ const repoType = version.repoType;
77
+ const repoName = version.repoName;
78
+ const repo = this.$store.getters['catalog/repo']({ repoType, repoName });
79
+
80
+ const chart = {
81
+ chartName: installChart.chartName,
82
+ version: version.version,
83
+ releaseName: installChart.chartName,
84
+ annotations: {
85
+ [CATALOG_ANNOTATIONS.SOURCE_REPO_TYPE]: repoType,
86
+ [CATALOG_ANNOTATIONS.SOURCE_REPO_NAME]: repoName
87
+ },
88
+ values: {}
89
+ };
90
+
91
+ const input = {
92
+ charts: [chart],
93
+ wait: true,
94
+ namespace: UI_PLUGIN_NAMESPACE,
95
+ };
96
+
97
+ const action = 'install';
98
+ const res = await repo.doAction(action, input);
99
+ const operationId = `${ res.operationNamespace }/${ res.operationName }`;
100
+
101
+ await repo.waitForOperation(operationId);
102
+
103
+ return this.$store.dispatch(`management/find`, {
104
+ type: CATALOG.OPERATION,
105
+ id: operationId
106
+ });
107
+ },
108
+
109
+ enable() {
110
+ this.errors = [];
111
+
112
+ // Reset checkbox bsed on if the repo is already installed
113
+ this.addRepo = !this.hasRancherUIPluginsRepo;
114
+
115
+ this.$modal.show('confirm-uiplugins-setup');
116
+ },
117
+
118
+ async dialogClosed(ok) {
119
+ this.errors = [];
120
+
121
+ // User wants to proceed
122
+ if (ok) {
123
+ this.buttonState = ASYNC_BUTTON_STATES.WAITING;
124
+
125
+ if (this.addRepo) {
126
+ await this.addDefaultHelmRepository();
127
+ }
128
+
129
+ await this.installPluginCharts();
130
+
131
+ await new Promise(resolve => setTimeout(resolve, 5000));
132
+
133
+ this.$store.dispatch('management/forgetType', UI_PLUGIN);
134
+
135
+ this.buttonState = this.errors.length > 0 ? ASYNC_BUTTON_STATES.ERROR : ASYNC_BUTTON_STATES.ACTION;
136
+
137
+ this.$router.push(
138
+ {
139
+ path: this.$route.path,
140
+ force: true,
141
+ },
142
+ );
143
+ }
144
+ },
145
+
146
+ async addDefaultHelmRepository() {
147
+ const name = UI_PLUGINS_REPO_NAME;
148
+
149
+ try {
150
+ const pluginCR = await this.$store.dispatch('management/create', {
151
+ type: CATALOG.CLUSTER_REPO,
152
+ metadata: { name },
153
+ spec: {
154
+ gitBranch: UI_PLUGINS_REPO_BRANCH,
155
+ gitRepo: UI_PLUGINS_REPO_URL,
156
+ }
157
+ });
158
+
159
+ return pluginCR.save();
160
+ } catch (e) {
161
+ console.error(e); // eslint-disable-line no-console
162
+
163
+ this.errors.push(e.message);
164
+ }
165
+ },
166
+
167
+ async installPluginCharts() {
168
+ for (let i = 0; i < this.installCharts.length; i++) {
169
+ const chart = this.installCharts[i];
170
+
171
+ try {
172
+ await this.installChart(chart);
173
+ } catch (e) {
174
+ this.errors.push(e.message);
175
+ }
176
+ }
177
+
178
+ return new Promise(resolve => setTimeout(resolve, 2000));
179
+ }
180
+ }
181
+ };
182
+ </script>
183
+ <template>
184
+ <div>
185
+ <IconMessage
186
+ :vertical="true"
187
+ :subtle="false"
188
+ icon="icon-gear"
189
+ >
190
+ <template v-slot:message>
191
+ <h2>
192
+ {{ t('plugins.setup.title') }}
193
+ </h2>
194
+ <div v-if="!loading">
195
+ <div v-if="!haveCharts">
196
+ <p>
197
+ {{ t('plugins.setup.prompt.cant') }}
198
+ </p>
199
+ </div>
200
+ <div v-else>
201
+ <p>
202
+ {{ t('plugins.setup.prompt.can') }}
203
+ </p>
204
+ <AsyncButton
205
+ mode="enable"
206
+ :manual="true"
207
+ :current-phase="buttonState"
208
+ class="enable-plugin-support"
209
+ @click="enable"
210
+ />
211
+ </div>
212
+ <div v-for="(e, i) in errors" :key="i" class="plugin-setup-error">
213
+ {{ e }}
214
+ </div>
215
+ </div>
216
+ </template>
217
+ </IconMessage>
218
+ <Dialog
219
+ name="confirm-uiplugins-setup"
220
+ :title="t('plugins.setup.install.title')"
221
+ @closed="dialogClosed"
222
+ >
223
+ <template>
224
+ <p>
225
+ {{ t('plugins.setup.install.prompt') }}
226
+ </p>
227
+ <div v-if="!hasRancherUIPluginsRepo" class="mt-20">
228
+ <Checkbox v-model="addRepo" :primary="true" label-key="plugins.setup.install.addRancherRepo" />
229
+ <div class="checkbox-info">
230
+ {{ t('plugins.setup.install.airgap') }}
231
+ </div>
232
+ </div>
233
+ </template>
234
+ </Dialog>
235
+ </div>
236
+ </template>
237
+ <style lang="scss" scoped>
238
+ .enable-plugin-support {
239
+ font-size: 14px;
240
+ margin-top: 20px;
241
+ }
242
+
243
+ .plugin-setup-error {
244
+ font-size: 14px;
245
+ color: var(--error);
246
+ margin: 10px 0 0 0;
247
+ }
248
+
249
+ .checkbox-info {
250
+ margin-left: 20px;
251
+ opacity: 0.7;
252
+ }
253
+ </style>
@@ -0,0 +1,115 @@
1
+ <script>
2
+ import AsyncButton from '@shell/components/AsyncButton';
3
+ import { CATALOG } from '@shell/config/types';
4
+
5
+ import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
6
+
7
+ export default {
8
+ components: { AsyncButton },
9
+
10
+ data() {
11
+ return { plugin: undefined, busy: false };
12
+ },
13
+
14
+ methods: {
15
+ showDialog(plugin) {
16
+ this.plugin = plugin;
17
+ this.busy = false;
18
+ this.$modal.show('uninstallPluginDialog');
19
+ },
20
+ closeDialog(result) {
21
+ this.$modal.hide('uninstallPluginDialog');
22
+ this.$emit('closed', result);
23
+ },
24
+ async uninstall() {
25
+ this.busy = true;
26
+
27
+ const plugin = this.plugin;
28
+
29
+ // Delete the CR if this is a developer plugin (there is no Helm App, so need to remove the CRD ourselves)
30
+ if (plugin.uiplugin?.isDeveloper) {
31
+ // Delete the custom resource
32
+ await plugin.uiplugin.remove();
33
+ }
34
+
35
+ // Find the app for this plugin
36
+ const apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
37
+
38
+ const pluginApp = apps.find((app) => {
39
+ return app.namespace === UI_PLUGIN_NAMESPACE && app.name === plugin.name;
40
+ });
41
+
42
+ if (pluginApp) {
43
+ await pluginApp.remove();
44
+
45
+ await this.$store.dispatch('management/findAll', { type: CATALOG.OPERATION });
46
+ }
47
+
48
+ // Unload the plugin code
49
+ this.$plugin.removePlugin(plugin.name);
50
+
51
+ this.closeDialog(plugin);
52
+ }
53
+ }
54
+ };
55
+ </script>
56
+
57
+ <template>
58
+ <modal
59
+ name="uninstallPluginDialog"
60
+ height="auto"
61
+ :scrollable="true"
62
+ >
63
+ <div v-if="plugin" class="plugin-install-dialog">
64
+ <h4 class="mt-10">
65
+ {{ t('plugins.uninstall.title', { name: plugin.name }) }}
66
+ </h4>
67
+ <div class="mt-10 dialog-panel">
68
+ <div class="dialog-info">
69
+ <p>
70
+ {{ t('plugins.uninstall.prompt') }}
71
+ </p>
72
+ </div>
73
+ <div class="dialog-buttons">
74
+ <button :disabled="busy" class="btn role-secondary" @click="closeDialog(false)">
75
+ {{ t('generic.cancel') }}
76
+ </button>
77
+ <AsyncButton
78
+ mode="uninstall"
79
+ @click="uninstall()"
80
+ />
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </modal>
85
+ </template>
86
+
87
+ <style lang="scss" scoped>
88
+ .plugin-install-dialog {
89
+ padding: 10px;
90
+
91
+ h4 {
92
+ font-weight: bold;
93
+ }
94
+
95
+ .dialog-panel {
96
+ display: flex;
97
+ flex-direction: column;
98
+ min-height: 100px;
99
+
100
+ .dialog-info {
101
+ flex: 1;
102
+ }
103
+ }
104
+
105
+ .dialog-buttons {
106
+ display: flex;
107
+ justify-content: flex-end;
108
+ margin-top: 10px;
109
+
110
+ > *:not(:last-child) {
111
+ margin-right: 10px;
112
+ }
113
+ }
114
+ }
115
+ </style>