@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
package/pages/diagnostic.vue
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { CAPI } from '@shell/config/types';
|
|
3
3
|
import AsyncButton from '@shell/components/AsyncButton';
|
|
4
|
+
import PromptModal from '@shell/components/PromptModal';
|
|
4
5
|
import { downloadFile } from '@shell/utils/download';
|
|
5
6
|
import { filterOnlyKubernetesClusters, filterHiddenLocalCluster } from '@shell/utils/cluster';
|
|
6
7
|
import { sortBy } from '@shell/utils/sort';
|
|
7
|
-
import { Checkbox } from '@components/Form/Checkbox';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
name: 'Diagnostic',
|
|
11
|
+
layout: 'plain',
|
|
12
|
+
|
|
13
|
+
components: { AsyncButton, PromptModal },
|
|
14
|
+
|
|
12
15
|
async fetch() {
|
|
13
16
|
const provClusters = await this.$store.dispatch('management/findAll', { type: CAPI.RANCHER_CLUSTER });
|
|
14
17
|
const readyClusters = provClusters.filter(c => c.mgmt?.isReady);
|
|
@@ -20,9 +23,11 @@ export default {
|
|
|
20
23
|
clusterForCounts.forEach((cluster, i) => {
|
|
21
24
|
finalCounts.push({
|
|
22
25
|
id: cluster.id,
|
|
26
|
+
name: cluster.metadata?.name,
|
|
27
|
+
namespace: cluster.metadata?.namespace,
|
|
23
28
|
capiId: cluster.mgmt?.id,
|
|
24
29
|
counts: null,
|
|
25
|
-
isTableVisible: i === 0
|
|
30
|
+
isTableVisible: !!(i === 0 && clusterForCounts.length === 1)
|
|
26
31
|
});
|
|
27
32
|
promises.push(this.$store.dispatch('management/request', { url: `/k8s/clusters/${ cluster.mgmt?.id }/v1/counts` }));
|
|
28
33
|
});
|
|
@@ -47,7 +52,7 @@ export default {
|
|
|
47
52
|
|
|
48
53
|
topTenForResponseTime = topTenForResponseTime.concat(sortedCount);
|
|
49
54
|
topTenForResponseTime = sortBy(topTenForResponseTime, 'count:desc');
|
|
50
|
-
topTenForResponseTime = topTenForResponseTime.splice(0,
|
|
55
|
+
topTenForResponseTime = topTenForResponseTime.splice(0, 15);
|
|
51
56
|
|
|
52
57
|
topTenForResponseTime.forEach((item, i) => {
|
|
53
58
|
topTenForResponseTime[i].id = finalCounts[index].id;
|
|
@@ -63,58 +68,50 @@ export default {
|
|
|
63
68
|
},
|
|
64
69
|
|
|
65
70
|
data() {
|
|
71
|
+
const {
|
|
72
|
+
userAgent,
|
|
73
|
+
userAgentData,
|
|
74
|
+
language,
|
|
75
|
+
cookieEnabled,
|
|
76
|
+
hardwareConcurrency,
|
|
77
|
+
deviceMemory
|
|
78
|
+
} = window?.navigator;
|
|
79
|
+
|
|
66
80
|
const systemInformation = {
|
|
67
|
-
|
|
68
|
-
label: this.t('about.diagnostic.systemInformation.
|
|
69
|
-
value:
|
|
81
|
+
browser: {
|
|
82
|
+
label: this.t('about.diagnostic.systemInformation.browser'),
|
|
83
|
+
value: this.t('about.diagnostic.systemInformation.browserInfo', {
|
|
84
|
+
userAgent, language, cookieEnabled
|
|
85
|
+
})
|
|
70
86
|
},
|
|
71
|
-
|
|
72
|
-
label: this.t('about.diagnostic.systemInformation.
|
|
73
|
-
value:
|
|
74
|
-
},
|
|
75
|
-
cookieEnabled: {
|
|
76
|
-
label: this.t('about.diagnostic.systemInformation.cookieEnabled'),
|
|
77
|
-
value: window?.navigator?.cookieEnabled
|
|
78
|
-
},
|
|
79
|
-
hardwareConcurrency: {
|
|
80
|
-
label: this.t('about.diagnostic.systemInformation.hardwareConcurrency'),
|
|
81
|
-
value: window?.navigator?.hardwareConcurrency
|
|
87
|
+
system: {
|
|
88
|
+
label: this.t('about.diagnostic.systemInformation.system'),
|
|
89
|
+
value: this.t('about.diagnostic.systemInformation.hardwareConcurrency', { hardwareConcurrency })
|
|
82
90
|
},
|
|
91
|
+
jsMemory: {
|
|
92
|
+
label: this.t('about.diagnostic.systemInformation.jsMemory'),
|
|
93
|
+
value: ''
|
|
94
|
+
}
|
|
83
95
|
};
|
|
84
96
|
|
|
85
|
-
if (
|
|
86
|
-
systemInformation.
|
|
87
|
-
label: this.t('about.diagnostic.systemInformation.os'),
|
|
88
|
-
value: window?.navigator?.userAgentData?.platform
|
|
89
|
-
};
|
|
97
|
+
if ( userAgentData?.platform ) {
|
|
98
|
+
systemInformation.system.value = systemInformation.system.value.concat(', ', this.t('about.diagnostic.systemInformation.os', { platform: userAgentData.platform }));
|
|
90
99
|
}
|
|
91
100
|
|
|
92
|
-
if (
|
|
93
|
-
systemInformation.
|
|
94
|
-
label: this.t('about.diagnostic.systemInformation.deviceMemory'),
|
|
95
|
-
value: window?.navigator?.deviceMemory
|
|
96
|
-
};
|
|
101
|
+
if ( deviceMemory ) {
|
|
102
|
+
systemInformation.system.value = systemInformation.system.value.concat(', ', this.t('about.diagnostic.systemInformation.deviceMemory', { deviceMemory }));
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
if (window?.performance?.memory?.jsHeapSizeLimit) {
|
|
100
|
-
systemInformation.memJsHeapLimit
|
|
101
|
-
label: this.t('about.diagnostic.systemInformation.memJsHeapLimit'),
|
|
102
|
-
value: window?.performance?.memory?.jsHeapSizeLimit
|
|
103
|
-
};
|
|
105
|
+
if ( window?.performance?.memory?.jsHeapSizeLimit ) {
|
|
106
|
+
systemInformation.jsMemory.value += this.t('about.diagnostic.systemInformation.memJsHeapLimit', { jsHeapSizeLimit: window?.performance?.memory?.jsHeapSizeLimit });
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
if (window?.performance?.memory?.totalJSHeapSize) {
|
|
107
|
-
systemInformation.memTotalJsHeapSize
|
|
108
|
-
label: this.t('about.diagnostic.systemInformation.memTotalJsHeapSize'),
|
|
109
|
-
value: window?.performance?.memory?.totalJSHeapSize
|
|
110
|
-
};
|
|
109
|
+
if ( window?.performance?.memory?.totalJSHeapSize ) {
|
|
110
|
+
systemInformation.jsMemory.value += `, ${ this.t('about.diagnostic.systemInformation.memTotalJsHeapSize', { totalJSHeapSize: window?.performance?.memory?.totalJSHeapSize }) }`;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
if (window?.performance?.memory?.usedJSHeapSize) {
|
|
114
|
-
systemInformation.memUsedJsHeapSize
|
|
115
|
-
label: this.t('about.diagnostic.systemInformation.memUsedJsHeapSize'),
|
|
116
|
-
value: window?.performance?.memory?.usedJSHeapSize
|
|
117
|
-
};
|
|
113
|
+
if ( window?.performance?.memory?.usedJSHeapSize ) {
|
|
114
|
+
systemInformation.jsMemory.value += `, ${ this.t('about.diagnostic.systemInformation.memUsedJsHeapSize', { usedJSHeapSize: window?.performance?.memory?.usedJSHeapSize }) }`;
|
|
118
115
|
}
|
|
119
116
|
|
|
120
117
|
// scroll logs container to the bottom
|
|
@@ -123,22 +120,26 @@ export default {
|
|
|
123
120
|
return {
|
|
124
121
|
systemInformation,
|
|
125
122
|
topTenForResponseTime: null,
|
|
123
|
+
responseTimes: null,
|
|
126
124
|
finalCounts: null,
|
|
127
125
|
includeResponseTimes: true,
|
|
128
126
|
storeMapping: this.$store?._modules?.root?.state,
|
|
129
127
|
latestLogs: console.logs // eslint-disable-line no-console
|
|
130
128
|
};
|
|
131
129
|
},
|
|
130
|
+
|
|
132
131
|
watch: {
|
|
133
132
|
latestLogs() {
|
|
134
133
|
this.scrollLogsToBottom();
|
|
135
134
|
}
|
|
136
135
|
},
|
|
136
|
+
|
|
137
137
|
computed: {
|
|
138
|
-
|
|
139
|
-
return this.
|
|
138
|
+
clusterCount() {
|
|
139
|
+
return this.finalCounts?.length;
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
|
+
|
|
142
143
|
methods: {
|
|
143
144
|
scrollLogsToBottom() {
|
|
144
145
|
this.$nextTick(() => {
|
|
@@ -147,12 +148,14 @@ export default {
|
|
|
147
148
|
logsContainer.scrollTop = logsContainer.scrollHeight;
|
|
148
149
|
});
|
|
149
150
|
},
|
|
151
|
+
|
|
150
152
|
generateKey(data) {
|
|
151
153
|
const randomize = Math.random() * 10000;
|
|
152
154
|
|
|
153
155
|
return `key_${ randomize }_${ data }`;
|
|
154
156
|
},
|
|
155
|
-
|
|
157
|
+
|
|
158
|
+
downloadData(btnCb) {
|
|
156
159
|
const date = new Date().toLocaleDateString();
|
|
157
160
|
const time = new Date().toLocaleTimeString();
|
|
158
161
|
const fileName = `rancher-diagnostic-data-${ date }-${ time.replaceAll(':', '_') }.json`;
|
|
@@ -160,25 +163,45 @@ export default {
|
|
|
160
163
|
systemInformation: this.systemInformation,
|
|
161
164
|
logs: this.latestLogs,
|
|
162
165
|
storeMapping: this.parseStoreData(this.storeMapping),
|
|
163
|
-
resourceCounts: this.finalCounts
|
|
166
|
+
resourceCounts: this.finalCounts,
|
|
167
|
+
responseTimes: this.responseTimes
|
|
164
168
|
};
|
|
165
169
|
|
|
166
|
-
if (this.includeResponseTimes) {
|
|
167
|
-
const responseTimes = await this.gatherResponseTimes();
|
|
168
|
-
|
|
169
|
-
data.responseTimes = responseTimes;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
170
|
downloadFile(fileName, JSON.stringify(data), 'application/json')
|
|
173
171
|
.then(() => btnCb(true))
|
|
174
172
|
.catch(() => btnCb(false));
|
|
175
173
|
},
|
|
174
|
+
|
|
175
|
+
setResourceResponseTiming(responseTimes) {
|
|
176
|
+
responseTimes?.forEach((res) => {
|
|
177
|
+
if ( res.outcome === 'success' ) {
|
|
178
|
+
const cluster = this.finalCounts.find(c => c.capiId === res.item.capiId);
|
|
179
|
+
const countIndex = cluster?.counts?.findIndex(c => c.resource === res.item.resource);
|
|
180
|
+
|
|
181
|
+
if ( (countIndex && countIndex !== -1) || countIndex === 0 ) {
|
|
182
|
+
this.$set(cluster?.counts[countIndex], 'durationMs', res.durationMs);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
sumResourceCount(counts) {
|
|
189
|
+
return counts.reduce((a, b) => (a + b.count), 0);
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
nodeCount(counts) {
|
|
193
|
+
const resource = counts.findIndex(c => c.resource === 'node');
|
|
194
|
+
|
|
195
|
+
return counts[resource]?.count;
|
|
196
|
+
},
|
|
197
|
+
|
|
176
198
|
toggleTable(area) {
|
|
177
199
|
const itemIndex = this.finalCounts.findIndex(item => item.id === area);
|
|
178
200
|
|
|
179
201
|
this.finalCounts[itemIndex].isTableVisible = !this.finalCounts[itemIndex].isTableVisible;
|
|
180
202
|
},
|
|
181
|
-
|
|
203
|
+
|
|
204
|
+
async gatherResponseTimes(btnCb) {
|
|
182
205
|
return await Promise.all(this.topTenForResponseTime.map((item) => {
|
|
183
206
|
const t = Date.now();
|
|
184
207
|
|
|
@@ -190,11 +213,14 @@ export default {
|
|
|
190
213
|
outcome: 'error', item, durationMs: Date.now() - t
|
|
191
214
|
}));
|
|
192
215
|
})).then((responseTimes) => {
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
this.responseTimes = responseTimes;
|
|
217
|
+
this.setResourceResponseTiming(responseTimes);
|
|
218
|
+
btnCb(true);
|
|
219
|
+
}).catch(() => btnCb(false));
|
|
195
220
|
},
|
|
221
|
+
|
|
196
222
|
parseStoreData(rootStore) {
|
|
197
|
-
// clear
|
|
223
|
+
// clear potential sensitive data
|
|
198
224
|
const disallowedDataKeys = [
|
|
199
225
|
'aws',
|
|
200
226
|
'digitalocean',
|
|
@@ -252,6 +278,21 @@ export default {
|
|
|
252
278
|
});
|
|
253
279
|
|
|
254
280
|
return cleanRootStore;
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
promptDownload(btnCb) {
|
|
284
|
+
const resources = [{ downloadData: this.downloadData, gatherResponseTimes: this.gatherResponseTimes }];
|
|
285
|
+
|
|
286
|
+
if ( !this.responseTimes ) {
|
|
287
|
+
this.$store.dispatch('management/promptModal', {
|
|
288
|
+
component: 'DiagnosticTimingsDialog',
|
|
289
|
+
resources
|
|
290
|
+
})
|
|
291
|
+
.then(() => btnCb(true))
|
|
292
|
+
.catch(() => btnCb(false));
|
|
293
|
+
} else {
|
|
294
|
+
this.downloadData(btnCb);
|
|
295
|
+
}
|
|
255
296
|
}
|
|
256
297
|
},
|
|
257
298
|
};
|
|
@@ -260,27 +301,25 @@ export default {
|
|
|
260
301
|
<template>
|
|
261
302
|
<div>
|
|
262
303
|
<div class="title-block mt-20 mb-40">
|
|
263
|
-
<h1
|
|
264
|
-
v-t="'about.diagnostic.title'"
|
|
265
|
-
class="mt-20 mb-40"
|
|
266
|
-
/>
|
|
267
304
|
<div>
|
|
268
|
-
<
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
305
|
+
<AsyncButton
|
|
306
|
+
mode="timing"
|
|
307
|
+
class="mr-20"
|
|
308
|
+
@click="gatherResponseTimes"
|
|
272
309
|
/>
|
|
273
310
|
<AsyncButton
|
|
274
311
|
mode="diagnostic"
|
|
275
|
-
@click="
|
|
312
|
+
@click="promptDownload"
|
|
276
313
|
/>
|
|
277
314
|
</div>
|
|
278
315
|
</div>
|
|
316
|
+
|
|
317
|
+
<!-- System info -->
|
|
279
318
|
<div class="mb-40">
|
|
280
319
|
<h2 class="mb-20">
|
|
281
320
|
{{ t('about.diagnostic.systemInformation.subtitle') }}
|
|
282
321
|
</h2>
|
|
283
|
-
<table>
|
|
322
|
+
<table class="full-width">
|
|
284
323
|
<thead>
|
|
285
324
|
<tr>
|
|
286
325
|
<th>Type</th>
|
|
@@ -289,33 +328,19 @@ export default {
|
|
|
289
328
|
</thead>
|
|
290
329
|
<tbody>
|
|
291
330
|
<tr v-for="(item, objKey) in systemInformation" :key="objKey">
|
|
292
|
-
<
|
|
293
|
-
|
|
331
|
+
<template v-if="item.value.length">
|
|
332
|
+
<td>{{ item.label }}</td>
|
|
333
|
+
<td>{{ item.value }}</td>
|
|
334
|
+
</template>
|
|
294
335
|
</tr>
|
|
295
336
|
</tbody>
|
|
296
337
|
</table>
|
|
297
338
|
</div>
|
|
339
|
+
|
|
340
|
+
<!-- Resources -->
|
|
298
341
|
<div class="mb-40">
|
|
299
342
|
<h2 class="mb-20">
|
|
300
|
-
{{ t('about.diagnostic.
|
|
301
|
-
</h2>
|
|
302
|
-
<ul class="logs-container">
|
|
303
|
-
<li
|
|
304
|
-
v-for="logEntry in latestLogs"
|
|
305
|
-
:key="generateKey(logEntry.timestamp)"
|
|
306
|
-
:class="logEntry.type"
|
|
307
|
-
>
|
|
308
|
-
<span class="log-entry-type">{{ logEntry.type }} :: </span>
|
|
309
|
-
<span
|
|
310
|
-
v-for="(arg, i) in logEntry.data"
|
|
311
|
-
:key="i"
|
|
312
|
-
>{{ arg }}</span>
|
|
313
|
-
</li>
|
|
314
|
-
</ul>
|
|
315
|
-
</div>
|
|
316
|
-
<div class="mb-40">
|
|
317
|
-
<h2 class="mb-20">
|
|
318
|
-
{{ t('about.diagnostic.resourceCounts.subtitle') }}
|
|
343
|
+
{{ t('about.diagnostic.resourceCounts', { count: clusterCount }) }}
|
|
319
344
|
</h2>
|
|
320
345
|
<div class="resources-count-container">
|
|
321
346
|
<table
|
|
@@ -324,9 +349,12 @@ export default {
|
|
|
324
349
|
class="full-width"
|
|
325
350
|
>
|
|
326
351
|
<thead @click="toggleTable(cluster.id)">
|
|
327
|
-
<th colspan="
|
|
328
|
-
<div>
|
|
329
|
-
<span>{{ cluster.
|
|
352
|
+
<th colspan="4">
|
|
353
|
+
<div class="cluster-row">
|
|
354
|
+
<span>Cluster: <b>{{ cluster.name }}</b></span>
|
|
355
|
+
<span>Namespace: <b>{{ cluster.namespace }}</b></span>
|
|
356
|
+
<span>Total Resources: <b>{{ sumResourceCount(cluster.counts) }}</b></span>
|
|
357
|
+
<span>Nodes: <b>{{ nodeCount(cluster.counts) }}</b></span>
|
|
330
358
|
<i
|
|
331
359
|
class="icon"
|
|
332
360
|
:class="{
|
|
@@ -338,21 +366,60 @@ export default {
|
|
|
338
366
|
</th>
|
|
339
367
|
</thead>
|
|
340
368
|
<tbody v-show="cluster.isTableVisible">
|
|
369
|
+
<tr>
|
|
370
|
+
<th>
|
|
371
|
+
Resource
|
|
372
|
+
</th>
|
|
373
|
+
<th>
|
|
374
|
+
Count
|
|
375
|
+
</th>
|
|
376
|
+
<th>
|
|
377
|
+
Resource Timing (ms)
|
|
378
|
+
</th>
|
|
379
|
+
</tr>
|
|
380
|
+
|
|
341
381
|
<tr v-for="item in cluster.counts" :key="item.resource">
|
|
342
|
-
<
|
|
343
|
-
|
|
382
|
+
<template v-if="item.count > 0">
|
|
383
|
+
<td scope="row">
|
|
384
|
+
{{ item.resource }}
|
|
385
|
+
</td>
|
|
386
|
+
<td>{{ item.count }}</td>
|
|
387
|
+
<td>{{ item.durationMs || '-' }}</td>
|
|
388
|
+
</template>
|
|
344
389
|
</tr>
|
|
345
390
|
</tbody>
|
|
346
391
|
</table>
|
|
347
392
|
</div>
|
|
348
393
|
</div>
|
|
394
|
+
|
|
395
|
+
<!-- Logs -->
|
|
396
|
+
<div class="mb-40">
|
|
397
|
+
<h2 class="mb-20">
|
|
398
|
+
{{ t('about.diagnostic.logs.subtitle') }}
|
|
399
|
+
</h2>
|
|
400
|
+
<ul class="logs-container">
|
|
401
|
+
<li
|
|
402
|
+
v-for="logEntry in latestLogs"
|
|
403
|
+
:key="generateKey(logEntry.timestamp)"
|
|
404
|
+
:class="logEntry.type"
|
|
405
|
+
>
|
|
406
|
+
<span class="log-entry-type">{{ logEntry.type }} :: </span>
|
|
407
|
+
<span
|
|
408
|
+
v-for="(arg, i) in logEntry.data"
|
|
409
|
+
:key="i"
|
|
410
|
+
>{{ arg }}</span>
|
|
411
|
+
</li>
|
|
412
|
+
</ul>
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
<PromptModal />
|
|
349
416
|
</div>
|
|
350
417
|
</template>
|
|
351
418
|
|
|
352
419
|
<style lang="scss" scoped>
|
|
353
420
|
.title-block {
|
|
354
421
|
display: flex;
|
|
355
|
-
justify-content:
|
|
422
|
+
justify-content: right;
|
|
356
423
|
align-items: center;
|
|
357
424
|
|
|
358
425
|
h1 {
|
|
@@ -383,6 +450,10 @@ table {
|
|
|
383
450
|
justify-content: space-between;
|
|
384
451
|
}
|
|
385
452
|
}
|
|
453
|
+
|
|
454
|
+
tbody {
|
|
455
|
+
border-bottom: 1px solid var(--sortable-table-top-divider);
|
|
456
|
+
}
|
|
386
457
|
}
|
|
387
458
|
|
|
388
459
|
tr > td:first-of-type {
|
|
@@ -398,7 +469,7 @@ table {
|
|
|
398
469
|
|
|
399
470
|
th {
|
|
400
471
|
background-color: var(--sortable-table-top-divider);
|
|
401
|
-
border-bottom: 1px solid var(--sortable-table-
|
|
472
|
+
border-bottom: 1px solid var(--sortable-table-header-bg);
|
|
402
473
|
}
|
|
403
474
|
|
|
404
475
|
a {
|
|
@@ -458,11 +529,24 @@ table {
|
|
|
458
529
|
}
|
|
459
530
|
|
|
460
531
|
.resources-count-container {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
532
|
+
.cluster-row {
|
|
533
|
+
display: grid;
|
|
534
|
+
grid-template-columns: repeat(4, 1fr) 20px;
|
|
535
|
+
grid-template-rows: 1fr;
|
|
536
|
+
align-content: center;
|
|
537
|
+
font-weight: normal;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
tbody tr, tbody tr th {
|
|
541
|
+
background-color: var(--sortable-table-header-bg);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
tbody tr th {
|
|
545
|
+
border-bottom: 1px solid var(--sortable-table-top-divider);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
tbody tr:hover {
|
|
549
|
+
background-color: var(--sortable-table-top-divider);
|
|
466
550
|
}
|
|
467
551
|
}
|
|
468
552
|
</style>
|
package/pages/docs/_doc.vue
CHANGED
|
@@ -301,10 +301,12 @@ export default {
|
|
|
301
301
|
|
|
302
302
|
thead > tr > th {
|
|
303
303
|
background-color: var(--sortable-table-header-bg);
|
|
304
|
+
line-height: 1.75em;
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
tbody > tr.table-group > td {
|
|
307
|
-
background-color: var(--sortable-table-
|
|
308
|
+
background-color: var(--sortable-table-header-bg);
|
|
309
|
+
font-weight: bold;
|
|
308
310
|
}
|
|
309
311
|
|
|
310
312
|
thead, tbody {
|
package/pages/home.vue
CHANGED
|
@@ -6,7 +6,6 @@ import IndentedPanel from '@shell/components/IndentedPanel';
|
|
|
6
6
|
import SortableTable from '@shell/components/SortableTable';
|
|
7
7
|
import { BadgeState } from '@components/BadgeState';
|
|
8
8
|
import CommunityLinks from '@shell/components/CommunityLinks';
|
|
9
|
-
import SimpleBox from '@shell/components/SimpleBox';
|
|
10
9
|
import SingleClusterInfo from '@shell/components/SingleClusterInfo';
|
|
11
10
|
import { mapGetters, mapState } from 'vuex';
|
|
12
11
|
import { MANAGEMENT, CAPI } from '@shell/config/types';
|
|
@@ -18,7 +17,6 @@ import { getVersionInfo, readReleaseNotes, markReadReleaseNotes, markSeenRelease
|
|
|
18
17
|
import PageHeaderActions from '@shell/mixins/page-actions';
|
|
19
18
|
import { getVendor } from '@shell/config/private-label';
|
|
20
19
|
import { mapFeature, MULTI_CLUSTER } from '@shell/store/features';
|
|
21
|
-
import { SETTING } from '@shell/config/settings';
|
|
22
20
|
import { BLANK_CLUSTER } from '@shell/store';
|
|
23
21
|
import { filterOnlyKubernetesClusters, filterHiddenLocalCluster } from '@shell/utils/cluster';
|
|
24
22
|
|
|
@@ -34,7 +32,6 @@ export default {
|
|
|
34
32
|
SortableTable,
|
|
35
33
|
BadgeState,
|
|
36
34
|
CommunityLinks,
|
|
37
|
-
SimpleBox,
|
|
38
35
|
SingleClusterInfo,
|
|
39
36
|
},
|
|
40
37
|
|
|
@@ -114,10 +111,6 @@ export default {
|
|
|
114
111
|
return this.homePageCards?.setLoginPage;
|
|
115
112
|
},
|
|
116
113
|
|
|
117
|
-
showSidePanel() {
|
|
118
|
-
return this.showCommercialSupport || this.showCommunityLinks;
|
|
119
|
-
},
|
|
120
|
-
|
|
121
114
|
clusterHeaders() {
|
|
122
115
|
return [
|
|
123
116
|
STATE,
|
|
@@ -170,24 +163,6 @@ export default {
|
|
|
170
163
|
];
|
|
171
164
|
},
|
|
172
165
|
|
|
173
|
-
showCommercialSupport() {
|
|
174
|
-
const canEditSettings = (this.$store.getters['management/schemaFor'](MANAGEMENT.SETTING)?.resourceMethods || []).includes('PUT');
|
|
175
|
-
|
|
176
|
-
const hasSupport = this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.SUPPORTED) || {};
|
|
177
|
-
|
|
178
|
-
return !this.homePageCards.commercialSupportTip && hasSupport.value !== 'true' && canEditSettings;
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
showCommunityLinks() {
|
|
182
|
-
const uiIssuesSetting = this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.UI_ISSUES) || {};
|
|
183
|
-
const communityLinksSetting = this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.COMMUNITY_LINKS) || {};
|
|
184
|
-
|
|
185
|
-
const hasSomethingToShow = communityLinksSetting?.value !== 'false' || !!( uiIssuesSetting.value && uiIssuesSetting.value !== '');
|
|
186
|
-
const hiddenByPreference = this.homePageCards.communitySupportTip === true;
|
|
187
|
-
|
|
188
|
-
return hasSomethingToShow && !hiddenByPreference;
|
|
189
|
-
},
|
|
190
|
-
|
|
191
166
|
...mapGetters(['currentCluster', 'defaultClusterId']),
|
|
192
167
|
|
|
193
168
|
kubeClusters() {
|
|
@@ -289,26 +264,9 @@ export default {
|
|
|
289
264
|
</div>
|
|
290
265
|
</div>
|
|
291
266
|
|
|
292
|
-
<div class="row">
|
|
293
|
-
<div
|
|
294
|
-
<
|
|
295
|
-
id="migration"
|
|
296
|
-
class="panel"
|
|
297
|
-
:title="t('landing.gettingStarted.title')"
|
|
298
|
-
:pref="HIDE_HOME_PAGE_CARDS"
|
|
299
|
-
pref-key="migrationTip"
|
|
300
|
-
>
|
|
301
|
-
<div class="getting-started">
|
|
302
|
-
<span>
|
|
303
|
-
{{ t('landing.gettingStarted.body') }}
|
|
304
|
-
</span>
|
|
305
|
-
<nuxt-link :to="{name: 'docs-doc', params: {doc: 'getting-started'}}" class="getting-started-btn">
|
|
306
|
-
{{ t('landing.learnMore') }}
|
|
307
|
-
</nuxt-link>
|
|
308
|
-
</div>
|
|
309
|
-
</SimpleBox>
|
|
310
|
-
|
|
311
|
-
<div v-if="!showSetLoginBanner" class="mt-5 mb-10 row">
|
|
267
|
+
<div class="row home-panels">
|
|
268
|
+
<div class="col main-panel">
|
|
269
|
+
<div v-if="!showSetLoginBanner" class="mb-10 row">
|
|
312
270
|
<div class="col span-12">
|
|
313
271
|
<Banner color="set-login-page" :closable="true" @close="closeSetLoginBanner()">
|
|
314
272
|
<div>{{ t('landing.landingPrefs.title') }}</div>
|
|
@@ -316,7 +274,6 @@ export default {
|
|
|
316
274
|
</Banner>
|
|
317
275
|
</div>
|
|
318
276
|
</div>
|
|
319
|
-
|
|
320
277
|
<div class="row panel">
|
|
321
278
|
<div v-if="mcm" class="col span-12">
|
|
322
279
|
<SortableTable
|
|
@@ -354,7 +311,7 @@ export default {
|
|
|
354
311
|
<template #col:name="{row}">
|
|
355
312
|
<td>
|
|
356
313
|
<span v-if="row.mgmt">
|
|
357
|
-
<n-link v-if="row.mgmt.isReady" :to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}">
|
|
314
|
+
<n-link v-if="row.mgmt.isReady && !row.hasError" :to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}">
|
|
358
315
|
{{ row.nameDisplay }}
|
|
359
316
|
</n-link>
|
|
360
317
|
<span v-else>{{ row.nameDisplay }}</span>
|
|
@@ -392,22 +349,30 @@ export default {
|
|
|
392
349
|
</div>
|
|
393
350
|
</div>
|
|
394
351
|
</div>
|
|
395
|
-
<
|
|
396
|
-
<CommunityLinks v-if="showCommunityLinks" :pref="HIDE_HOME_PAGE_CARDS" pref-key="communitySupportTip" class="mb-20" />
|
|
397
|
-
<SimpleBox v-if="showCommercialSupport" :pref="HIDE_HOME_PAGE_CARDS" pref-key="commercialSupportTip" :title="t('landing.commercial.title')">
|
|
398
|
-
<nuxt-link :to="{ path: 'support'}">
|
|
399
|
-
{{ t('landing.commercial.body') }}
|
|
400
|
-
</nuxt-link>
|
|
401
|
-
</SimpleBox>
|
|
402
|
-
</div>
|
|
352
|
+
<CommunityLinks class="col span-3 side-panel" />
|
|
403
353
|
</div>
|
|
404
354
|
</IndentedPanel>
|
|
405
355
|
</div>
|
|
406
356
|
</template>
|
|
407
357
|
<style lang='scss' scoped>
|
|
358
|
+
.home-panels {
|
|
359
|
+
display: flex;
|
|
360
|
+
align-items: stretch;
|
|
361
|
+
.col {
|
|
362
|
+
margin: 0
|
|
363
|
+
}
|
|
364
|
+
.main-panel {
|
|
365
|
+
flex: auto;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.side-panel {
|
|
369
|
+
margin-left: 1.75%;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
408
373
|
.banner.info.whats-new, .banner.set-login-page {
|
|
409
374
|
border: 0;
|
|
410
|
-
margin-top:
|
|
375
|
+
margin-top: 0;
|
|
411
376
|
display: flex;
|
|
412
377
|
align-items: center;
|
|
413
378
|
flex-direction: row;
|