@rancher/shell 3.0.3 → 3.0.5-rc.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/styles/base/_basic.scss +6 -0
- package/assets/styles/global/_button.scss +1 -0
- package/assets/translations/en-us.yaml +38 -3
- package/cloud-credential/aws.vue +2 -0
- package/components/AssignTo.vue +25 -11
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/CommunityLinks.vue +3 -3
- package/components/CopyToClipboardText.vue +2 -1
- package/components/DetailText.vue +5 -0
- package/components/DisableAuthProviderModal.vue +1 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +56 -14
- package/components/LandingPagePreference.vue +5 -3
- package/components/LocaleSelector.vue +38 -94
- package/components/ModalWithCard.vue +1 -0
- package/components/MoveModal.vue +1 -0
- package/components/PromptRemove.vue +2 -1
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/SortableTable/index.vue +35 -10
- package/components/StatusBadge.vue +10 -4
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/auth/Principal.vue +9 -3
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/form/ArrayList.vue +75 -54
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +15 -8
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/KeyValue.vue +1 -1
- package/components/form/LabeledSelect.vue +2 -1
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +10 -7
- package/components/form/NameNsDescription.vue +123 -103
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/PodAffinity.vue +43 -43
- package/components/form/Probe.vue +67 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
- package/components/form/SSHKnownHosts/index.vue +16 -2
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +31 -6
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +3 -0
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Group.vue +15 -1
- package/components/nav/Header.vue +1 -0
- package/components/nav/Type.vue +12 -1
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +2 -0
- package/components/templates/home.vue +4 -1
- package/components/templates/plain.vue +4 -1
- package/composables/useRuntimeFlag.ts +29 -0
- package/config/router/routes.js +20 -13
- package/core/types.ts +5 -0
- package/dialog/AddCustomBadgeDialog.vue +1 -0
- package/dialog/DeactivateDriverDialog.vue +5 -4
- package/dialog/ForceMachineRemoveDialog.vue +4 -1
- package/dialog/GitRepoForceUpdateDialog.vue +1 -1
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
- package/edit/auth/__tests__/oidc.test.ts +152 -109
- package/edit/auth/azuread.vue +1 -0
- package/edit/auth/googleoauth.vue +4 -0
- package/edit/auth/oidc.vue +37 -4
- package/edit/cloudcredential.vue +1 -0
- package/edit/fleet.cattle.io.gitrepo.vue +1 -0
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
- package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
- package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +25 -34
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +29 -1
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
- package/edit/token.vue +2 -0
- package/edit/workload/index.vue +1 -0
- package/edit/workload/mixins/workload.js +0 -2
- package/list/management.cattle.io.feature.vue +1 -0
- package/list/provisioning.cattle.io.cluster.vue +20 -12
- package/machine-config/__tests__/vmwarevsphere.test.ts +48 -3
- package/machine-config/vmwarevsphere.vue +16 -0
- package/models/__tests__/namespace.test.ts +25 -1
- package/models/cloudcredential.js +5 -0
- package/models/kontainerdriver.js +6 -3
- package/models/management.cattle.io.node.js +3 -3
- package/models/namespace.js +4 -5
- package/models/nodedriver.js +6 -3
- package/models/workload.js +4 -1
- package/package.json +4 -4
- package/pages/about.vue +16 -8
- package/pages/account/index.vue +4 -1
- package/pages/auth/login.vue +11 -3
- package/pages/auth/logout.vue +4 -1
- package/pages/auth/setup.vue +1 -0
- package/pages/auth/verify.vue +4 -1
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/diagnostic.vue +47 -2
- package/pages/fail-whale.vue +6 -3
- package/pages/home.vue +24 -18
- package/pages/support/index.vue +4 -1
- package/promptRemove/management.cattle.io.fleetworkspace.vue +1 -1
- package/promptRemove/management.cattle.io.globalrole.vue +1 -1
- package/promptRemove/management.cattle.io.project.vue +2 -2
- package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
- package/promptRemove/pod.vue +1 -1
- package/rancher-components/Form/Radio/RadioGroup.vue +25 -23
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +3 -3
- package/rancher-components/RcDropdown/RcDropdown.vue +6 -5
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -2
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +12 -2
- package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
- package/scripts/extension/publish +1 -0
- package/server/har-file.js +25 -3
- package/store/features.js +2 -1
- package/store/type-map.js +4 -0
- package/types/shell/index.d.ts +9 -2
- package/utils/__tests__/string.test.ts +2 -2
- package/utils/cluster.js +35 -0
- package/utils/string.js +1 -3
- package/utils/validators/machine-pool.ts +20 -0
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
|
@@ -10,6 +10,7 @@ export const useDropdownCollection = () => {
|
|
|
10
10
|
const dropdownItems = ref<Element[]>([]);
|
|
11
11
|
const dropdownContainer = ref<HTMLElement | null>(null);
|
|
12
12
|
const firstDropdownItem = ref<HTMLElement | null>(null);
|
|
13
|
+
const lastDropdownItem = ref<HTMLElement | null>(null);
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Registers the dropdown container and initializes dropdown items.
|
|
@@ -22,6 +23,12 @@ export const useDropdownCollection = () => {
|
|
|
22
23
|
if (dropdownItems.value[0] instanceof HTMLElement) {
|
|
23
24
|
firstDropdownItem.value = dropdownItems.value[0];
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
const lastItem = dropdownItems.value[dropdownItems.value.length - 1];
|
|
28
|
+
|
|
29
|
+
if (lastItem instanceof HTMLElement) {
|
|
30
|
+
lastDropdownItem.value = lastItem;
|
|
31
|
+
}
|
|
25
32
|
}
|
|
26
33
|
};
|
|
27
34
|
|
|
@@ -40,6 +47,7 @@ export const useDropdownCollection = () => {
|
|
|
40
47
|
return {
|
|
41
48
|
dropdownItems,
|
|
42
49
|
firstDropdownItem,
|
|
50
|
+
lastDropdownItem,
|
|
43
51
|
dropdownContainer,
|
|
44
52
|
registerDropdownCollection,
|
|
45
53
|
};
|
|
@@ -17,6 +17,7 @@ export const useDropdownContext = (emit: typeof rcDropdownEmits) => {
|
|
|
17
17
|
const {
|
|
18
18
|
dropdownItems,
|
|
19
19
|
firstDropdownItem,
|
|
20
|
+
lastDropdownItem,
|
|
20
21
|
dropdownContainer,
|
|
21
22
|
registerDropdownCollection,
|
|
22
23
|
} = useDropdownCollection();
|
|
@@ -70,7 +71,7 @@ export const useDropdownContext = (emit: typeof rcDropdownEmits) => {
|
|
|
70
71
|
/**
|
|
71
72
|
* Sets focus to the first dropdown item if a keydown event has occurred.
|
|
72
73
|
*/
|
|
73
|
-
const setFocus = () => {
|
|
74
|
+
const setFocus = (direction: 'down' | 'up') => {
|
|
74
75
|
nextTick(() => {
|
|
75
76
|
if (!didKeydown.value) {
|
|
76
77
|
dropdownContainer.value?.focus();
|
|
@@ -78,7 +79,12 @@ export const useDropdownContext = (emit: typeof rcDropdownEmits) => {
|
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
if (direction === 'down') {
|
|
83
|
+
firstDropdownItem.value?.focus();
|
|
84
|
+
} else if (direction === 'up') {
|
|
85
|
+
lastDropdownItem.value?.focus();
|
|
86
|
+
}
|
|
87
|
+
|
|
82
88
|
didKeydown.value = false;
|
|
83
89
|
});
|
|
84
90
|
};
|
|
@@ -95,7 +101,7 @@ export const useDropdownContext = (emit: typeof rcDropdownEmits) => {
|
|
|
95
101
|
dropdownItems,
|
|
96
102
|
close: () => returnFocus(),
|
|
97
103
|
focusFirstElement: () => {
|
|
98
|
-
setFocus();
|
|
104
|
+
setFocus('down');
|
|
99
105
|
},
|
|
100
106
|
handleKeydown,
|
|
101
107
|
});
|
package/server/har-file.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const querystring = require('querystring');
|
|
3
4
|
|
|
4
5
|
// When we receive a request to this URL we will reset the session to replay again from the HAR file
|
|
5
6
|
// This allows the user to refresh the browser and replay the HAR file again
|
|
6
7
|
const RESET_URL = '/api/v1/namespaces/cattle-ui-plugin-system/services/http:ui-plugin-operator:80/proxy/index.json';
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
+
const EXCLUDE_QS = 'exclude';
|
|
10
|
+
|
|
11
|
+
const LEGACY_UI_PLUGIN_INDEX = '/api/v1/namespaces/cattle-ui-plugin-system/services/http:ui-plugin-operator:80/proxy/index.json';
|
|
12
|
+
const NEW_UI_PLUGIN_INDEX = '/v1/uiplugins';
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* Load the network requests/responses from the har file
|
|
@@ -113,10 +117,28 @@ function harProxy(responses, folder) {
|
|
|
113
117
|
const url = decodeURIComponent(req.originalUrl);
|
|
114
118
|
let playback = session[req.originalUrl];
|
|
115
119
|
|
|
120
|
+
// Handle case where HAR file was created with older UI Extension API that used the operator
|
|
121
|
+
if (!playback && req.originalUrl.includes(NEW_UI_PLUGIN_INDEX)) {
|
|
122
|
+
// Look for new URl for UI plugins
|
|
123
|
+
playback = session[LEGACY_UI_PLUGIN_INDEX];
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
// If it did not match, try without the metadata excludes query string that was adding in 2.8.0
|
|
117
127
|
// This might allow HAR captures with Rancher < 2.8.0 to be replayed on >= 2.8.0
|
|
118
|
-
if (!playback && req.originalUrl.
|
|
119
|
-
|
|
128
|
+
if (!playback && req.originalUrl.includes('?')) {
|
|
129
|
+
const urlParts = req.originalUrl.split('?');
|
|
130
|
+
|
|
131
|
+
if (urlParts.length > 1) {
|
|
132
|
+
const queryString = urlParts[1];
|
|
133
|
+
const qs = querystring.parse(queryString);
|
|
134
|
+
|
|
135
|
+
delete qs[EXCLUDE_QS];
|
|
136
|
+
|
|
137
|
+
const newQs = querystring.stringify(qs);
|
|
138
|
+
const newUrl = newQs.length ? `${ urlParts[0] }?${ newQs }` : urlParts[0];
|
|
139
|
+
|
|
140
|
+
playback = session[newUrl];
|
|
141
|
+
}
|
|
120
142
|
}
|
|
121
143
|
|
|
122
144
|
if (playback && playback[req.method] && playback[req.method].length) {
|
package/store/features.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MANAGEMENT } from '@shell/config/types';
|
|
2
|
+
import { SCHEDULING_CUSTOMIZATION as SCHEDULING_CUSTOMIZATION_FEATURE } from '@shell/config/features';
|
|
2
3
|
|
|
3
4
|
const definitions = {};
|
|
4
5
|
|
|
@@ -36,7 +37,7 @@ export const FLEET_WORKSPACE_BACK = create('provisioningv2-fleet-workspace-back-
|
|
|
36
37
|
export const STEVE_CACHE = create('ui-sql-cache', false);
|
|
37
38
|
export const UIEXTENSION = create('uiextension', true);
|
|
38
39
|
export const PROVISIONING_PRE_BOOTSTRAP = create('provisioningprebootstrap', false);
|
|
39
|
-
export const SCHEDULING_CUSTOMIZATION = create(
|
|
40
|
+
export const SCHEDULING_CUSTOMIZATION = create(SCHEDULING_CUSTOMIZATION_FEATURE, false);
|
|
40
41
|
|
|
41
42
|
// Not currently used.. no point defining ones we don't use
|
|
42
43
|
// export const EMBEDDED_CLUSTER_API = create('embedded-cluster-api', true);
|
package/store/type-map.js
CHANGED
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
// graphConfig: undefined -- Use this to pass along the graph configuration
|
|
108
108
|
// notFilterNamespace: undefined -- Define namespaces that do not need to be filtered
|
|
109
109
|
// localOnly: False -- Hide this type from the nav/search bar on downstream clusters
|
|
110
|
+
// custom: any - Custom options for a given type
|
|
110
111
|
// }
|
|
111
112
|
// )
|
|
112
113
|
// ignoreGroup(group): Never show group or any types in it
|
|
@@ -524,6 +525,7 @@ export const getters = {
|
|
|
524
525
|
depaginate: false,
|
|
525
526
|
customRoute: undefined,
|
|
526
527
|
resourceEditMasthead: true,
|
|
528
|
+
custom: {},
|
|
527
529
|
};
|
|
528
530
|
|
|
529
531
|
return (schemaOrType, pagination) => {
|
|
@@ -1729,6 +1731,8 @@ export const mutations = {
|
|
|
1729
1731
|
let obj = { ...options, match };
|
|
1730
1732
|
|
|
1731
1733
|
if ( idx >= 0 ) {
|
|
1734
|
+
// Merge the custom data object - multiple configures will update existing rather than overwrite
|
|
1735
|
+
obj.custom = Object.assign(state.typeOptions[idx].custom || {}, obj.custom || {});
|
|
1732
1736
|
obj = Object.assign(state.typeOptions[idx], obj);
|
|
1733
1737
|
state.typeOptions.splice(idx, 1, obj);
|
|
1734
1738
|
} else {
|
package/types/shell/index.d.ts
CHANGED
|
@@ -2475,7 +2475,7 @@ export default class Namespace {
|
|
|
2475
2475
|
get isObscure(): any;
|
|
2476
2476
|
get projectId(): any;
|
|
2477
2477
|
get project(): any;
|
|
2478
|
-
get
|
|
2478
|
+
get groupById(): any;
|
|
2479
2479
|
get projectNameSort(): any;
|
|
2480
2480
|
get istioInstalled(): boolean;
|
|
2481
2481
|
get injectionEnabled(): boolean;
|
|
@@ -3498,6 +3498,13 @@ export function abbreviateClusterName(input: string): string;
|
|
|
3498
3498
|
export function labelForAddon(store: any, name: any, configuration?: boolean): any;
|
|
3499
3499
|
export function filterOutDeprecatedPatchVersions(allVersions: any, currentVersion: any): any;
|
|
3500
3500
|
export function getAllOptionsAfterCurrentVersion(store: any, versions: any, currentVersion: any, defaultVersion: any): any;
|
|
3501
|
+
export function initSchedulingCustomization(value: any, features: any, store: any, mode: any): Promise<{
|
|
3502
|
+
clusterAgentDefaultPC: any;
|
|
3503
|
+
clusterAgentDefaultPDB: any;
|
|
3504
|
+
schedulingCustomizationFeatureEnabled: any;
|
|
3505
|
+
schedulingCustomizationOriginallyEnabled: boolean;
|
|
3506
|
+
errors: any[];
|
|
3507
|
+
}>;
|
|
3501
3508
|
}
|
|
3502
3509
|
|
|
3503
3510
|
// @shell/utils/color
|
|
@@ -4361,7 +4368,7 @@ export function random32(count: any): number | number[];
|
|
|
4361
4368
|
export function randomStr(length?: number, chars?: string): any;
|
|
4362
4369
|
export function formatPercent(value: any, maxPrecision?: number): string;
|
|
4363
4370
|
export function pluralize(str: any): any;
|
|
4364
|
-
export function resourceNames(names: any, t: any,
|
|
4371
|
+
export function resourceNames(names: any, plusMore: any, t: any, endString: any): any;
|
|
4365
4372
|
export function indent(lines: any, count?: number, token?: string, afterRegex?: any): any;
|
|
4366
4373
|
export function decamelize(str: any): any;
|
|
4367
4374
|
export function dasherize(str: any): any;
|
|
@@ -81,9 +81,9 @@ describe('fx: resourceNames', () => {
|
|
|
81
81
|
it.each(args)(`having: %p`, (
|
|
82
82
|
names,
|
|
83
83
|
expectation,
|
|
84
|
-
options,
|
|
84
|
+
options: any,
|
|
85
85
|
) => {
|
|
86
|
-
const result = resourceNames(names, t, options);
|
|
86
|
+
const result = resourceNames(names, options.plusMore, t, options.endString);
|
|
87
87
|
|
|
88
88
|
expect(result).toStrictEqual(expectation);
|
|
89
89
|
});
|
package/utils/cluster.js
CHANGED
|
@@ -6,6 +6,10 @@ import { SETTING } from '@shell/config/settings';
|
|
|
6
6
|
import { PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
|
|
7
7
|
import { compare, sortable } from '@shell/utils/version';
|
|
8
8
|
import { sortBy } from '@shell/utils/sort';
|
|
9
|
+
import { SCHEDULING_CUSTOMIZATION } from '@shell/store/features';
|
|
10
|
+
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
11
|
+
import isEmpty from 'lodash/isEmpty';
|
|
12
|
+
import { set } from '@shell/utils/object';
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* Combination of paginationFilterHiddenLocalCluster and paginationFilterOnlyKubernetesClusters
|
|
@@ -296,3 +300,34 @@ export function getAllOptionsAfterCurrentVersion(store, versions, currentVersion
|
|
|
296
300
|
|
|
297
301
|
return sortedWithDeprecatedLabel;
|
|
298
302
|
}
|
|
303
|
+
|
|
304
|
+
export async function initSchedulingCustomization(value, features, store, mode) {
|
|
305
|
+
const schedulingCustomizationFeatureEnabled = features(SCHEDULING_CUSTOMIZATION);
|
|
306
|
+
let clusterAgentDefaultPC = null;
|
|
307
|
+
let clusterAgentDefaultPDB = null;
|
|
308
|
+
let schedulingCustomizationOriginallyEnabled = false;
|
|
309
|
+
const errors = [];
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
clusterAgentDefaultPC = JSON.parse((await store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS })).value) || null;
|
|
313
|
+
} catch (e) {
|
|
314
|
+
errors.push(e);
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
clusterAgentDefaultPDB = JSON.parse((await store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.CLUSTER_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET })).value) || null;
|
|
318
|
+
} catch (e) {
|
|
319
|
+
errors.push(e);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (schedulingCustomizationFeatureEnabled && mode === _CREATE && isEmpty(value?.clusterAgentDeploymentCustomization?.schedulingCustomization)) {
|
|
323
|
+
set(value, 'clusterAgentDeploymentCustomization.schedulingCustomization', { priorityClass: clusterAgentDefaultPC, podDisruptionBudget: clusterAgentDefaultPDB });
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (mode === _EDIT && !!value?.clusterAgentDeploymentCustomization?.schedulingCustomization) {
|
|
327
|
+
schedulingCustomizationOriginallyEnabled = true;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
clusterAgentDefaultPC, clusterAgentDefaultPDB, schedulingCustomizationFeatureEnabled, schedulingCustomizationOriginallyEnabled, errors
|
|
332
|
+
};
|
|
333
|
+
}
|
package/utils/string.js
CHANGED
|
@@ -151,11 +151,9 @@ export function pluralize(str) {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
export function resourceNames(names, t,
|
|
154
|
+
export function resourceNames(names, plusMore, t, endString) {
|
|
155
155
|
const MAX_NAMES_COUNT = 5;
|
|
156
156
|
|
|
157
|
-
let { plusMore, endString } = options;
|
|
158
|
-
|
|
159
157
|
// plusMore default value
|
|
160
158
|
if (!plusMore) {
|
|
161
159
|
plusMore = t('promptRemove.andOthers', { count: names.length > MAX_NAMES_COUNT ? names.length - MAX_NAMES_COUNT : 0 });
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const FIELDS = {
|
|
2
|
+
NAME: 'pool.name',
|
|
3
|
+
QUANTITY: 'pool.quantity'
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const RULESETS = [
|
|
7
|
+
{
|
|
8
|
+
path: FIELDS.QUANTITY,
|
|
9
|
+
rules: ['requiredInt', 'isPositive'],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
path: FIELDS.NAME,
|
|
13
|
+
rules: ['required'],
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export const MACHINE_POOL_VALIDATION = {
|
|
18
|
+
FIELDS,
|
|
19
|
+
RULESETS
|
|
20
|
+
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { BadgeState } from '@components/BadgeState';
|
|
3
|
-
import { stateDisplay } from '@shell/plugins/dashboard-store/resource-class';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
props: {
|
|
7
|
-
value: {
|
|
8
|
-
type: String,
|
|
9
|
-
default: ''
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
components: { BadgeState },
|
|
14
|
-
|
|
15
|
-
data() {
|
|
16
|
-
const STATES = {
|
|
17
|
-
cached: {
|
|
18
|
-
color: 'info', icon: 'dot-open', label: 'Cached', compoundIcon: 'checkmark'
|
|
19
|
-
},
|
|
20
|
-
pending: {
|
|
21
|
-
color: 'warning', icon: 'tag', label: 'In Progress', compoundIcon: 'info'
|
|
22
|
-
},
|
|
23
|
-
disabled: {
|
|
24
|
-
color: 'error', icon: 'dot-half', label: 'Cache Disabled', compoundIcon: 'info'
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
STATES,
|
|
30
|
-
stateDisplay: '',
|
|
31
|
-
stateBackground: ''
|
|
32
|
-
};
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
watch: {
|
|
36
|
-
value: {
|
|
37
|
-
handler() {
|
|
38
|
-
const out = this.value || 'pending';
|
|
39
|
-
const color = this.colorForState(out);
|
|
40
|
-
|
|
41
|
-
this.stateDisplay = stateDisplay(out);
|
|
42
|
-
this.stateBackground = color.replace('text-', 'bg-');
|
|
43
|
-
},
|
|
44
|
-
immediate: true
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
methods: {
|
|
49
|
-
colorForState(state) {
|
|
50
|
-
const key = (state).toLowerCase();
|
|
51
|
-
let color;
|
|
52
|
-
|
|
53
|
-
if ( this.STATES[key] && this.STATES[key].color ) {
|
|
54
|
-
color = this.STATES[key].color;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if ( !color ) {
|
|
58
|
-
color = 'info';
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return `text-${ color }`;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
</script>
|
|
66
|
-
|
|
67
|
-
<template>
|
|
68
|
-
<div>
|
|
69
|
-
<BadgeState
|
|
70
|
-
:color="stateBackground"
|
|
71
|
-
:label="stateDisplay"
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
</template>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
export default {
|
|
3
|
-
props: {
|
|
4
|
-
value: {
|
|
5
|
-
type: Array,
|
|
6
|
-
default: () => []
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
|
-
data() {
|
|
10
|
-
const { hostPort = '', protocol = '' } = this.value[0] || {};
|
|
11
|
-
|
|
12
|
-
return { hostPort, protocol };
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
</script>
|
|
16
|
-
|
|
17
|
-
<template>
|
|
18
|
-
<div v-if="hostPort">
|
|
19
|
-
{{ hostPort+'/'+protocol }}
|
|
20
|
-
</div>
|
|
21
|
-
<div v-else>
|
|
22
|
-
—
|
|
23
|
-
</div>
|
|
24
|
-
</template>
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { SERVICE_ACCOUNT } from '@shell/config/types';
|
|
3
|
-
export default {
|
|
4
|
-
props: {
|
|
5
|
-
value: {
|
|
6
|
-
type: [String, Object],
|
|
7
|
-
default: 'Opaque'
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
data() {
|
|
11
|
-
if (this.value.typeDisplay) {
|
|
12
|
-
this.findServiceAccount();
|
|
13
|
-
|
|
14
|
-
return { typeDisplay: this.value.typeDisplay, serviceAccountLink: null };
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return { typeDisplay: this.value, serviceAccountLink: null };
|
|
18
|
-
},
|
|
19
|
-
methods: {
|
|
20
|
-
async findServiceAccount() {
|
|
21
|
-
const serviceAccount = await this.$store.dispatch('cluster/find', { type: SERVICE_ACCOUNT, id: this.value.serviceAccountID });
|
|
22
|
-
|
|
23
|
-
if (serviceAccount) {
|
|
24
|
-
this.serviceAccountLink = serviceAccount.detailLocation;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
</script>>
|
|
30
|
-
|
|
31
|
-
<template>
|
|
32
|
-
<router-link
|
|
33
|
-
v-if="serviceAccountLink"
|
|
34
|
-
:to="serviceAccountLink"
|
|
35
|
-
>
|
|
36
|
-
{{ typeDisplay }}
|
|
37
|
-
</router-link>
|
|
38
|
-
<div v-else>
|
|
39
|
-
{{ typeDisplay }}
|
|
40
|
-
</div>
|
|
41
|
-
</template>
|