@rancher/shell 3.0.1-rc.4 → 3.0.1
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/data/aws-regions.json +1 -0
- package/assets/styles/base/_basic.scss +5 -0
- package/assets/styles/base/_mixins.scss +8 -0
- package/assets/styles/global/_button.scss +5 -0
- package/assets/styles/themes/_dark.scss +2 -0
- package/assets/styles/themes/_light.scss +2 -0
- package/assets/translations/en-us.yaml +27 -11
- package/assets/translations/zh-hans.yaml +1 -1
- package/chart/monitoring/StorageClassSelector.vue +1 -1
- package/components/AssignTo.vue +1 -0
- package/components/AsyncButton.vue +1 -0
- package/components/BackLink.vue +8 -2
- package/components/PaginatedResourceTable.vue +135 -0
- package/components/ResourceList/index.vue +0 -1
- package/components/ResourceTable.vue +6 -1
- package/components/SortableTable/index.vue +8 -6
- package/components/Tabbed/index.vue +35 -2
- package/components/form/ResourceLabeledSelect.vue +2 -2
- package/components/form/ResourceTabs/index.vue +0 -23
- package/components/form/Taints.vue +1 -1
- package/components/nav/TopLevelMenu.helper.ts +546 -0
- package/components/nav/TopLevelMenu.vue +124 -159
- package/components/nav/__tests__/TopLevelMenu.test.ts +338 -326
- package/config/pagination-table-headers.js +4 -4
- package/config/product/explorer.js +2 -0
- package/config/router/routes.js +1 -1
- package/config/settings.ts +13 -1
- package/core/plugin.ts +8 -1
- package/core/types-provisioning.ts +5 -0
- package/core/types.ts +26 -1
- package/dialog/DrainNode.vue +6 -6
- package/edit/catalog.cattle.io.clusterrepo.vue +95 -52
- package/edit/provisioning.cattle.io.cluster/index.vue +8 -3
- package/list/node.vue +8 -5
- package/mixins/resource-fetch-api-pagination.js +40 -5
- package/mixins/resource-fetch.js +48 -5
- package/models/management.cattle.io.nodepool.js +5 -4
- package/models/provisioning.cattle.io.cluster.js +2 -10
- package/package.json +6 -6
- package/pages/about.vue +22 -0
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +36 -24
- package/pages/c/_cluster/explorer/index.vue +100 -59
- package/pages/home.vue +308 -123
- package/plugins/dashboard-store/__tests__/mutations.test.ts +2 -0
- package/plugins/dashboard-store/actions.js +29 -19
- package/plugins/dashboard-store/getters.js +5 -2
- package/plugins/dashboard-store/mutations.js +4 -2
- package/plugins/steve/__tests__/mutations.test.ts +2 -1
- package/plugins/steve/steve-pagination-utils.ts +25 -2
- package/plugins/steve/subscribe.js +22 -8
- package/scripts/extension/parse-tag-name +2 -0
- package/scripts/test-plugins-build.sh +1 -0
- package/store/index.js +31 -9
- package/tsconfig.json +7 -1
- package/types/resources/settings.d.ts +1 -1
- package/types/shell/index.d.ts +1107 -1276
- package/types/store/dashboard-store.types.ts +4 -0
- package/types/store/pagination.types.ts +13 -0
- package/types/store/vuex.d.ts +8 -0
- package/types/vue-shim.d.ts +6 -31
- package/utils/cluster.js +92 -1
- package/utils/pagination-utils.ts +17 -8
- package/utils/pagination-wrapper.ts +70 -0
- package/utils/uiplugins.ts +18 -4
package/pages/home.vue
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { defineComponent } from 'vue';
|
|
2
3
|
import { mapPref, AFTER_LOGIN_ROUTE, READ_WHATS_NEW, HIDE_HOME_PAGE_CARDS } from '@shell/store/prefs';
|
|
3
4
|
import { Banner } from '@components/Banner';
|
|
4
|
-
import BannerGraphic from '@shell/components/BannerGraphic';
|
|
5
|
-
import IndentedPanel from '@shell/components/IndentedPanel';
|
|
6
|
-
import
|
|
5
|
+
import BannerGraphic from '@shell/components/BannerGraphic.vue';
|
|
6
|
+
import IndentedPanel from '@shell/components/IndentedPanel.vue';
|
|
7
|
+
import PaginatedResourceTable, { FetchPageSecondaryResourcesOpts, FetchSecondaryResourcesOpts } from '@shell/components/PaginatedResourceTable.vue';
|
|
7
8
|
import { BadgeState } from '@components/BadgeState';
|
|
8
|
-
import CommunityLinks from '@shell/components/CommunityLinks';
|
|
9
|
-
import SingleClusterInfo from '@shell/components/SingleClusterInfo';
|
|
9
|
+
import CommunityLinks from '@shell/components/CommunityLinks.vue';
|
|
10
|
+
import SingleClusterInfo from '@shell/components/SingleClusterInfo.vue';
|
|
10
11
|
import { mapGetters, mapState } from 'vuex';
|
|
11
12
|
import { MANAGEMENT, CAPI } from '@shell/config/types';
|
|
12
13
|
import { NAME as MANAGER } from '@shell/config/product/manager';
|
|
@@ -18,19 +19,24 @@ import PageHeaderActions from '@shell/mixins/page-actions';
|
|
|
18
19
|
import { getVendor } from '@shell/config/private-label';
|
|
19
20
|
import { mapFeature, MULTI_CLUSTER } from '@shell/store/features';
|
|
20
21
|
import { BLANK_CLUSTER } from '@shell/store/store-types.js';
|
|
21
|
-
import { filterOnlyKubernetesClusters,
|
|
22
|
-
import TabTitle from '@shell/components/TabTitle';
|
|
22
|
+
import { filterHiddenLocalCluster, filterOnlyKubernetesClusters, paginationFilterClusters } from '@shell/utils/cluster';
|
|
23
|
+
import TabTitle from '@shell/components/TabTitle.vue';
|
|
24
|
+
import { ActionFindPageArgs } from '@shell/types/store/dashboard-store.types';
|
|
23
25
|
|
|
24
26
|
import { RESET_CARDS_ACTION, SET_LOGIN_ACTION } from '@shell/config/page-actions';
|
|
27
|
+
import { STEVE_NAME_COL, STEVE_STATE_COL } from '@shell/config/pagination-table-headers';
|
|
28
|
+
import { PaginationParamFilter, FilterArgs, PaginationFilterField, PaginationArgs } from '@shell/types/store/pagination.types';
|
|
29
|
+
import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
|
|
30
|
+
import { sameContents } from 'utils/array';
|
|
25
31
|
|
|
26
|
-
export default {
|
|
32
|
+
export default defineComponent({
|
|
27
33
|
name: 'Home',
|
|
28
34
|
layout: 'home',
|
|
29
35
|
components: {
|
|
30
36
|
Banner,
|
|
31
37
|
BannerGraphic,
|
|
32
38
|
IndentedPanel,
|
|
33
|
-
|
|
39
|
+
PaginatedResourceTable,
|
|
34
40
|
BadgeState,
|
|
35
41
|
CommunityLinks,
|
|
36
42
|
SingleClusterInfo,
|
|
@@ -39,102 +45,51 @@ export default {
|
|
|
39
45
|
|
|
40
46
|
mixins: [PageHeaderActions],
|
|
41
47
|
|
|
42
|
-
fetch() {
|
|
43
|
-
if ( this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER) ) {
|
|
44
|
-
this.$store.dispatch('management/findAll', { type: CAPI.RANCHER_CLUSTER });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if ( this.$store.getters['management/schemaFor'](MANAGEMENT.CLUSTER) ) {
|
|
48
|
-
this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if ( this.$store.getters['management/canList'](CAPI.MACHINE) ) {
|
|
52
|
-
this.$store.dispatch('management/findAll', { type: CAPI.MACHINE });
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if ( this.$store.getters['management/canList'](MANAGEMENT.NODE) ) {
|
|
56
|
-
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE });
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// We need to fetch node pools and node templates in order to correctly show the provider for RKE1 clusters
|
|
60
|
-
if ( this.$store.getters['management/canList'](MANAGEMENT.NODE_POOL) ) {
|
|
61
|
-
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE_POOL });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if ( this.$store.getters['management/canList'](MANAGEMENT.NODE_TEMPLATE) ) {
|
|
65
|
-
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE_TEMPLATE });
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
|
|
69
48
|
data() {
|
|
70
|
-
const fullVersion = getVersionInfo(this.$store).fullVersion;
|
|
71
|
-
// Page actions don't change on the Home Page
|
|
72
|
-
const pageActions = [
|
|
73
|
-
{
|
|
74
|
-
labelKey: 'nav.header.setLoginPage',
|
|
75
|
-
action: SET_LOGIN_ACTION
|
|
76
|
-
},
|
|
77
|
-
{ separator: true },
|
|
78
|
-
{
|
|
79
|
-
labelKey: 'nav.header.restoreCards',
|
|
80
|
-
action: RESET_CARDS_ACTION
|
|
81
|
-
},
|
|
82
|
-
];
|
|
83
|
-
|
|
84
49
|
return {
|
|
85
50
|
HIDE_HOME_PAGE_CARDS,
|
|
86
|
-
fullVersion,
|
|
87
|
-
|
|
51
|
+
fullVersion: getVersionInfo(this.$store).fullVersion,
|
|
52
|
+
// Page actions don't change on the Home Page
|
|
53
|
+
pageActions: [
|
|
54
|
+
{
|
|
55
|
+
labelKey: 'nav.header.setLoginPage',
|
|
56
|
+
action: SET_LOGIN_ACTION
|
|
57
|
+
},
|
|
58
|
+
{ separator: true },
|
|
59
|
+
{
|
|
60
|
+
labelKey: 'nav.header.restoreCards',
|
|
61
|
+
action: RESET_CARDS_ACTION
|
|
62
|
+
},
|
|
63
|
+
],
|
|
88
64
|
vendor: getVendor(),
|
|
89
|
-
};
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
computed: {
|
|
93
|
-
...mapState(['managementReady']),
|
|
94
|
-
...mapGetters(['currentCluster', 'defaultClusterId', 'releaseNotesUrl']),
|
|
95
|
-
mcm: mapFeature(MULTI_CLUSTER),
|
|
96
|
-
|
|
97
|
-
provClusters() {
|
|
98
|
-
return this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
|
|
99
|
-
},
|
|
100
65
|
|
|
101
|
-
|
|
102
|
-
canManageClusters() {
|
|
103
|
-
const schema = this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER);
|
|
66
|
+
provClusterSchema: this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER),
|
|
104
67
|
|
|
105
|
-
|
|
106
|
-
|
|
68
|
+
canViewMgmtClusters: !!this.$store.getters['management/schemaFor'](MANAGEMENT.CLUSTER),
|
|
69
|
+
canViewMachine: !!this.$store.getters['management/canList'](CAPI.MACHINE),
|
|
70
|
+
canViewMgmtNodes: !!this.$store.getters['management/canList'](MANAGEMENT.NODE),
|
|
71
|
+
canViewMgmtPools: !!this.$store.getters['management/canList'](MANAGEMENT.NODE_POOL),
|
|
72
|
+
canViewMgmtTemplates: !!this.$store.getters['management/canList'](MANAGEMENT.NODE_TEMPLATE),
|
|
107
73
|
|
|
108
|
-
|
|
109
|
-
const schema = this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER);
|
|
110
|
-
|
|
111
|
-
return !!schema?.collectionMethods.find((x) => x.toLowerCase() === 'post');
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
manageLocation() {
|
|
115
|
-
return {
|
|
74
|
+
manageLocation: {
|
|
116
75
|
name: 'c-cluster-product-resource',
|
|
117
76
|
params: {
|
|
118
77
|
product: MANAGER,
|
|
119
78
|
cluster: BLANK_CLUSTER,
|
|
120
79
|
resource: CAPI.RANCHER_CLUSTER
|
|
121
80
|
},
|
|
122
|
-
}
|
|
123
|
-
},
|
|
81
|
+
},
|
|
124
82
|
|
|
125
|
-
|
|
126
|
-
return {
|
|
83
|
+
createLocation: {
|
|
127
84
|
name: 'c-cluster-product-resource-create',
|
|
128
85
|
params: {
|
|
129
86
|
product: MANAGER,
|
|
130
87
|
cluster: BLANK_CLUSTER,
|
|
131
88
|
resource: CAPI.RANCHER_CLUSTER
|
|
132
89
|
},
|
|
133
|
-
}
|
|
134
|
-
},
|
|
90
|
+
},
|
|
135
91
|
|
|
136
|
-
|
|
137
|
-
return {
|
|
92
|
+
importLocation: {
|
|
138
93
|
name: 'c-cluster-product-resource-create',
|
|
139
94
|
params: {
|
|
140
95
|
product: MANAGER,
|
|
@@ -142,22 +97,9 @@ export default {
|
|
|
142
97
|
resource: CAPI.RANCHER_CLUSTER
|
|
143
98
|
},
|
|
144
99
|
query: { [MODE]: _IMPORT }
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
|
|
149
|
-
homePageCards: mapPref(HIDE_HOME_PAGE_CARDS),
|
|
150
|
-
|
|
151
|
-
readWhatsNewAlready() {
|
|
152
|
-
return readReleaseNotes(this.$store);
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
showSetLoginBanner() {
|
|
156
|
-
return this.homePageCards?.setLoginPage;
|
|
157
|
-
},
|
|
100
|
+
},
|
|
158
101
|
|
|
159
|
-
|
|
160
|
-
return [
|
|
102
|
+
headers: [
|
|
161
103
|
STATE,
|
|
162
104
|
{
|
|
163
105
|
name: 'name',
|
|
@@ -165,7 +107,7 @@ export default {
|
|
|
165
107
|
value: 'nameDisplay',
|
|
166
108
|
sort: ['nameSort'],
|
|
167
109
|
canBeVariable: true,
|
|
168
|
-
getValue: (row) => row.mgmt?.nameDisplay
|
|
110
|
+
getValue: (row: ProvCluster) => row.mgmt?.nameDisplay
|
|
169
111
|
},
|
|
170
112
|
{
|
|
171
113
|
label: this.t('landing.clusters.provider'),
|
|
@@ -185,14 +127,12 @@ export default {
|
|
|
185
127
|
value: '',
|
|
186
128
|
name: 'cpu',
|
|
187
129
|
sort: ['status.allocatable.cpu', 'status.available.cpu']
|
|
188
|
-
|
|
189
130
|
},
|
|
190
131
|
{
|
|
191
132
|
label: this.t('tableHeaders.memory'),
|
|
192
133
|
value: '',
|
|
193
134
|
name: 'memory',
|
|
194
135
|
sort: ['status.allocatable.memory', 'status.available.memory']
|
|
195
|
-
|
|
196
136
|
},
|
|
197
137
|
{
|
|
198
138
|
label: this.t('tableHeaders.pods'),
|
|
@@ -206,12 +146,80 @@ export default {
|
|
|
206
146
|
// name: 'explorer',
|
|
207
147
|
// label: this.t('landing.clusters.explorer')
|
|
208
148
|
// }
|
|
209
|
-
]
|
|
149
|
+
],
|
|
150
|
+
|
|
151
|
+
paginationHeaders: [
|
|
152
|
+
STEVE_STATE_COL,
|
|
153
|
+
// https://github.com/rancher/dashboard/issues/12890 BUG - rke1 cluster's prov cluster metadata.name is the mgmt cluster id rather than true name
|
|
154
|
+
{
|
|
155
|
+
...STEVE_NAME_COL,
|
|
156
|
+
canBeVariable: true,
|
|
157
|
+
getValue: (row: ProvCluster) => row.metadata?.name
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: this.t('landing.clusters.provider'),
|
|
161
|
+
subLabel: this.t('landing.clusters.distro'),
|
|
162
|
+
value: 'mgmt.status.provider',
|
|
163
|
+
name: 'Provider',
|
|
164
|
+
sort: false,
|
|
165
|
+
search: false,
|
|
166
|
+
formatter: 'ClusterProvider'
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
label: this.t('landing.clusters.kubernetesVersion'),
|
|
170
|
+
subLabel: this.t('landing.clusters.architecture'),
|
|
171
|
+
name: 'kubernetesVersion',
|
|
172
|
+
sort: false,
|
|
173
|
+
search: false,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
label: this.t('tableHeaders.cpu'),
|
|
177
|
+
value: '',
|
|
178
|
+
name: 'cpu',
|
|
179
|
+
sort: false,
|
|
180
|
+
search: false,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
label: this.t('tableHeaders.memory'),
|
|
184
|
+
value: '',
|
|
185
|
+
name: 'memory',
|
|
186
|
+
sort: false,
|
|
187
|
+
search: false,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
label: this.t('tableHeaders.pods'),
|
|
191
|
+
name: 'pods',
|
|
192
|
+
value: '',
|
|
193
|
+
sort: false,
|
|
194
|
+
search: false,
|
|
195
|
+
formatter: 'PodsUsage',
|
|
196
|
+
delayLoading: true
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
|
|
200
|
+
clusterCount: 0,
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
computed: {
|
|
205
|
+
...mapState(['managementReady']),
|
|
206
|
+
...mapGetters(['currentCluster', 'defaultClusterId', 'releaseNotesUrl']),
|
|
207
|
+
mcm: mapFeature(MULTI_CLUSTER),
|
|
208
|
+
|
|
209
|
+
canCreateCluster() {
|
|
210
|
+
return !!this.provClusterSchema?.collectionMethods.find((x: string) => x.toLowerCase() === 'post');
|
|
210
211
|
},
|
|
211
212
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
|
|
214
|
+
homePageCards: mapPref(HIDE_HOME_PAGE_CARDS),
|
|
215
|
+
|
|
216
|
+
readWhatsNewAlready() {
|
|
217
|
+
return readReleaseNotes(this.$store);
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
showSetLoginBanner() {
|
|
221
|
+
return this.homePageCards?.setLoginPage;
|
|
222
|
+
},
|
|
215
223
|
},
|
|
216
224
|
|
|
217
225
|
async created() {
|
|
@@ -229,11 +237,131 @@ export default {
|
|
|
229
237
|
},
|
|
230
238
|
|
|
231
239
|
methods: {
|
|
240
|
+
/**
|
|
241
|
+
* Of type FetchSecondaryResources
|
|
242
|
+
*/
|
|
243
|
+
fetchSecondaryResources(opts: FetchSecondaryResourcesOpts): Promise<any> {
|
|
244
|
+
if (opts.canPaginate) {
|
|
245
|
+
return Promise.resolve({});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if ( this.canViewMgmtClusters ) {
|
|
249
|
+
this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if ( this.canViewMachine ) {
|
|
253
|
+
this.$store.dispatch('management/findAll', { type: CAPI.MACHINE });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if ( this.canViewMgmtNodes ) {
|
|
257
|
+
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// We need to fetch node pools and node templates in order to correctly show the provider for RKE1 clusters
|
|
261
|
+
if ( this.canViewMgmtPools ) {
|
|
262
|
+
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE_POOL });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if ( this.canViewMgmtTemplates ) {
|
|
266
|
+
this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE_TEMPLATE });
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return Promise.resolve({});
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
async fetchPageSecondaryResources({
|
|
273
|
+
canPaginate, force, page, pagResult
|
|
274
|
+
}: FetchPageSecondaryResourcesOpts) {
|
|
275
|
+
if (!canPaginate || !page?.length) {
|
|
276
|
+
this.clusterCount = 0;
|
|
277
|
+
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
this.clusterCount = pagResult.count;
|
|
282
|
+
|
|
283
|
+
if ( this.canViewMgmtClusters ) {
|
|
284
|
+
const opt: ActionFindPageArgs = {
|
|
285
|
+
force,
|
|
286
|
+
pagination: new FilterArgs({
|
|
287
|
+
filters: PaginationParamFilter.createMultipleFields(page.map((r: any) => new PaginationFilterField({
|
|
288
|
+
field: 'id',
|
|
289
|
+
value: r.mgmtClusterId
|
|
290
|
+
}))),
|
|
291
|
+
})
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
this.$store.dispatch(`management/findPage`, { type: MANAGEMENT.CLUSTER, opt });
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if ( this.canViewMachine ) {
|
|
298
|
+
const opt: ActionFindPageArgs = {
|
|
299
|
+
force,
|
|
300
|
+
pagination: new FilterArgs({
|
|
301
|
+
filters: PaginationParamFilter.createMultipleFields(page.map((r: any) => new PaginationFilterField({
|
|
302
|
+
field: 'spec.clusterName',
|
|
303
|
+
value: r.metadata.name
|
|
304
|
+
}))),
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
await this.$store.dispatch(`management/findPage`, { type: CAPI.MACHINE, opt });
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if ( this.canViewMgmtNodes ) {
|
|
312
|
+
const opt: ActionFindPageArgs = {
|
|
313
|
+
force,
|
|
314
|
+
pagination: new FilterArgs({
|
|
315
|
+
filters: PaginationParamFilter.createMultipleFields(page.map((r: any) => new PaginationFilterField({
|
|
316
|
+
field: 'id',
|
|
317
|
+
value: r.mgmtClusterId,
|
|
318
|
+
exact: false,
|
|
319
|
+
}))),
|
|
320
|
+
})
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
this.$store.dispatch(`management/findPage`, { type: MANAGEMENT.NODE, opt });
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// We need to fetch node pools and node templates in order to correctly show the provider for RKE1 clusters
|
|
327
|
+
if ( this.canViewMgmtPools && this.canViewMgmtTemplates ) {
|
|
328
|
+
const nodePoolFilters = PaginationParamFilter.createMultipleFields(page
|
|
329
|
+
.filter((p: any) => p.status?.clusterName)
|
|
330
|
+
.map((r: any) => new PaginationFilterField({
|
|
331
|
+
field: 'spec.clusterName',
|
|
332
|
+
value: r.status?.clusterName
|
|
333
|
+
})));
|
|
334
|
+
const nodePools = await this.$store.dispatch(`management/findPage`, {
|
|
335
|
+
type: MANAGEMENT.NODE_POOL,
|
|
336
|
+
opt: {
|
|
337
|
+
force,
|
|
338
|
+
pagination: new FilterArgs({ filters: nodePoolFilters })
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const templateOpt = PaginationParamFilter.createMultipleFields(nodePools
|
|
343
|
+
.filter((np: any) => !!np.nodeTemplateId)
|
|
344
|
+
.map((np: any) => new PaginationFilterField({
|
|
345
|
+
field: 'id',
|
|
346
|
+
value: np.nodeTemplateId,
|
|
347
|
+
exact: true,
|
|
348
|
+
})));
|
|
349
|
+
|
|
350
|
+
this.$store.dispatch(`management/findPage`, {
|
|
351
|
+
type: MANAGEMENT.NODE_TEMPLATE,
|
|
352
|
+
opt: {
|
|
353
|
+
force,
|
|
354
|
+
pagination: new FilterArgs({ filters: templateOpt })
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
|
|
232
360
|
/**
|
|
233
361
|
* Define actions for each navigation link
|
|
234
362
|
* @param {*} action
|
|
235
363
|
*/
|
|
236
|
-
handlePageAction(action) {
|
|
364
|
+
handlePageAction(action: any) {
|
|
237
365
|
switch (action.action) {
|
|
238
366
|
case RESET_CARDS_ACTION:
|
|
239
367
|
this.resetCards();
|
|
@@ -247,21 +375,22 @@ export default {
|
|
|
247
375
|
}
|
|
248
376
|
},
|
|
249
377
|
|
|
250
|
-
cpuUsed(cluster) {
|
|
378
|
+
cpuUsed(cluster: any) {
|
|
251
379
|
return parseSi(cluster.status.requested?.cpu);
|
|
252
380
|
},
|
|
253
381
|
|
|
254
|
-
cpuAllocatable(cluster) {
|
|
382
|
+
cpuAllocatable(cluster: any) {
|
|
255
383
|
return parseSi(cluster.status.allocatable?.cpu);
|
|
256
384
|
},
|
|
257
|
-
|
|
385
|
+
|
|
386
|
+
memoryAllocatable(cluster: any) {
|
|
258
387
|
const parsedAllocatable = (parseSi(cluster.status.allocatable?.memory) || 0).toString();
|
|
259
388
|
const format = createMemoryFormat(parsedAllocatable);
|
|
260
389
|
|
|
261
390
|
return formatSi(parsedAllocatable, format);
|
|
262
391
|
},
|
|
263
392
|
|
|
264
|
-
memoryReserved(cluster) {
|
|
393
|
+
memoryReserved(cluster: any) {
|
|
265
394
|
const memValues = createMemoryValues(cluster?.status?.allocatable?.memory, cluster?.status?.requested?.memory);
|
|
266
395
|
|
|
267
396
|
return `${ memValues.useful }/${ memValues.total } ${ memValues.units }`;
|
|
@@ -294,11 +423,55 @@ export default {
|
|
|
294
423
|
if (retry === 0 && res?.type === 'error' && res?.status === 500) {
|
|
295
424
|
await this.closeSetLoginBanner(retry + 1);
|
|
296
425
|
}
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Filter out hidden clusters from list of all clusters
|
|
430
|
+
*/
|
|
431
|
+
filterRowsLocal(rows: any[]) {
|
|
432
|
+
return filterHiddenLocalCluster(filterOnlyKubernetesClusters(rows || [], this.$store), this.$store);
|
|
433
|
+
},
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Filter out hidden clusters via api
|
|
437
|
+
*/
|
|
438
|
+
filterRowsApi(pagination: PaginationArgs): PaginationArgs {
|
|
439
|
+
if (!pagination.filters) {
|
|
440
|
+
pagination.filters = [];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const existingFilters = pagination.filters;
|
|
444
|
+
const requiredFilters = paginationFilterClusters(this.$store, false);
|
|
445
|
+
|
|
446
|
+
for (let i = 0; i < requiredFilters.length; i++) {
|
|
447
|
+
let found = false;
|
|
448
|
+
const required = requiredFilters[i];
|
|
449
|
+
|
|
450
|
+
for (let j = 0; j < existingFilters.length; j++) {
|
|
451
|
+
const existing = existingFilters[j];
|
|
452
|
+
|
|
453
|
+
if (
|
|
454
|
+
required.fields.length === existing.fields.length &&
|
|
455
|
+
sameContents(required.fields.map((e) => e.field), existing.fields.map((e) => e.field))
|
|
456
|
+
) {
|
|
457
|
+
Object.assign(existing, required);
|
|
458
|
+
found = true;
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (!found) {
|
|
464
|
+
pagination.filters.push(required);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return pagination;
|
|
297
469
|
}
|
|
298
470
|
}
|
|
299
|
-
};
|
|
471
|
+
});
|
|
300
472
|
|
|
301
473
|
</script>
|
|
474
|
+
|
|
302
475
|
<template>
|
|
303
476
|
<div
|
|
304
477
|
v-if="managementReady"
|
|
@@ -369,14 +542,24 @@ export default {
|
|
|
369
542
|
v-if="mcm"
|
|
370
543
|
class="col span-12"
|
|
371
544
|
>
|
|
372
|
-
<
|
|
545
|
+
<PaginatedResourceTable
|
|
546
|
+
v-if="provClusterSchema"
|
|
547
|
+
:schema="provClusterSchema"
|
|
373
548
|
:table-actions="false"
|
|
374
549
|
:row-actions="false"
|
|
375
550
|
key-field="id"
|
|
376
|
-
:
|
|
377
|
-
:headers="
|
|
378
|
-
|
|
379
|
-
|
|
551
|
+
:headers="headers"
|
|
552
|
+
:pagination-headers="paginationHeaders"
|
|
553
|
+
context="home"
|
|
554
|
+
|
|
555
|
+
:local-filter="filterRowsLocal"
|
|
556
|
+
:api-filter="filterRowsApi"
|
|
557
|
+
|
|
558
|
+
:namespaced="false"
|
|
559
|
+
:groupable="false"
|
|
560
|
+
manualRefreshButtonSize="sm"
|
|
561
|
+
:fetchSecondaryResources="fetchSecondaryResources"
|
|
562
|
+
:fetchPageSecondaryResources="fetchPageSecondaryResources"
|
|
380
563
|
>
|
|
381
564
|
<template #header-left>
|
|
382
565
|
<div class="row table-heading">
|
|
@@ -384,19 +567,19 @@ export default {
|
|
|
384
567
|
{{ t('landing.clusters.title') }}
|
|
385
568
|
</h2>
|
|
386
569
|
<BadgeState
|
|
387
|
-
v-if="
|
|
388
|
-
:label="
|
|
570
|
+
v-if="clusterCount"
|
|
571
|
+
:label="clusterCount.toString()"
|
|
389
572
|
color="role-tertiary ml-20 mr-20"
|
|
390
573
|
/>
|
|
391
574
|
</div>
|
|
392
575
|
</template>
|
|
393
576
|
<template
|
|
394
|
-
v-if="canCreateCluster ||
|
|
577
|
+
v-if="canCreateCluster || !!provClusterSchema"
|
|
395
578
|
#header-middle
|
|
396
579
|
>
|
|
397
580
|
<div class="table-heading">
|
|
398
581
|
<router-link
|
|
399
|
-
v-if="
|
|
582
|
+
v-if="!!provClusterSchema"
|
|
400
583
|
:to="manageLocation"
|
|
401
584
|
class="btn btn-sm role-secondary"
|
|
402
585
|
data-testid="cluster-management-manage-button"
|
|
@@ -487,7 +670,7 @@ export default {
|
|
|
487
670
|
{{ t('landing.clusters.explore') }}
|
|
488
671
|
</button>
|
|
489
672
|
</template> -->
|
|
490
|
-
</
|
|
673
|
+
</PaginatedResourceTable>
|
|
491
674
|
</div>
|
|
492
675
|
<div
|
|
493
676
|
v-else
|
|
@@ -502,6 +685,7 @@ export default {
|
|
|
502
685
|
</IndentedPanel>
|
|
503
686
|
</div>
|
|
504
687
|
</template>
|
|
688
|
+
|
|
505
689
|
<style lang='scss' scoped>
|
|
506
690
|
.home-panels {
|
|
507
691
|
display: flex;
|
|
@@ -591,6 +775,7 @@ export default {
|
|
|
591
775
|
}
|
|
592
776
|
}
|
|
593
777
|
</style>
|
|
778
|
+
|
|
594
779
|
<style lang="scss">
|
|
595
780
|
.home-page {
|
|
596
781
|
.search {
|
|
@@ -375,6 +375,8 @@ describe('dashboard-store: mutations', () => {
|
|
|
375
375
|
it.each([
|
|
376
376
|
['Add a new pod', mutationHelpers.loadAll.createNewEntry()],
|
|
377
377
|
])('%s', (_, run) => { // eslint-disable-line jest/no-identical-title
|
|
378
|
+
run.expected.types[POD].havePage = false;
|
|
379
|
+
|
|
378
380
|
loadAdd(...run.params);
|
|
379
381
|
const { map: cacheMap, ...cacheState } = run.params[0].types?.[POD] || {};
|
|
380
382
|
const { map: expectedMap, ...expected } = run.expected.types?.[POD];
|
|
@@ -146,7 +146,7 @@ export default {
|
|
|
146
146
|
/**
|
|
147
147
|
*
|
|
148
148
|
* @param {*} ctx
|
|
149
|
-
* @param { {type: string, opt:
|
|
149
|
+
* @param { {type: string, opt: ActionFindAllArgs} } opt
|
|
150
150
|
*/
|
|
151
151
|
async findAll(ctx, { type, opt }) {
|
|
152
152
|
const {
|
|
@@ -364,7 +364,7 @@ export default {
|
|
|
364
364
|
/**
|
|
365
365
|
*
|
|
366
366
|
* @param {*} ctx
|
|
367
|
-
* @param { {type: string, opt:
|
|
367
|
+
* @param { {type: string, opt: ActionFindPageArgs} } opt
|
|
368
368
|
*/
|
|
369
369
|
async findPage(ctx, { type, opt }) {
|
|
370
370
|
const { getters, commit, dispatch } = ctx;
|
|
@@ -384,7 +384,7 @@ export default {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
// No need to request the resources if we have them already
|
|
387
|
-
if (!opt.force && getters['havePaginatedPage'](type, opt)) {
|
|
387
|
+
if (!opt.transient && !opt.force && getters['havePaginatedPage'](type, opt)) {
|
|
388
388
|
return findAllGetter(getters, type, opt);
|
|
389
389
|
}
|
|
390
390
|
|
|
@@ -408,24 +408,31 @@ export default {
|
|
|
408
408
|
return Promise.reject(e);
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
-
|
|
412
|
-
ctx,
|
|
411
|
+
await dispatch('unwatch', {
|
|
413
412
|
type,
|
|
414
|
-
|
|
415
|
-
pagination: opt.pagination ? {
|
|
416
|
-
request: {
|
|
417
|
-
namespace: opt.namespaced,
|
|
418
|
-
pagination: opt.pagination
|
|
419
|
-
},
|
|
420
|
-
result: {
|
|
421
|
-
count: out.count,
|
|
422
|
-
pages: out.pages || Math.ceil(out.count / (opt.pagination.pageSize || Number.MAX_SAFE_INTEGER)),
|
|
423
|
-
timestamp: new Date().getTime()
|
|
424
|
-
}
|
|
425
|
-
} : undefined,
|
|
413
|
+
all: true,
|
|
426
414
|
});
|
|
427
415
|
|
|
428
|
-
const
|
|
416
|
+
const pagination = opt.pagination ? {
|
|
417
|
+
request: {
|
|
418
|
+
namespace: opt.namespaced,
|
|
419
|
+
pagination: opt.pagination
|
|
420
|
+
},
|
|
421
|
+
result: {
|
|
422
|
+
count: out.count,
|
|
423
|
+
pages: out.pages || Math.ceil(out.count / (opt.pagination.pageSize || Number.MAX_SAFE_INTEGER)),
|
|
424
|
+
timestamp: new Date().getTime()
|
|
425
|
+
}
|
|
426
|
+
} : undefined;
|
|
427
|
+
|
|
428
|
+
if (!opt.transient) {
|
|
429
|
+
commit('loadPage', {
|
|
430
|
+
ctx,
|
|
431
|
+
type,
|
|
432
|
+
data: out.data,
|
|
433
|
+
pagination,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
429
436
|
|
|
430
437
|
if (opt.hasManualRefresh) {
|
|
431
438
|
dispatch('resource-fetch/updateManualRefreshIsLoading', false, { root: true });
|
|
@@ -433,7 +440,10 @@ export default {
|
|
|
433
440
|
|
|
434
441
|
garbageCollect.gcUpdateLastAccessed(ctx, type);
|
|
435
442
|
|
|
436
|
-
return
|
|
443
|
+
return opt.transient ? {
|
|
444
|
+
data: out.data,
|
|
445
|
+
pagination
|
|
446
|
+
} : findAllGetter(getters, type, opt);
|
|
437
447
|
},
|
|
438
448
|
|
|
439
449
|
async findMatching(ctx, {
|