@rancher/shell 3.0.9-rc.5 → 3.0.9-rc.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/images/providers/oci-open-containers.svg +22 -0
- package/assets/images/providers/traefik.png +0 -0
- package/assets/styles/themes/_dark.scss +2 -0
- package/assets/styles/themes/_light.scss +2 -0
- package/assets/styles/themes/_modern.scss +6 -0
- package/assets/translations/en-us.yaml +129 -25
- package/components/CruResource.vue +3 -1
- package/components/ExplorerProjectsNamespaces.vue +12 -12
- package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +109 -0
- package/components/Resource/Detail/Card/StatusCard/index.vue +21 -4
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +19 -2
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +19 -11
- package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +12 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +2 -0
- package/components/Resource/Detail/ResourceRow.vue +2 -2
- package/components/ResourceList/index.vue +7 -4
- package/components/Window/ContainerLogs.vue +48 -37
- package/components/fleet/FleetClusterTargets/TargetsList.vue +2 -2
- package/components/fleet/FleetClusterTargets/index.vue +6 -1
- package/components/fleet/GitRepoAdvancedTab.vue +333 -0
- package/components/fleet/GitRepoMetadataTab.vue +43 -0
- package/components/fleet/GitRepoRepositoryTab.vue +101 -0
- package/components/fleet/GitRepoTargetTab.vue +77 -0
- package/components/fleet/HelmOpAdvancedTab.vue +247 -0
- package/components/fleet/HelmOpChartTab.vue +158 -0
- package/components/fleet/HelmOpMetadataTab.vue +46 -0
- package/components/fleet/HelmOpTargetTab.vue +84 -0
- package/components/fleet/HelmOpValuesTab.vue +147 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +119 -70
- package/components/form/NodeScheduling.vue +81 -7
- package/components/form/PodAffinity.vue +1 -36
- package/components/form/ResourceLabeledSelect.vue +8 -4
- package/components/form/ResourceQuota/Namespace.vue +30 -9
- package/components/form/ResourceQuota/NamespaceRow.vue +25 -7
- package/components/form/ResourceQuota/Project.vue +140 -82
- package/components/form/ResourceQuota/ResourceQuotaEntry.vue +145 -0
- package/components/form/ResourceQuota/__tests__/Namespace.test.ts +307 -0
- package/components/form/ResourceQuota/__tests__/NamespaceRow.test.ts +281 -0
- package/components/form/ResourceQuota/__tests__/Project.test.ts +274 -27
- package/components/form/ResourceQuota/__tests__/ResourceQuotaEntry.test.ts +215 -0
- package/components/form/SchedulingCustomization.vue +14 -6
- package/components/form/SelectOrCreateAuthSecret.vue +107 -18
- package/components/form/__tests__/NodeScheduling.test.ts +12 -9
- package/components/form/__tests__/PodAffinity.test.ts +21 -2
- package/components/form/__tests__/SchedulingCustomization.test.ts +240 -0
- package/components/formatter/ClusterLink.vue +8 -0
- package/components/formatter/SecretOrigin.vue +79 -0
- package/config/labels-annotations.js +7 -6
- package/config/pagination-table-headers.js +6 -4
- package/config/product/explorer.js +1 -11
- package/config/query-params.js +3 -0
- package/config/settings.ts +15 -2
- package/config/table-headers.js +21 -17
- package/config/types.js +23 -8
- package/detail/workload/index.vue +11 -16
- package/dialog/DeactivateDriverDialog.vue +1 -1
- package/dialog/Ipv6NetworkingDialog.vue +156 -0
- package/dialog/ScalePoolDownDialog.vue +2 -2
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +1 -0
- package/edit/__tests__/management.cattle.io.project.test.js +56 -128
- package/edit/auth/oidc.vue +1 -1
- package/edit/catalog.cattle.io.clusterrepo.vue +155 -25
- package/edit/fleet.cattle.io.gitrepo.vue +153 -283
- package/edit/fleet.cattle.io.helmop.vue +190 -332
- package/edit/management.cattle.io.project.vue +5 -42
- package/edit/management.cattle.io.setting.vue +6 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +55 -24
- package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +1 -103
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +13 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2-fleet-cluster-agent.test.ts +283 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +65 -49
- package/edit/provisioning.cattle.io.cluster/ingress/IngressCards.vue +112 -0
- package/edit/provisioning.cattle.io.cluster/ingress/IngressConfiguration.vue +158 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -72
- package/edit/provisioning.cattle.io.cluster/shared.ts +36 -1
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +55 -7
- package/edit/provisioning.cattle.io.cluster/tabs/Ingress.vue +319 -0
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/__tests__/S3Config.test.ts +13 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +10 -44
- package/edit/secret/index.vue +1 -1
- package/edit/token.vue +68 -29
- package/edit/workload/__tests__/index.test.ts +2 -37
- package/edit/workload/index.vue +6 -2
- package/edit/workload/mixins/workload.js +0 -32
- package/list/__tests__/management.cattle.io.setting.test.ts +198 -0
- package/list/management.cattle.io.setting.vue +13 -0
- package/list/provisioning.cattle.io.cluster.vue +50 -1
- package/list/secret.vue +4 -9
- package/list/service.vue +6 -8
- package/machine-config/amazonec2.vue +11 -4
- package/machine-config/components/EC2Networking.vue +46 -30
- package/machine-config/components/__tests__/EC2Networking.test.ts +7 -7
- package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +0 -9
- package/machine-config/digitalocean.vue +3 -3
- package/models/__tests__/namespace.test.ts +11 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +96 -0
- package/models/__tests__/workload.test.ts +42 -1
- package/models/catalog.cattle.io.clusterrepo.js +30 -4
- package/models/ext.cattle.io.token.js +48 -0
- package/models/kontainerdriver.js +2 -2
- package/models/namespace.js +7 -1
- package/models/nodedriver.js +2 -2
- package/models/provisioning.cattle.io.cluster.js +28 -7
- package/models/secret.js +0 -17
- package/models/service.js +44 -1
- package/models/token.js +4 -0
- package/models/workload.js +12 -6
- package/package.json +1 -1
- package/pages/account/index.vue +96 -67
- package/pages/auth/setup.vue +5 -14
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +4 -1
- package/pages/c/_cluster/apps/charts/index.vue +93 -4
- package/pages/c/_cluster/apps/charts/install.vue +317 -42
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -4
- package/pages/c/_cluster/settings/index.vue +3 -1
- package/plugins/dashboard-store/__tests__/getters.test.ts +108 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +27 -0
- package/plugins/dashboard-store/actions.js +3 -8
- package/plugins/dashboard-store/getters.js +7 -5
- package/plugins/dashboard-store/mutations.js +4 -1
- package/plugins/dashboard-store/resource-class.js +3 -3
- package/plugins/steve/__tests__/steve-class.test.ts +102 -141
- package/plugins/steve/steve-class.js +12 -3
- package/plugins/steve/steve-pagination-utils.ts +6 -2
- package/rancher-components/RcIcon/types.ts +2 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +64 -19
- package/store/prefs.js +3 -0
- package/types/aws-sdk.d.ts +121 -0
- package/types/resources/node.ts +15 -0
- package/types/shell/index.d.ts +536 -506
- package/types/store/pagination.types.ts +5 -5
- package/utils/__tests__/array.test.ts +1 -29
- package/utils/__tests__/cluster-agent-configuration.test.ts +203 -0
- package/utils/array.ts +0 -11
- package/utils/aws.ts +21 -0
- package/utils/cluster.js +22 -2
- package/utils/selector-typed.ts +1 -1
- package/components/__tests__/ProjectRow.test.ts +0 -206
- package/components/form/ResourceQuota/ProjectRow.vue +0 -277
|
@@ -68,6 +68,8 @@ describe('component: Workload', () => {
|
|
|
68
68
|
$store: {
|
|
69
69
|
getters: {
|
|
70
70
|
'cluster/schemaFor': jest.fn(),
|
|
71
|
+
'cluster/canList': jest.fn(),
|
|
72
|
+
currentStore: () => 'cluster',
|
|
71
73
|
'type-map/labelFor': jest.fn(),
|
|
72
74
|
'i18n/t': (text: string, v: {[key:string]: string}) => {
|
|
73
75
|
return `${ text }, ${ Object.values(v || {}) }`;
|
|
@@ -99,42 +101,5 @@ describe('component: Workload', () => {
|
|
|
99
101
|
|
|
100
102
|
expect(result).toStrictEqual(newMessage);
|
|
101
103
|
});
|
|
102
|
-
|
|
103
|
-
describe('secondaryResourceDataConfig', () => {
|
|
104
|
-
it('should filter out nodes with control-plane or etcd taints from workerNodes parsingFunc', () => {
|
|
105
|
-
const allNodeObjects = [
|
|
106
|
-
{
|
|
107
|
-
id: 'node-1',
|
|
108
|
-
spec: { taints: [{ key: 'node-role.kubernetes.io/control-plane', effect: 'NoSchedule' }] }
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
id: 'node-2',
|
|
112
|
-
spec: { taints: [{ key: 'node-role.kubernetes.io/etcd', effect: 'NoSchedule' }] }
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
id: 'node-3',
|
|
116
|
-
spec: { taints: [{ key: 'node-role.kubernetes.io/worker', effect: 'NoSchedule' }] }
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
id: 'node-4',
|
|
120
|
-
spec: { taints: [] }
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
id: 'node-5',
|
|
124
|
-
spec: {}
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
id: 'node-6',
|
|
128
|
-
spec: null
|
|
129
|
-
}
|
|
130
|
-
];
|
|
131
|
-
|
|
132
|
-
const { data } = (Workload.mixins[2] as any).methods.secondaryResourceDataConfig.apply({ value: { metadata: { namespace: 'test' } } });
|
|
133
|
-
const workerNodesParsingFunc = data.node.applyTo.find((r: any) => r.var === 'workerNodes').parsingFunc;
|
|
134
|
-
const result = workerNodesParsingFunc(allNodeObjects);
|
|
135
|
-
|
|
136
|
-
expect(result).toStrictEqual(['node-3', 'node-4', 'node-5', 'node-6']);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
104
|
});
|
|
140
105
|
});
|
package/edit/workload/index.vue
CHANGED
|
@@ -4,6 +4,7 @@ import FormValidation from '@shell/mixins/form-validation';
|
|
|
4
4
|
import WorkLoadMixin from '@shell/edit/workload/mixins/workload';
|
|
5
5
|
import { mapGetters } from 'vuex';
|
|
6
6
|
import { FORM_TYPES } from '@shell/components/form/Security';
|
|
7
|
+
import { NODE } from '@shell/config/types';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
name: 'Workload',
|
|
@@ -21,9 +22,13 @@ export default {
|
|
|
21
22
|
},
|
|
22
23
|
},
|
|
23
24
|
data() {
|
|
25
|
+
const inStore = this.$store.getters['currentStore'](NODE);
|
|
26
|
+
const canNode = this.$store.getters[`${ inStore }/canList`](NODE);
|
|
27
|
+
|
|
24
28
|
return {
|
|
25
29
|
selectedName: null,
|
|
26
30
|
errors: [],
|
|
31
|
+
canNode,
|
|
27
32
|
FORM_TYPES
|
|
28
33
|
};
|
|
29
34
|
},
|
|
@@ -506,11 +511,11 @@ export default {
|
|
|
506
511
|
<PodAffinity
|
|
507
512
|
:mode="mode"
|
|
508
513
|
:value="podTemplateSpec"
|
|
509
|
-
:nodes="allNodeObjects"
|
|
510
514
|
:loading="isLoadingSecondaryResources"
|
|
511
515
|
/>
|
|
512
516
|
</Tab>
|
|
513
517
|
<Tab
|
|
518
|
+
v-if="canNode"
|
|
514
519
|
:label="t('workload.container.titles.nodeScheduling')"
|
|
515
520
|
name="nodeScheduling-pod"
|
|
516
521
|
:weight="tabWeightMap['nodeScheduling']"
|
|
@@ -518,7 +523,6 @@ export default {
|
|
|
518
523
|
<NodeScheduling
|
|
519
524
|
:mode="mode"
|
|
520
525
|
:value="podTemplateSpec"
|
|
521
|
-
:nodes="workerNodes"
|
|
522
526
|
:loading="isLoadingSecondaryResources"
|
|
523
527
|
/>
|
|
524
528
|
</Tab>
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
CONFIG_MAP,
|
|
6
6
|
SECRET,
|
|
7
7
|
WORKLOAD_TYPES,
|
|
8
|
-
NODE,
|
|
9
8
|
SERVICE,
|
|
10
9
|
PVC,
|
|
11
10
|
SERVICE_ACCOUNT,
|
|
@@ -263,9 +262,6 @@ export default {
|
|
|
263
262
|
return {
|
|
264
263
|
secondaryResourceData: this.secondaryResourceDataConfig(),
|
|
265
264
|
namespacedConfigMaps: [],
|
|
266
|
-
allNodes: null,
|
|
267
|
-
workerNodes: null,
|
|
268
|
-
allNodeObjects: [],
|
|
269
265
|
namespacedSecrets: [],
|
|
270
266
|
imagePullNamespacedSecrets: [],
|
|
271
267
|
allServices: [],
|
|
@@ -690,34 +686,6 @@ export default {
|
|
|
690
686
|
}
|
|
691
687
|
]
|
|
692
688
|
},
|
|
693
|
-
[NODE]: {
|
|
694
|
-
applyTo: [
|
|
695
|
-
{ var: 'allNodeObjects' },
|
|
696
|
-
{
|
|
697
|
-
var: 'allNodes',
|
|
698
|
-
parsingFunc: (data) => {
|
|
699
|
-
return data.map((node) => node.id);
|
|
700
|
-
}
|
|
701
|
-
},
|
|
702
|
-
{
|
|
703
|
-
var: 'workerNodes',
|
|
704
|
-
parsingFunc: (data) => {
|
|
705
|
-
const keys = [
|
|
706
|
-
`node-role.kubernetes.io/control-plane`,
|
|
707
|
-
`node-role.kubernetes.io/etcd`
|
|
708
|
-
];
|
|
709
|
-
|
|
710
|
-
return data
|
|
711
|
-
.filter((node) => {
|
|
712
|
-
const taints = node?.spec?.taints || [];
|
|
713
|
-
|
|
714
|
-
return taints.every((taint) => !keys.includes(taint.key));
|
|
715
|
-
})
|
|
716
|
-
.map((node) => node.id);
|
|
717
|
-
}
|
|
718
|
-
},
|
|
719
|
-
]
|
|
720
|
-
},
|
|
721
689
|
[SERVICE]: {
|
|
722
690
|
applyTo: [
|
|
723
691
|
{ var: 'allServices' },
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { nextTick } from 'vue';
|
|
3
|
+
import ManagementSetting from '@shell/list/management.cattle.io.setting.vue';
|
|
4
|
+
import { SETTING } from '@shell/config/settings';
|
|
5
|
+
|
|
6
|
+
const mockStore = {
|
|
7
|
+
getters: {
|
|
8
|
+
'prefs/get': () => false,
|
|
9
|
+
'i18n/t': (key: string) => key,
|
|
10
|
+
},
|
|
11
|
+
dispatch: jest.fn()
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const mockRoute = {
|
|
15
|
+
hash: '',
|
|
16
|
+
params: {}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const mockRouter = {
|
|
20
|
+
push: jest.fn(),
|
|
21
|
+
replace: jest.fn()
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Mock scrollIntoView
|
|
25
|
+
const mockScrollIntoView = jest.fn();
|
|
26
|
+
|
|
27
|
+
Object.defineProperty(Element.prototype, 'scrollIntoView', {
|
|
28
|
+
value: mockScrollIntoView,
|
|
29
|
+
writable: true
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Mock querySelector
|
|
33
|
+
const mockQuerySelector = jest.fn();
|
|
34
|
+
|
|
35
|
+
Object.defineProperty(document, 'querySelector', {
|
|
36
|
+
value: mockQuerySelector,
|
|
37
|
+
writable: true
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('managementSetting - Scroll Behavior', () => {
|
|
41
|
+
let wrapper: any;
|
|
42
|
+
|
|
43
|
+
const createWrapper = (routeHash = '') => {
|
|
44
|
+
const route = { ...mockRoute, hash: routeHash };
|
|
45
|
+
|
|
46
|
+
return mount(ManagementSetting, {
|
|
47
|
+
global: {
|
|
48
|
+
mocks: {
|
|
49
|
+
$store: mockStore,
|
|
50
|
+
$route: route,
|
|
51
|
+
$router: mockRouter,
|
|
52
|
+
$fetchState: { pending: false }
|
|
53
|
+
},
|
|
54
|
+
stubs: {
|
|
55
|
+
Loading: true,
|
|
56
|
+
Banner: true,
|
|
57
|
+
Setting: true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
jest.clearAllMocks();
|
|
65
|
+
mockScrollIntoView.mockClear();
|
|
66
|
+
mockQuerySelector.mockClear();
|
|
67
|
+
|
|
68
|
+
// Mock successful API response with cluster agent setting
|
|
69
|
+
mockStore.dispatch.mockResolvedValue([
|
|
70
|
+
{
|
|
71
|
+
id: SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS,
|
|
72
|
+
value: '{"enabled": true}',
|
|
73
|
+
default: '{"enabled": false}',
|
|
74
|
+
availableActions: ['edit']
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: SETTING.FLEET_AGENT_DEFAULT_PRIORITY_CLASS,
|
|
78
|
+
value: '{"enabled": true}',
|
|
79
|
+
default: '{"enabled": false}',
|
|
80
|
+
availableActions: ['edit']
|
|
81
|
+
}
|
|
82
|
+
]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterEach(() => {
|
|
86
|
+
if (wrapper) {
|
|
87
|
+
wrapper.unmount();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should scroll to hash anchor after data is loaded', async() => {
|
|
92
|
+
const mockElement = document.createElement('div');
|
|
93
|
+
|
|
94
|
+
mockQuerySelector.mockReturnValue(mockElement);
|
|
95
|
+
|
|
96
|
+
wrapper = createWrapper('#cluster-agent-default-priority-class');
|
|
97
|
+
|
|
98
|
+
// Trigger fetch manually since we can't easily test the async fetch hook
|
|
99
|
+
await wrapper.vm.$options.fetch.call(wrapper.vm);
|
|
100
|
+
await nextTick();
|
|
101
|
+
|
|
102
|
+
expect(mockQuerySelector).toHaveBeenCalledWith('#cluster-agent-default-priority-class');
|
|
103
|
+
expect(mockScrollIntoView).toHaveBeenCalledWith({
|
|
104
|
+
behavior: 'smooth',
|
|
105
|
+
block: 'start'
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should not scroll if hash is empty', async() => {
|
|
110
|
+
wrapper = createWrapper('');
|
|
111
|
+
|
|
112
|
+
await wrapper.vm.$options.fetch.call(wrapper.vm);
|
|
113
|
+
await nextTick();
|
|
114
|
+
|
|
115
|
+
expect(mockQuerySelector).not.toHaveBeenCalled();
|
|
116
|
+
expect(mockScrollIntoView).not.toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should not scroll if element is not found', async() => {
|
|
120
|
+
mockQuerySelector.mockReturnValue(null);
|
|
121
|
+
|
|
122
|
+
wrapper = createWrapper('#non-existent-element');
|
|
123
|
+
|
|
124
|
+
await wrapper.vm.$options.fetch.call(wrapper.vm);
|
|
125
|
+
await nextTick();
|
|
126
|
+
|
|
127
|
+
expect(mockQuerySelector).toHaveBeenCalledWith('#non-existent-element');
|
|
128
|
+
expect(mockScrollIntoView).not.toHaveBeenCalled();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should scroll to fleet agent setting hash', async() => {
|
|
132
|
+
const mockElement = document.createElement('div');
|
|
133
|
+
|
|
134
|
+
mockQuerySelector.mockReturnValue(mockElement);
|
|
135
|
+
|
|
136
|
+
wrapper = createWrapper('#fleet-agent-default-priority-class');
|
|
137
|
+
|
|
138
|
+
await wrapper.vm.$options.fetch.call(wrapper.vm);
|
|
139
|
+
await nextTick();
|
|
140
|
+
|
|
141
|
+
expect(mockQuerySelector).toHaveBeenCalledWith('#fleet-agent-default-priority-class');
|
|
142
|
+
expect(mockScrollIntoView).toHaveBeenCalledWith({
|
|
143
|
+
behavior: 'smooth',
|
|
144
|
+
block: 'start'
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should handle hash with special characters', async() => {
|
|
149
|
+
const mockElement = document.createElement('div');
|
|
150
|
+
|
|
151
|
+
mockQuerySelector.mockReturnValue(mockElement);
|
|
152
|
+
|
|
153
|
+
wrapper = createWrapper('#setting-with-special-chars_123');
|
|
154
|
+
|
|
155
|
+
await wrapper.vm.$options.fetch.call(wrapper.vm);
|
|
156
|
+
await nextTick();
|
|
157
|
+
|
|
158
|
+
expect(mockQuerySelector).toHaveBeenCalledWith('#setting-with-special-chars_123');
|
|
159
|
+
expect(mockScrollIntoView).toHaveBeenCalledWith({
|
|
160
|
+
behavior: 'smooth',
|
|
161
|
+
block: 'start'
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should render settings with correct IDs for anchors', async() => {
|
|
166
|
+
wrapper = createWrapper();
|
|
167
|
+
|
|
168
|
+
// Manually set the data to simulate successful fetch
|
|
169
|
+
wrapper.vm.settings = [
|
|
170
|
+
{
|
|
171
|
+
id: SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS,
|
|
172
|
+
description: 'test-description',
|
|
173
|
+
data: { value: 'test' },
|
|
174
|
+
customized: false,
|
|
175
|
+
fromEnv: false,
|
|
176
|
+
hasActions: true
|
|
177
|
+
}
|
|
178
|
+
];
|
|
179
|
+
wrapper.vm.provisioningSettings = [
|
|
180
|
+
{
|
|
181
|
+
id: SETTING.FLEET_AGENT_DEFAULT_PRIORITY_CLASS,
|
|
182
|
+
description: 'test-description',
|
|
183
|
+
data: { value: 'test' },
|
|
184
|
+
customized: false,
|
|
185
|
+
fromEnv: false,
|
|
186
|
+
hasActions: true
|
|
187
|
+
}
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
await nextTick();
|
|
191
|
+
|
|
192
|
+
const settingDivs = wrapper.findAll('div[id]');
|
|
193
|
+
const ids = settingDivs.map((div: any) => div.attributes('id'));
|
|
194
|
+
|
|
195
|
+
expect(ids).toContain(SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS);
|
|
196
|
+
expect(ids).toContain(SETTING.FLEET_AGENT_DEFAULT_PRIORITY_CLASS);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
@@ -66,6 +66,17 @@ export default {
|
|
|
66
66
|
|
|
67
67
|
this.settings = settings;
|
|
68
68
|
this.provisioningSettings = provisioningSettings;
|
|
69
|
+
|
|
70
|
+
this.$nextTick(() => {
|
|
71
|
+
// Handle scrolling to hash anchor after data is loaded
|
|
72
|
+
if (this.$route.hash) {
|
|
73
|
+
const element = document.querySelector(this.$route.hash);
|
|
74
|
+
|
|
75
|
+
if (element) {
|
|
76
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
69
80
|
},
|
|
70
81
|
|
|
71
82
|
data() {
|
|
@@ -89,6 +100,7 @@ export default {
|
|
|
89
100
|
</Banner>
|
|
90
101
|
<div
|
|
91
102
|
v-for="(setting) in settings"
|
|
103
|
+
:id="setting.id"
|
|
92
104
|
:key="setting.id"
|
|
93
105
|
>
|
|
94
106
|
<Setting
|
|
@@ -101,6 +113,7 @@ export default {
|
|
|
101
113
|
</h2>
|
|
102
114
|
<div
|
|
103
115
|
v-for="(setting) in provisioningSettings"
|
|
116
|
+
:id="setting.id"
|
|
104
117
|
:key="setting.id"
|
|
105
118
|
>
|
|
106
119
|
<Setting
|
|
@@ -167,6 +167,12 @@ export default {
|
|
|
167
167
|
|
|
168
168
|
},
|
|
169
169
|
|
|
170
|
+
methods: {
|
|
171
|
+
getCustomDetailLink(cluster) {
|
|
172
|
+
return cluster.isCapiHybrid ? null : cluster.detailLocation;
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
|
|
170
176
|
$loadingResources() {
|
|
171
177
|
// results are filtered so we wouldn't get the correct count on indicator...
|
|
172
178
|
return { loadIndeterminate: true };
|
|
@@ -211,7 +217,6 @@ export default {
|
|
|
211
217
|
</router-link>
|
|
212
218
|
</template>
|
|
213
219
|
</Masthead>
|
|
214
|
-
|
|
215
220
|
<ResourceTable
|
|
216
221
|
:headers="headers"
|
|
217
222
|
:table-actions="true"
|
|
@@ -221,6 +226,8 @@ export default {
|
|
|
221
226
|
:use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
|
|
222
227
|
:data-testid="'cluster-list'"
|
|
223
228
|
:force-update-live-and-delayed="forceUpdateLiveAndDelayed"
|
|
229
|
+
:get-custom-detail-link="getCustomDetailLink"
|
|
230
|
+
:sub-rows="true"
|
|
224
231
|
>
|
|
225
232
|
<!-- Why are state column and subrow overwritten here? -->
|
|
226
233
|
<!-- for rke1 clusters, where they try to use the mgmt cluster stateObj instead of prov cluster stateObj, -->
|
|
@@ -266,6 +273,48 @@ export default {
|
|
|
266
273
|
{{ t('cluster.explore') }}
|
|
267
274
|
</button>
|
|
268
275
|
</template>
|
|
276
|
+
<template #additional-sub-row="{row, fullColspan, tableActions}">
|
|
277
|
+
<tr
|
|
278
|
+
class="capi-unsupported"
|
|
279
|
+
:class="{'has-description': !!row.stateDescription}"
|
|
280
|
+
>
|
|
281
|
+
<td
|
|
282
|
+
v-if="row.isCapiHybrid"
|
|
283
|
+
class="row-check"
|
|
284
|
+
/>
|
|
285
|
+
<td
|
|
286
|
+
v-if="row.isCapiHybrid"
|
|
287
|
+
:data-testid="`capi-unsupported-warning-${row?.metadata?.name}`"
|
|
288
|
+
:colspan="fullColspan - (tableActions ? 1: 0)"
|
|
289
|
+
>
|
|
290
|
+
<div
|
|
291
|
+
class="text-warning"
|
|
292
|
+
:class="{'mt-5': !!row.stateDescription.trim()}"
|
|
293
|
+
>
|
|
294
|
+
<i class="icon icon-warning" />{{ t('cluster.capi.notSupported') }}
|
|
295
|
+
</div>
|
|
296
|
+
</td>
|
|
297
|
+
</tr>
|
|
298
|
+
</template>
|
|
269
299
|
</ResourceTable>
|
|
270
300
|
</div>
|
|
271
301
|
</template>
|
|
302
|
+
|
|
303
|
+
<stye scoped lang="scss">
|
|
304
|
+
.capi-unsupported {
|
|
305
|
+
&.has-description {
|
|
306
|
+
border-bottom: none;
|
|
307
|
+
padding: 0px;
|
|
308
|
+
td {
|
|
309
|
+
padding-top: 0px;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
& div {
|
|
314
|
+
& i {
|
|
315
|
+
margin-right: 0.1em;
|
|
316
|
+
}
|
|
317
|
+
display: flex;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
</stye>
|
package/list/secret.vue
CHANGED
|
@@ -7,8 +7,8 @@ import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
|
|
|
7
7
|
import { TableColumn } from '@shell/types/store/type-map';
|
|
8
8
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
9
9
|
import { mapGetters } from 'vuex';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { SECRET_ORIGIN } from '@shell/config/table-headers';
|
|
11
|
+
import { STEVE_SECRET_ORIGIN } from '@shell/config/pagination-table-headers';
|
|
12
12
|
|
|
13
13
|
export default {
|
|
14
14
|
name: 'ListSecret',
|
|
@@ -61,13 +61,8 @@ export default {
|
|
|
61
61
|
|
|
62
62
|
if (this.canViewProjects) {
|
|
63
63
|
// if the user can see projects, add a column to let them know if it's a secret from a project scoped secret
|
|
64
|
-
headers.push(
|
|
65
|
-
headersSSP.push(
|
|
66
|
-
if (this.currentCluster.isLocal) {
|
|
67
|
-
// if the user is on the local cluster, add a column to let them know if it's a project scoped secret (from another cluster)
|
|
68
|
-
headers.push(SECRET_PROJECT_SCOPED);
|
|
69
|
-
headersSSP.push(SECRET_PROJECT_SCOPED);
|
|
70
|
-
}
|
|
64
|
+
headers.push(SECRET_ORIGIN);
|
|
65
|
+
headersSSP.push(STEVE_SECRET_ORIGIN);
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
headers.push(this.namespacedHeaders[this.namespacedHeaders.length - 1]);
|
package/list/service.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
|
|
3
|
-
import {
|
|
3
|
+
import { fetchNodesForServiceTargets } from '@shell/models/service';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
name: 'ListService',
|
|
@@ -27,13 +27,11 @@ export default {
|
|
|
27
27
|
* of type PagTableFetchSecondaryResources
|
|
28
28
|
*/
|
|
29
29
|
async fetchSecondaryResources(opts) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await this.$store.dispatch(`${ inStore }/findAll`, { type: NODE });
|
|
36
|
-
}
|
|
30
|
+
// Nodes should be fetched because they may be referenced in the target column of a service list item.
|
|
31
|
+
await fetchNodesForServiceTargets({
|
|
32
|
+
$store: this.$store,
|
|
33
|
+
inStore: this.$store.getters['currentStore']()
|
|
34
|
+
});
|
|
37
35
|
}
|
|
38
36
|
}
|
|
39
37
|
};
|
|
@@ -24,7 +24,7 @@ export default {
|
|
|
24
24
|
|
|
25
25
|
mixins: [CreateEditView],
|
|
26
26
|
|
|
27
|
-
emits: ['validationChanged', 'update:
|
|
27
|
+
emits: ['validationChanged', 'update:isIpv6', 'update:isDualStack'],
|
|
28
28
|
|
|
29
29
|
props: {
|
|
30
30
|
uuid: {
|
|
@@ -47,7 +47,12 @@ export default {
|
|
|
47
47
|
default: false
|
|
48
48
|
},
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
isIpv6: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
isDualStack: {
|
|
51
56
|
type: Boolean,
|
|
52
57
|
default: false
|
|
53
58
|
},
|
|
@@ -386,10 +391,12 @@ export default {
|
|
|
386
391
|
:zone="value.zone"
|
|
387
392
|
:region="value.region"
|
|
388
393
|
:machine-pools="machinePools"
|
|
389
|
-
:
|
|
394
|
+
:is-ipv6="isIpv6"
|
|
395
|
+
:is-dual-stack="isDualStack"
|
|
390
396
|
:disabled="disabled"
|
|
391
397
|
:is-new="poolCreateMode"
|
|
392
|
-
@update:
|
|
398
|
+
@update:is-ipv6="e=>$emit('update:isIpv6', e)"
|
|
399
|
+
@update:is-dual-stack="e=>$emit('update:isDualStack', e)"
|
|
393
400
|
@validation-changed="e=>$emit('validationChanged',e)"
|
|
394
401
|
/>
|
|
395
402
|
|