@rancher/shell 3.0.5-rc.9 → 3.0.6
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/translations/en-us.yaml +11 -5
- package/components/FilterPanel.vue +8 -1
- package/components/PaginatedResourceTable.vue +7 -2
- package/components/PodSecurityAdmission.vue +2 -0
- package/components/PromptRemove.vue +5 -0
- package/components/ResourceTable.vue +30 -20
- package/components/form/ProjectMemberEditor.vue +2 -0
- package/components/nav/Header.vue +6 -5
- package/config/product/explorer.js +5 -5
- package/config/store.js +2 -0
- package/config/uiplugins.js +1 -1
- package/core/plugin.ts +15 -3
- package/core/types.ts +30 -7
- package/dialog/SloDialog.vue +1 -1
- package/edit/auth/oidc.vue +106 -6
- package/edit/auth/saml.vue +5 -5
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -0
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +6 -0
- package/initialize/install-plugins.js +1 -3
- package/list/catalog.cattle.io.clusterrepo.vue +2 -2
- package/mixins/__tests__/auth-config.test.ts +4 -6
- package/mixins/__tests__/chart.test.ts +1 -1
- package/mixins/auth-config.js +33 -10
- package/mixins/chart.js +1 -1
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/workload.js +1 -1
- package/package.json +2 -2
- package/pages/auth/login.vue +8 -3
- package/pages/auth/logout.vue +6 -5
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +6 -0
- package/pages/c/_cluster/apps/charts/StatusLabel.vue +4 -3
- package/pages/c/_cluster/apps/charts/index.vue +12 -11
- package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +1 -1
- package/pages/c/_cluster/explorer/tools/index.vue +1 -1
- package/plugins/axios.js +3 -2
- package/plugins/dashboard-store/resource-class.js +12 -1
- package/plugins/ember-cookie.js +7 -3
- package/plugins/steve/steve-pagination-utils.ts +14 -22
- package/plugins/steve/subscribe.js +4 -2
- package/scripts/test-plugins-build.sh +4 -6
- package/scripts/typegen.sh +2 -0
- package/store/__tests__/cookies.test.ts +72 -0
- package/store/auth.js +34 -11
- package/store/cookies.ts +30 -0
- package/store/prefs.js +10 -5
- package/types/shell/index.d.ts +183 -11
- package/types/store/vuex.d.ts +2 -1
- package/types/vue-shim.d.ts +2 -5
- package/utils/auth.js +1 -1
- package/utils/pagination-utils.ts +11 -2
- package/utils/cookie-universal.js +0 -10
|
@@ -98,12 +98,11 @@ createTestComponent() {
|
|
|
98
98
|
# Add test list component to the test package
|
|
99
99
|
# Validates rancher-components imports
|
|
100
100
|
|
|
101
|
-
#
|
|
102
|
-
# cp ${SHELL_DIR}/list/catalog.cattle.io.clusterrepo.vue pkg/test-pkg/list
|
|
103
|
-
# See https://github.com/rancher/dashboard/issues/12918
|
|
104
|
-
|
|
105
|
-
# Use a basic list instead
|
|
101
|
+
# Basic list instead
|
|
106
102
|
cp ${SHELL_DIR}/list/namespace.vue pkg/test-pkg/list
|
|
103
|
+
|
|
104
|
+
# More complex list
|
|
105
|
+
cp ${SHELL_DIR}/list/catalog.cattle.io.clusterrepo.vue pkg/test-pkg/list
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
# Publish shell pkg (tag is needed as publish-shell is optimized to work with release-shell-pkg workflow)
|
|
@@ -239,7 +238,6 @@ function clone_repo_test_extension_build() {
|
|
|
239
238
|
clone_repo_test_extension_build "rancher" "kubewarden-ui" "kubewarden"
|
|
240
239
|
clone_repo_test_extension_build "rancher" "elemental-ui" "elemental"
|
|
241
240
|
clone_repo_test_extension_build "neuvector" "manager-ext" "neuvector-ui-ext"
|
|
242
|
-
clone_repo_test_extension_build "rancher" "capi-ui-extension" "capi"
|
|
243
241
|
clone_repo_test_extension_build "StackVista" "rancher-extension-stackstate" "observability"
|
|
244
242
|
clone_repo_test_extension_build "harvester" "harvester-ui-extension" "harvester"
|
|
245
243
|
|
package/scripts/typegen.sh
CHANGED
|
@@ -39,6 +39,8 @@ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/steve/hybrid-class.js --d
|
|
|
39
39
|
# # mixins
|
|
40
40
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/create-edit-view/index.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins/create-edit-view > /dev/null
|
|
41
41
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/resource-fetch.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins > /dev/null
|
|
42
|
+
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/resource-fetch-namespaced.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins > /dev/null
|
|
43
|
+
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/mixins/resource-fetch-api-pagination.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/mixins > /dev/null
|
|
42
44
|
|
|
43
45
|
# # models
|
|
44
46
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/models/namespace.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/models/ > /dev/null
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import cookieStore from '../cookies';
|
|
2
|
+
|
|
3
|
+
// Mock cookie-universal
|
|
4
|
+
const mockCookie = {
|
|
5
|
+
get: jest.fn(),
|
|
6
|
+
set: jest.fn(),
|
|
7
|
+
remove: jest.fn(),
|
|
8
|
+
getAll: jest.fn(),
|
|
9
|
+
addChangeListener: jest.fn(),
|
|
10
|
+
removeChangeListener: jest.fn()
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
jest.mock('cookie-universal', () => {
|
|
14
|
+
return jest.fn(() => mockCookie);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('store: cookies', () => {
|
|
18
|
+
let state: any;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
state = cookieStore.state();
|
|
22
|
+
// Reset mocks before each test
|
|
23
|
+
mockCookie.get.mockClear();
|
|
24
|
+
mockCookie.set.mockClear();
|
|
25
|
+
mockCookie.remove.mockClear();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('getters', () => {
|
|
29
|
+
it('get should call cookies.get with the correct parameters', () => {
|
|
30
|
+
const { getters } = cookieStore;
|
|
31
|
+
const key = 'test-key';
|
|
32
|
+
const options = { from: 'server' };
|
|
33
|
+
|
|
34
|
+
getters.get(state, {}, {}, {})({ key, options });
|
|
35
|
+
expect(mockCookie.get).toHaveBeenCalledWith(key, options);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('mutations', () => {
|
|
40
|
+
it('set should call cookies.set with the correct parameters', () => {
|
|
41
|
+
const { mutations } = cookieStore;
|
|
42
|
+
const key = 'test-key';
|
|
43
|
+
const value = { data: 'test-value' };
|
|
44
|
+
const options = { path: '/' };
|
|
45
|
+
|
|
46
|
+
mutations.set(state, {
|
|
47
|
+
key, value, options
|
|
48
|
+
});
|
|
49
|
+
expect(mockCookie.set).toHaveBeenCalledWith(key, value, options);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('remove should call cookies.remove with the correct key', () => {
|
|
53
|
+
const { mutations } = cookieStore;
|
|
54
|
+
const key = 'test-key';
|
|
55
|
+
|
|
56
|
+
mutations.remove(state, { key });
|
|
57
|
+
expect(mockCookie.remove).toHaveBeenCalledWith(key);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('state', () => {
|
|
62
|
+
it('should return a cookies object', () => {
|
|
63
|
+
expect(state.cookies).toBeDefined();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('namespaced', () => {
|
|
68
|
+
it('should be namespaced', () => {
|
|
69
|
+
expect(cookieStore.namespaced).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
package/store/auth.js
CHANGED
|
@@ -8,6 +8,13 @@ import { removeEmberPage } from '@shell/utils/ember-page';
|
|
|
8
8
|
import { randomStr } from '@shell/utils/string';
|
|
9
9
|
import { addParams, parse as parseUrl, removeParam } from '@shell/utils/url';
|
|
10
10
|
|
|
11
|
+
// configuration for Single Logout/SLO
|
|
12
|
+
// admissable auth providers compatible with SLO, based on shell/models/management.cattle.io.authconfig "configType"
|
|
13
|
+
export const SLO_AUTH_PROVIDERS = ['oidc', 'saml'];
|
|
14
|
+
|
|
15
|
+
// this is connected to the redirect url, for which the logic can be found in "shell/store/auth"
|
|
16
|
+
const SLO_TOKENS_ENDPOINT_LOGOUT_RES_BASETYPE = ['authConfigLogoutOutput'];
|
|
17
|
+
|
|
11
18
|
export const BASE_SCOPES = {
|
|
12
19
|
github: ['read:org'],
|
|
13
20
|
googleoauth: ['openid profile email'],
|
|
@@ -85,8 +92,6 @@ export const mutations = {
|
|
|
85
92
|
loggedInAs(state, principalId) {
|
|
86
93
|
state.loggedIn = true;
|
|
87
94
|
state.principalId = principalId;
|
|
88
|
-
|
|
89
|
-
this.$cookies.remove(KEY);
|
|
90
95
|
},
|
|
91
96
|
|
|
92
97
|
loggedOut(state) {
|
|
@@ -136,10 +141,18 @@ export const actions = {
|
|
|
136
141
|
commit('initialPass', pass);
|
|
137
142
|
},
|
|
138
143
|
|
|
139
|
-
getAuthProviders({ dispatch }) {
|
|
144
|
+
getAuthProviders({ dispatch }, opt) {
|
|
145
|
+
let force = false;
|
|
146
|
+
|
|
147
|
+
if (opt?.force) {
|
|
148
|
+
force = true;
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
return dispatch('rancher/findAll', {
|
|
141
152
|
type: 'authProvider',
|
|
142
|
-
opt: {
|
|
153
|
+
opt: {
|
|
154
|
+
url: `/v3-public/authProviders`, watch: false, force
|
|
155
|
+
}
|
|
143
156
|
}, { root: true });
|
|
144
157
|
},
|
|
145
158
|
|
|
@@ -183,14 +196,18 @@ export const actions = {
|
|
|
183
196
|
* Save nonce details. Information it contains will be used to validate auth requests/responses
|
|
184
197
|
* Note - this may be structurally different than the nonce we encode and send
|
|
185
198
|
*/
|
|
186
|
-
saveNonce(
|
|
199
|
+
saveNonce({ commit }, opt) {
|
|
187
200
|
const strung = JSON.stringify(opt);
|
|
188
201
|
|
|
189
|
-
|
|
202
|
+
const options = {
|
|
190
203
|
path: '/',
|
|
191
204
|
sameSite: true,
|
|
192
205
|
secure: true,
|
|
193
|
-
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
commit('cookies/set', {
|
|
209
|
+
key: KEY, value: strung, options
|
|
210
|
+
}, { root: true });
|
|
194
211
|
|
|
195
212
|
return strung;
|
|
196
213
|
},
|
|
@@ -265,8 +282,8 @@ export const actions = {
|
|
|
265
282
|
}
|
|
266
283
|
},
|
|
267
284
|
|
|
268
|
-
verifyOAuth({ dispatch }, { nonce, code, provider }) {
|
|
269
|
-
const expectJSON =
|
|
285
|
+
verifyOAuth({ dispatch, rootGetters }, { nonce, code, provider }) {
|
|
286
|
+
const expectJSON = rootGetters['cookies/get']({ key: KEY, options: { parseJSON: false } });
|
|
270
287
|
let parsed;
|
|
271
288
|
|
|
272
289
|
try {
|
|
@@ -351,6 +368,12 @@ export const actions = {
|
|
|
351
368
|
}
|
|
352
369
|
},
|
|
353
370
|
|
|
371
|
+
loggedInAs({ commit }, principalId) {
|
|
372
|
+
commit('loggedInAs', principalId);
|
|
373
|
+
|
|
374
|
+
commit('cookies/remove', { key: KEY }, { root: true });
|
|
375
|
+
},
|
|
376
|
+
|
|
354
377
|
uiLogout({ commit, dispatch }) {
|
|
355
378
|
removeEmberPage();
|
|
356
379
|
|
|
@@ -398,8 +421,8 @@ export const actions = {
|
|
|
398
421
|
redirectUnauthorized: false,
|
|
399
422
|
}, { root: true });
|
|
400
423
|
|
|
401
|
-
// Single-sign logout for
|
|
402
|
-
if (res.baseType
|
|
424
|
+
// Single-sign logout redirect for SLO compatible auth providers
|
|
425
|
+
if (SLO_TOKENS_ENDPOINT_LOGOUT_RES_BASETYPE.includes(res.baseType) && res.idpRedirectUrl) {
|
|
403
426
|
window.location.href = res.idpRedirectUrl;
|
|
404
427
|
|
|
405
428
|
return;
|
package/store/cookies.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MutationTree, GetterTree, ActionTree } from 'vuex';
|
|
2
|
+
import Cookie, { ICookie, ICookieGetOpts } from 'cookie-universal';
|
|
3
|
+
|
|
4
|
+
type State = { cookies: ICookie };
|
|
5
|
+
const options = { parseJSON: true };
|
|
6
|
+
const state = (): State => ({ cookies: Cookie(undefined, undefined, options.parseJSON) });
|
|
7
|
+
|
|
8
|
+
const getters: GetterTree<State, any> = {
|
|
9
|
+
get(state) {
|
|
10
|
+
return ({ key, options }: {key: string, options?: ICookieGetOpts}) => state.cookies.get(key, options);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const mutations: MutationTree<State> = {
|
|
14
|
+
set(state, { key, value, options }) {
|
|
15
|
+
return state.cookies.set(key, value, options);
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
remove(state, { key }) {
|
|
19
|
+
return state.cookies.remove(key);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const actions: ActionTree<State, any> = {};
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
namespaced: true,
|
|
26
|
+
state,
|
|
27
|
+
getters,
|
|
28
|
+
mutations,
|
|
29
|
+
actions
|
|
30
|
+
};
|
package/store/prefs.js
CHANGED
|
@@ -289,12 +289,16 @@ export const actions = {
|
|
|
289
289
|
commit('load', { key, value });
|
|
290
290
|
|
|
291
291
|
if ( definition.asCookie ) {
|
|
292
|
-
const
|
|
292
|
+
const options = {
|
|
293
293
|
...cookieOptions,
|
|
294
294
|
parseJSON: definition.parseJSON === true
|
|
295
295
|
};
|
|
296
296
|
|
|
297
|
-
|
|
297
|
+
const computedKey = `${ cookiePrefix }${ key }`.toUpperCase();
|
|
298
|
+
|
|
299
|
+
commit('cookies/set', {
|
|
300
|
+
key: computedKey, value, options
|
|
301
|
+
}, { root: true });
|
|
298
302
|
}
|
|
299
303
|
|
|
300
304
|
if ( definition.asUserPreference ) {
|
|
@@ -336,7 +340,7 @@ export const actions = {
|
|
|
336
340
|
await dispatch('set', { key: THEME, value: val });
|
|
337
341
|
},
|
|
338
342
|
|
|
339
|
-
loadCookies({ state, commit }) {
|
|
343
|
+
loadCookies({ state, commit, rootGetters }) {
|
|
340
344
|
if ( state.cookiesLoaded ) {
|
|
341
345
|
return;
|
|
342
346
|
}
|
|
@@ -348,8 +352,9 @@ export const actions = {
|
|
|
348
352
|
continue;
|
|
349
353
|
}
|
|
350
354
|
|
|
351
|
-
const
|
|
352
|
-
const
|
|
355
|
+
const options = { parseJSON: definition.parseJSON === true };
|
|
356
|
+
const computedKey = `${ cookiePrefix }${ key }`.toUpperCase();
|
|
357
|
+
const value = rootGetters['cookies/get']({ key: computedKey, options });
|
|
353
358
|
|
|
354
359
|
if (value !== undefined) {
|
|
355
360
|
commit('load', { key, value });
|
package/types/shell/index.d.ts
CHANGED
|
@@ -2323,6 +2323,18 @@ export function setKubeVersionData(v: any): void;
|
|
|
2323
2323
|
export const CURRENT_RANCHER_VERSION: "2.12";
|
|
2324
2324
|
}
|
|
2325
2325
|
|
|
2326
|
+
// @shell/mixins/components/ResourceList/resource-list.config
|
|
2327
|
+
|
|
2328
|
+
declare module '@shell/mixins/components/ResourceList/resource-list.config' {
|
|
2329
|
+
/**
|
|
2330
|
+
* Component name of the `ResourceList`
|
|
2331
|
+
*
|
|
2332
|
+
* This needs to be a in separate file to avoid circular dependency of
|
|
2333
|
+
* index.vue --> resource-fetch mixin --> resource-fetch-namespaced mixin --> index.vue
|
|
2334
|
+
*/
|
|
2335
|
+
export const ResourceListComponentName: "ResourceList";
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2326
2338
|
// @shell/mixins/create-edit-view/impl
|
|
2327
2339
|
|
|
2328
2340
|
declare module '@shell/mixins/create-edit-view/impl' {
|
|
@@ -2468,6 +2480,175 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
2468
2480
|
export default _default;
|
|
2469
2481
|
}
|
|
2470
2482
|
|
|
2483
|
+
// @shell/mixins/mixins/resource-fetch-api-pagination
|
|
2484
|
+
|
|
2485
|
+
declare module '@shell/mixins/mixins/resource-fetch-api-pagination' {
|
|
2486
|
+
declare namespace _default {
|
|
2487
|
+
namespace props {
|
|
2488
|
+
namespace namespaced {
|
|
2489
|
+
export let type: BooleanConstructor;
|
|
2490
|
+
let _default: any;
|
|
2491
|
+
export { _default as default };
|
|
2492
|
+
}
|
|
2493
|
+
namespace context {
|
|
2494
|
+
let type_1: StringConstructor;
|
|
2495
|
+
export { type_1 as type };
|
|
2496
|
+
let _default_1: any;
|
|
2497
|
+
export { _default_1 as default };
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
function data(): {
|
|
2501
|
+
forceUpdateLiveAndDelayed: number;
|
|
2502
|
+
/**
|
|
2503
|
+
* This of type `OptPagination`
|
|
2504
|
+
*/
|
|
2505
|
+
pPagination: any;
|
|
2506
|
+
debouncedSetPagination: any;
|
|
2507
|
+
/**
|
|
2508
|
+
* Apply these additional filters given the ns / project header selection
|
|
2509
|
+
*/
|
|
2510
|
+
requestFilters: {
|
|
2511
|
+
filters: any[];
|
|
2512
|
+
projectsOrNamespaces: any[];
|
|
2513
|
+
};
|
|
2514
|
+
paginationFromList: any;
|
|
2515
|
+
isPaginationManualRefreshEnabled: any;
|
|
2516
|
+
};
|
|
2517
|
+
namespace methods {
|
|
2518
|
+
/**
|
|
2519
|
+
* @param {PaginationArgs} pagination
|
|
2520
|
+
*/
|
|
2521
|
+
function setPagination(pagination: PaginationArgs): void;
|
|
2522
|
+
/**
|
|
2523
|
+
* Primary point that handles changes from either a table or the namespace filter
|
|
2524
|
+
*/
|
|
2525
|
+
function paginationChanged(event: any): void;
|
|
2526
|
+
/**
|
|
2527
|
+
* @param {PaginationArgs} neu
|
|
2528
|
+
* @param {PaginationArgs} old
|
|
2529
|
+
*/
|
|
2530
|
+
function paginationEqual(neu: PaginationArgs, old: PaginationArgs): boolean;
|
|
2531
|
+
function calcCanPaginate(): any;
|
|
2532
|
+
}
|
|
2533
|
+
namespace computed {
|
|
2534
|
+
/**
|
|
2535
|
+
* Why is this a specific getter and not not in mapGetters?
|
|
2536
|
+
*
|
|
2537
|
+
* Adding it to mapGetters means the kubewarden unit tests fail as they don't mock it....
|
|
2538
|
+
*/
|
|
2539
|
+
function namespaceFilters(): any;
|
|
2540
|
+
/**
|
|
2541
|
+
* Does the user need to update the filter to supply valid options?
|
|
2542
|
+
*/
|
|
2543
|
+
function paginationNsFilterRequired(): boolean;
|
|
2544
|
+
/**
|
|
2545
|
+
* Check if the Project/Namespace filter from the header contains a valid ns / project filter
|
|
2546
|
+
*/
|
|
2547
|
+
function __validPaginationNsFilter(): any;
|
|
2548
|
+
/**
|
|
2549
|
+
* ResourceList imports resource-fetch --> this mixin
|
|
2550
|
+
* When there is no custom list this is fine (ResourceList with mixins --> ResourceTable)
|
|
2551
|
+
* When there is a custom list there are two instances of this mixin (ResourceList with mixins --> CustomList with mixins --> ResourceTable)
|
|
2552
|
+
* - In this scenario, reduce churn by exiting earlier if mixin is from parent ResourceList and leave work for CustomList mixins
|
|
2553
|
+
*/
|
|
2554
|
+
function isResourceList(): any;
|
|
2555
|
+
/**
|
|
2556
|
+
* Is Pagination supported and has the table supplied pagination settings from the table?
|
|
2557
|
+
*/
|
|
2558
|
+
function pagination(): any;
|
|
2559
|
+
/**
|
|
2560
|
+
* Should this list be paginated via API?
|
|
2561
|
+
*/
|
|
2562
|
+
function canPaginate(): any;
|
|
2563
|
+
function paginationResult(): any;
|
|
2564
|
+
function havePaginated(): any;
|
|
2565
|
+
/**
|
|
2566
|
+
* Links to ns.isSystem and covers things like ns with system annotation, hardcoded list, etc
|
|
2567
|
+
*/
|
|
2568
|
+
function productHidesSystemNamespaces(): any;
|
|
2569
|
+
/**
|
|
2570
|
+
* Links to ns.isObscure and covers things like `c-`, `user-`, etc (see OBSCURE_NAMESPACE_PREFIX)
|
|
2571
|
+
*/
|
|
2572
|
+
function showDynamicRancherNamespaces(): any;
|
|
2573
|
+
function isNamespaced(): any;
|
|
2574
|
+
let currentProduct: import("vuex").Computed;
|
|
2575
|
+
let isAllNamespaces: import("vuex").Computed;
|
|
2576
|
+
}
|
|
2577
|
+
let watch: {
|
|
2578
|
+
/**
|
|
2579
|
+
* Monitor the rows to ensure deleting the last entry in a server-side paginated page doesn't
|
|
2580
|
+
* result in an empty page
|
|
2581
|
+
*/
|
|
2582
|
+
rows(neu: any): void;
|
|
2583
|
+
namespaceFilters: {
|
|
2584
|
+
immediate: boolean;
|
|
2585
|
+
handler(neu: any, old: any): Promise<void>;
|
|
2586
|
+
};
|
|
2587
|
+
'requestFilters.filters'(): void;
|
|
2588
|
+
'requestFilters.projectsOrNamespaces'(): void;
|
|
2589
|
+
/**
|
|
2590
|
+
* When a pagination is required and the user changes page / sort / filter, kick off a new set of API requests
|
|
2591
|
+
*
|
|
2592
|
+
* @param {StorePaginationResult} neu
|
|
2593
|
+
* @param {StorePaginationResult} old
|
|
2594
|
+
*/
|
|
2595
|
+
pagination(neu: StorePaginationResult, old: StorePaginationResult): Promise<void>;
|
|
2596
|
+
/**
|
|
2597
|
+
* If the pagination result has changed fetch secondary resources
|
|
2598
|
+
*
|
|
2599
|
+
* Lists should implement fetchPageSecondaryResources to fetch them
|
|
2600
|
+
*
|
|
2601
|
+
* @param {StorePaginationResult} neu
|
|
2602
|
+
* @param {StorePaginationResult} old
|
|
2603
|
+
*/
|
|
2604
|
+
paginationResult(neu: StorePaginationResult, old: StorePaginationResult): Promise<void>;
|
|
2605
|
+
};
|
|
2606
|
+
function beforeUnmount(): Promise<void>;
|
|
2607
|
+
}
|
|
2608
|
+
export default _default;
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
// @shell/mixins/mixins/resource-fetch-namespaced
|
|
2612
|
+
|
|
2613
|
+
declare module '@shell/mixins/mixins/resource-fetch-namespaced' {
|
|
2614
|
+
declare namespace _default {
|
|
2615
|
+
function data(): {
|
|
2616
|
+
forceUpdateLiveAndDelayed: number;
|
|
2617
|
+
};
|
|
2618
|
+
namespace computed {
|
|
2619
|
+
/**
|
|
2620
|
+
* Does the user need to update the filter to supply a single namespace?
|
|
2621
|
+
*/
|
|
2622
|
+
function namespaceFilterRequired(): boolean;
|
|
2623
|
+
/**
|
|
2624
|
+
* Returns the namespace that requests should be filtered by
|
|
2625
|
+
*/
|
|
2626
|
+
function namespaceFilter(): "" | (() => import("vuex").Computed);
|
|
2627
|
+
/**
|
|
2628
|
+
* If the Project/Namespace filter from the header contains a valid ns / project filter ... return it
|
|
2629
|
+
*/
|
|
2630
|
+
function __validFilter(): import("vuex").Computed;
|
|
2631
|
+
/**
|
|
2632
|
+
* Do we need to filter the list by a namespace? This will control whether the user is shown an error
|
|
2633
|
+
*
|
|
2634
|
+
* We shouldn't show an error on pages with resources that aren't namespaced
|
|
2635
|
+
*/
|
|
2636
|
+
function __namespaceRequired(): false | (() => any);
|
|
2637
|
+
/**
|
|
2638
|
+
* Are all core list resources namespaced?
|
|
2639
|
+
*/
|
|
2640
|
+
function __areResourcesNamespaced(): any;
|
|
2641
|
+
let currentProduct: import("vuex").Computed;
|
|
2642
|
+
let currentCluster: import("vuex").Computed;
|
|
2643
|
+
let namespaceFilters: import("vuex").Computed;
|
|
2644
|
+
}
|
|
2645
|
+
namespace watch {
|
|
2646
|
+
function namespaceFilter(neu: any): Promise<void>;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
export default _default;
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2471
2652
|
// @shell/mixins/resource-fetch
|
|
2472
2653
|
|
|
2473
2654
|
declare module '@shell/mixins/resource-fetch' {
|
|
@@ -3601,9 +3782,10 @@ export namespace actions {
|
|
|
3601
3782
|
function setTheme({ dispatch }: {
|
|
3602
3783
|
dispatch: any;
|
|
3603
3784
|
}, val: any): Promise<void>;
|
|
3604
|
-
function loadCookies({ state, commit }: {
|
|
3785
|
+
function loadCookies({ state, commit, rootGetters }: {
|
|
3605
3786
|
state: any;
|
|
3606
3787
|
commit: any;
|
|
3788
|
+
rootGetters: any;
|
|
3607
3789
|
}): void;
|
|
3608
3790
|
function loadTheme({ dispatch }: {
|
|
3609
3791
|
dispatch: any;
|
|
@@ -3850,16 +4032,6 @@ declare function _default(context: any, inject: any): void;
|
|
|
3850
4032
|
export default _default;
|
|
3851
4033
|
}
|
|
3852
4034
|
|
|
3853
|
-
// @shell/utils/cookie-universal
|
|
3854
|
-
|
|
3855
|
-
declare module '@shell/utils/cookie-universal' {
|
|
3856
|
-
declare function _default({ req, res }: {
|
|
3857
|
-
req: any;
|
|
3858
|
-
res: any;
|
|
3859
|
-
}, inject: any): void;
|
|
3860
|
-
export default _default;
|
|
3861
|
-
}
|
|
3862
|
-
|
|
3863
4035
|
// @shell/utils/create-yaml
|
|
3864
4036
|
|
|
3865
4037
|
declare module '@shell/utils/create-yaml' {
|
package/types/store/vuex.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ export interface VuexStoreGetters {
|
|
|
10
10
|
|
|
11
11
|
export interface VuexStore {
|
|
12
12
|
getters: VuexStoreGetters,
|
|
13
|
-
dispatch: any,
|
|
13
|
+
dispatch: <T = any>(action: string, payload?: any) => Promise<T>,
|
|
14
|
+
commit: (mutation: string, payload?: any) => void,
|
|
14
15
|
|
|
15
16
|
// When we have exact properties above we can remove below
|
|
16
17
|
[name:string]: any
|
package/types/vue-shim.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import type ShellApi from '@shell/plugins/internal-api/shell/shell.api';
|
|
3
|
+
import { VuexStore } from '@shell/types/store/vuex';
|
|
3
4
|
|
|
4
5
|
export {};
|
|
5
6
|
|
|
@@ -13,11 +14,7 @@ declare module 'vue' {
|
|
|
13
14
|
(key: string, args?: Record<string, any>, raw?: boolean): string;
|
|
14
15
|
(options: { k: string; raw?: boolean; tag?: string | Record<string, any>; escapehtml?: boolean }): string;
|
|
15
16
|
},
|
|
16
|
-
$store:
|
|
17
|
-
getters: Record<string, any>,
|
|
18
|
-
dispatch: (action: string, payload?: any) => Promise<any>,
|
|
19
|
-
commit: (mutation: string, payload?: any) => void,
|
|
20
|
-
},
|
|
17
|
+
$store: VuexStore,
|
|
21
18
|
$shell: ShellApi,
|
|
22
19
|
}
|
|
23
20
|
}
|
package/utils/auth.js
CHANGED
|
@@ -263,7 +263,7 @@ export async function tryInitialSetup(store, password = 'admin') {
|
|
|
263
263
|
*/
|
|
264
264
|
export async function isLoggedIn(store, userData) {
|
|
265
265
|
store.commit('auth/hasAuth', true);
|
|
266
|
-
store.
|
|
266
|
+
store.dispatch('auth/loggedInAs', userData.id);
|
|
267
267
|
|
|
268
268
|
// Init the notification center now that we know who the user is
|
|
269
269
|
await store.dispatch('notifications/init', userData);
|
|
@@ -16,6 +16,7 @@ import { STEVE_CACHE } from '@shell/store/features';
|
|
|
16
16
|
import { getPerformanceSetting } from '@shell/utils/settings';
|
|
17
17
|
import { PAGINATION_SETTINGS_STORE_DEFAULTS } from '@shell/plugins/steve/steve-pagination-utils';
|
|
18
18
|
import { MANAGEMENT } from '@shell/config/types';
|
|
19
|
+
import { DEFAULT_PERF_SETTING } from '@shell/config/settings';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Helper functions for server side pagination
|
|
@@ -43,7 +44,15 @@ class PaginationUtils {
|
|
|
43
44
|
public getStoreSettings(arg: any | PaginationSettings): PaginationSettingsStore {
|
|
44
45
|
const serverPagination: PaginationSettings = arg?.rootGetters !== undefined ? this.getSettings(arg) : arg;
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
// Ensure we use the current default store settings if
|
|
48
|
+
// 1. from 2.11.0 user saved `ui-performance` setting and it's applied the default pagination settings containing useDefaultStores
|
|
49
|
+
// 2. before 2.11.0 user has saved `ui-performance` setting and it's applied an obsolete pagination settings that lack useDefaultStore
|
|
50
|
+
// 3. user has manually set the `ui-performance` pagination setting useDefaultStores value
|
|
51
|
+
if (serverPagination?.useDefaultStores || serverPagination?.useDefaultStores === undefined) {
|
|
52
|
+
return this.getStoreDefault();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return serverPagination?.stores || this.getStoreDefault();
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
public getStoreDefault(): PaginationSettingsStore {
|
|
@@ -168,7 +177,7 @@ class PaginationUtils {
|
|
|
168
177
|
resourceChangesDebounceMs({ rootGetters }: any): number | undefined {
|
|
169
178
|
const settings = this.getSettings({ rootGetters });
|
|
170
179
|
|
|
171
|
-
return settings.resourceChangesDebounceMs;
|
|
180
|
+
return settings.resourceChangesDebounceMs || DEFAULT_PERF_SETTING.serverPagination.resourceChangesDebounceMs;
|
|
172
181
|
}
|
|
173
182
|
|
|
174
183
|
validateNsProjectFilters(nsProjectFilters: string[]) {
|