@rancher/shell 3.0.1 → 3.0.2-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 +17 -5
- package/assets/styles/base/_mixins.scss +2 -1
- package/assets/styles/global/_button.scss +10 -0
- package/assets/styles/global/_form.scss +2 -2
- package/assets/translations/en-us.yaml +33 -5
- package/assets/translations/zh-hans.yaml +1 -1
- package/components/ActionMenu.vue +8 -0
- package/components/AsyncButton.vue +9 -3
- package/components/BannerGraphic.vue +10 -0
- package/components/ButtonGroup.vue +2 -0
- package/components/ButtonMultiAction.vue +6 -0
- package/components/ClusterIconMenu.vue +1 -1
- package/components/CodeMirror.vue +28 -1
- package/components/CommunityLinks.vue +13 -0
- package/components/CruResource.vue +6 -0
- package/components/GrowlManager.vue +14 -4
- package/components/LocaleSelector.vue +49 -5
- package/components/PaginatedResourceTable.vue +4 -3
- package/components/ResourceDetail/Masthead.vue +11 -4
- package/components/ResourceList/index.vue +5 -3
- package/components/ResourceTable.vue +1 -1
- package/components/SortableTable/THead.vue +19 -4
- package/components/SortableTable/index.vue +13 -9
- package/components/SortableTable/selection.js +19 -5
- package/components/YamlEditor.vue +2 -1
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetBundles.vue +2 -1
- package/components/form/LabeledSelect.vue +20 -7
- package/components/form/NodeScheduling.vue +5 -1
- package/components/form/Password.vue +23 -13
- package/components/form/ResourceLabeledSelect.vue +1 -1
- package/components/form/Select.vue +28 -6
- package/components/form/SelectOrCreateAuthSecret.vue +39 -11
- package/components/form/__tests__/NodeScheduling.test.ts +44 -0
- package/components/formatter/Endpoints.vue +1 -1
- package/components/formatter/LiveExpiryDate.vue +5 -1
- package/components/formatter/ServiceTargets.vue +1 -1
- package/components/formatter/ServiceType.vue +19 -17
- package/components/nav/Pinned.vue +6 -1
- package/components/nav/TopLevelMenu.helper.ts +17 -1
- package/components/nav/TopLevelMenu.vue +154 -19
- package/config/pagination-table-headers.js +9 -1
- package/config/product/apps.js +63 -30
- package/config/product/explorer.js +182 -17
- package/config/product/settings.js +9 -1
- package/config/router/routes.js +0 -1
- package/config/settings.ts +20 -2
- package/config/table-headers.js +23 -15
- package/config/types.js +2 -1
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +12 -3
- package/edit/fleet.cattle.io.gitrepo.vue +40 -33
- package/edit/provisioning.cattle.io.cluster/rke2.vue +13 -2
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +10 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +6 -3
- package/edit/workload/mixins/workload.js +15 -7
- package/list/catalog.cattle.io.app.vue +4 -11
- package/list/catalog.cattle.io.clusterrepo.vue +59 -25
- package/list/fleet.cattle.io.bundle.vue +2 -2
- package/list/management.cattle.io.feature.vue +12 -5
- package/list/management.cattle.io.setting.vue +30 -19
- package/list/namespace.vue +4 -1
- package/list/networking.k8s.io.ingress.vue +14 -11
- package/list/node.vue +65 -63
- package/list/persistentvolume.vue +55 -20
- package/list/persistentvolumeclaim.vue +3 -15
- package/list/service.vue +16 -21
- package/list/workload.vue +35 -49
- package/mixins/resource-fetch.js +8 -1
- package/mixins/vue-select-overrides.js +10 -16
- package/models/management.cattle.io.cluster.js +6 -1
- package/models/persistentvolume.js +1 -3
- package/models/storage.k8s.io.storageclass.js +4 -0
- package/package.json +28 -29
- package/pages/c/_cluster/explorer/EventsTable.vue +58 -16
- package/pages/c/_cluster/explorer/index.vue +3 -16
- package/pages/c/_cluster/settings/performance.vue +49 -23
- package/pages/home.vue +24 -3
- package/pages/support/index.vue +1 -1
- package/plugins/floating-vue.js +1 -1
- package/plugins/steve/steve-pagination-utils.ts +85 -15
- package/rancher-components/Banner/Banner.vue +12 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -5
- package/rancher-components/Form/Radio/RadioButton.vue +0 -6
- package/rancher-components/Form/Radio/RadioGroup.vue +5 -1
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +2 -2
- package/scripts/test-plugins-build.sh +21 -6
- package/scripts/typegen.sh +1 -0
- package/store/index.js +16 -0
- package/store/type-map.utils.ts +14 -1
- package/types/shell/index.d.ts +467 -418
- package/types/store/vuex.d.ts +1 -1
- package/types/vue-shim.d.ts +2 -8
- package/utils/cluster.js +2 -2
- package/utils/string.js +6 -0
- package/vue.config.js +3 -4
|
@@ -86,9 +86,7 @@ export default {
|
|
|
86
86
|
|
|
87
87
|
this.tlsMode = tls;
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
this.value.spec['correctDrift'] = { enabled: false };
|
|
91
|
-
}
|
|
89
|
+
this.correctDriftEnabled = this.value.spec?.correctDrift?.enabled || false;
|
|
92
90
|
|
|
93
91
|
this.updateTargets();
|
|
94
92
|
},
|
|
@@ -119,7 +117,7 @@ export default {
|
|
|
119
117
|
subtext: this.t('fleet.gitRepo.add.steps.repoInfo.subtext'),
|
|
120
118
|
descriptionKey: 'fleet.gitRepo.add.steps.repoInfo.description',
|
|
121
119
|
ready: false,
|
|
122
|
-
weight:
|
|
120
|
+
weight: 1
|
|
123
121
|
};
|
|
124
122
|
|
|
125
123
|
const stepTargetInfo = {
|
|
@@ -129,11 +127,9 @@ export default {
|
|
|
129
127
|
subtext: this.t('fleet.gitRepo.add.steps.targetInfo.subtext'),
|
|
130
128
|
descriptionKey: 'fleet.gitRepo.steps.add.targetInfo.description',
|
|
131
129
|
ready: true,
|
|
132
|
-
weight:
|
|
130
|
+
weight: 1
|
|
133
131
|
};
|
|
134
132
|
|
|
135
|
-
const addRepositorySteps = [stepRepoInfo, stepTargetInfo].sort((a, b) => (b.weight || 0) - (a.weight || 0));
|
|
136
|
-
|
|
137
133
|
return {
|
|
138
134
|
allClusters: [],
|
|
139
135
|
allClusterGroups: [],
|
|
@@ -145,6 +141,7 @@ export default {
|
|
|
145
141
|
privateKey: null,
|
|
146
142
|
tlsMode: null,
|
|
147
143
|
caBundle: null,
|
|
144
|
+
correctDriftEnabled: false,
|
|
148
145
|
targetAdvancedErrors: null,
|
|
149
146
|
matchingClusters: null,
|
|
150
147
|
ref,
|
|
@@ -155,7 +152,6 @@ export default {
|
|
|
155
152
|
targetAdvanced,
|
|
156
153
|
stepRepoInfo,
|
|
157
154
|
stepTargetInfo,
|
|
158
|
-
addRepositorySteps,
|
|
159
155
|
displayHelmRepoURLRegex: false,
|
|
160
156
|
fvFormRuleSets: [{ path: 'spec.repo', rules: ['required'] }]
|
|
161
157
|
};
|
|
@@ -168,6 +164,13 @@ export default {
|
|
|
168
164
|
return _SPECIFY;
|
|
169
165
|
},
|
|
170
166
|
|
|
167
|
+
steps() {
|
|
168
|
+
return [
|
|
169
|
+
this.stepRepoInfo,
|
|
170
|
+
this.stepTargetInfo
|
|
171
|
+
];
|
|
172
|
+
},
|
|
173
|
+
|
|
171
174
|
isLocal() {
|
|
172
175
|
return this.value.metadata.namespace === 'fleet-local';
|
|
173
176
|
},
|
|
@@ -463,7 +466,7 @@ export default {
|
|
|
463
466
|
},
|
|
464
467
|
|
|
465
468
|
stepOneReady() {
|
|
466
|
-
this.
|
|
469
|
+
this.stepRepoInfo['ready'] = this.stepOneRequires;
|
|
467
470
|
},
|
|
468
471
|
|
|
469
472
|
updateTls() {
|
|
@@ -492,6 +495,12 @@ export default {
|
|
|
492
495
|
}
|
|
493
496
|
}
|
|
494
497
|
},
|
|
498
|
+
|
|
499
|
+
onSave() {
|
|
500
|
+
this.value.spec['correctDrift'] = { enabled: this.correctDriftEnabled };
|
|
501
|
+
|
|
502
|
+
this.save();
|
|
503
|
+
}
|
|
495
504
|
}
|
|
496
505
|
};
|
|
497
506
|
</script>
|
|
@@ -507,13 +516,12 @@ export default {
|
|
|
507
516
|
:subtypes="[]"
|
|
508
517
|
:validation-passed="true"
|
|
509
518
|
:errors="errors"
|
|
510
|
-
:steps="
|
|
511
|
-
:edit-first-step="true"
|
|
519
|
+
:steps="steps"
|
|
512
520
|
:finish-mode="'finish'"
|
|
513
521
|
class="wizard"
|
|
514
522
|
@cancel="done"
|
|
515
523
|
@error="e=>errors = e"
|
|
516
|
-
@finish="
|
|
524
|
+
@finish="onSave"
|
|
517
525
|
>
|
|
518
526
|
<template #noticeBanner>
|
|
519
527
|
<Banner
|
|
@@ -646,35 +654,26 @@ export default {
|
|
|
646
654
|
</template>
|
|
647
655
|
<div class="spacer" />
|
|
648
656
|
<h2 v-t="'fleet.gitRepo.resources.label'" />
|
|
649
|
-
<div>
|
|
657
|
+
<div class="resource-handling">
|
|
650
658
|
<Checkbox
|
|
651
|
-
v-model:value="
|
|
659
|
+
v-model:value="correctDriftEnabled"
|
|
660
|
+
:tooltip="t('fleet.gitRepo.resources.correctDriftBanner')"
|
|
652
661
|
data-testid="GitRepo-correctDrift-checkbox"
|
|
653
662
|
class="check"
|
|
654
663
|
type="checkbox"
|
|
655
664
|
label-key="fleet.gitRepo.resources.correctDrift"
|
|
656
665
|
:mode="mode"
|
|
657
666
|
/>
|
|
658
|
-
<
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
667
|
+
<Checkbox
|
|
668
|
+
v-model:value="value.spec.keepResources"
|
|
669
|
+
:tooltip="t('fleet.gitRepo.resources.keepResourcesBanner')"
|
|
670
|
+
data-testid="GitRepo-keepResources-checkbox"
|
|
671
|
+
class="check"
|
|
672
|
+
type="checkbox"
|
|
673
|
+
label-key="fleet.gitRepo.resources.keepResources"
|
|
674
|
+
:mode="mode"
|
|
675
|
+
/>
|
|
664
676
|
</div>
|
|
665
|
-
|
|
666
|
-
<Checkbox
|
|
667
|
-
v-model:value="value.spec.keepResources"
|
|
668
|
-
class="check"
|
|
669
|
-
type="checkbox"
|
|
670
|
-
label-key="fleet.gitRepo.resources.keepResources"
|
|
671
|
-
:mode="mode"
|
|
672
|
-
/>
|
|
673
|
-
<Banner
|
|
674
|
-
color="info"
|
|
675
|
-
>
|
|
676
|
-
{{ t('fleet.gitRepo.resources.keepResourcesBanner') }}
|
|
677
|
-
</Banner>
|
|
678
677
|
<div class="spacer" />
|
|
679
678
|
<h2 v-t="'fleet.gitRepo.paths.label'" />
|
|
680
679
|
<ArrayList
|
|
@@ -764,3 +763,11 @@ export default {
|
|
|
764
763
|
</template>
|
|
765
764
|
</CruResource>
|
|
766
765
|
</template>
|
|
766
|
+
|
|
767
|
+
<style lang="scss" scoped>
|
|
768
|
+
.resource-handling {
|
|
769
|
+
display: flex;
|
|
770
|
+
flex-direction: column;
|
|
771
|
+
gap: 5px
|
|
772
|
+
}
|
|
773
|
+
</style>
|
|
@@ -248,6 +248,7 @@ export default {
|
|
|
248
248
|
busy: false,
|
|
249
249
|
machinePoolValidation: {}, // map of validation states for each machine pool
|
|
250
250
|
machinePoolErrors: {},
|
|
251
|
+
addonConfigValidation: {}, // validation state of each addon config (boolean of whether codemirror's yaml lint passed)
|
|
251
252
|
allNamespaces: [],
|
|
252
253
|
extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.CLUSTER_CREATE_RKE2, this.$route, this),
|
|
253
254
|
labelForAddon
|
|
@@ -797,7 +798,9 @@ export default {
|
|
|
797
798
|
// and in all of the validation statuses for each machine pool
|
|
798
799
|
Object.values(this.machinePoolValidation).forEach((v) => (base = base && v));
|
|
799
800
|
|
|
800
|
-
|
|
801
|
+
const hasAddonConfigErrors = Object.values(this.addonConfigValidation).filter((v) => v === false).length > 0;
|
|
802
|
+
|
|
803
|
+
return validRequiredPools && base && !hasAddonConfigErrors;
|
|
801
804
|
},
|
|
802
805
|
currentCluster() {
|
|
803
806
|
if (this.mode === _EDIT) {
|
|
@@ -1565,6 +1568,8 @@ export default {
|
|
|
1565
1568
|
* 2) We're ready to cache any values the user provides for each addon
|
|
1566
1569
|
*/
|
|
1567
1570
|
async initAddons() {
|
|
1571
|
+
this.addonConfigValidation = {};
|
|
1572
|
+
|
|
1568
1573
|
for (const chartName of this.addonNames) {
|
|
1569
1574
|
const entry = this.chartVersions[chartName];
|
|
1570
1575
|
|
|
@@ -2133,7 +2138,11 @@ export default {
|
|
|
2133
2138
|
}
|
|
2134
2139
|
}
|
|
2135
2140
|
}
|
|
2136
|
-
}
|
|
2141
|
+
},
|
|
2142
|
+
|
|
2143
|
+
addonConfigValidationChanged(configName, isValid) {
|
|
2144
|
+
this.addonConfigValidation[configName] = isValid;
|
|
2145
|
+
},
|
|
2137
2146
|
}
|
|
2138
2147
|
};
|
|
2139
2148
|
</script>
|
|
@@ -2430,6 +2439,7 @@ export default {
|
|
|
2430
2439
|
:label="labelForAddon($store, v.name, false)"
|
|
2431
2440
|
:weight="9"
|
|
2432
2441
|
:showHeader="false"
|
|
2442
|
+
:error="addonConfigValidation[v.name]===false"
|
|
2433
2443
|
@active="showAddons(v.name)"
|
|
2434
2444
|
>
|
|
2435
2445
|
<AddOnConfig
|
|
@@ -2444,6 +2454,7 @@ export default {
|
|
|
2444
2454
|
@update:value="$emit('input', $event)"
|
|
2445
2455
|
@update-questions="syncChartValues"
|
|
2446
2456
|
@update-values="updateValues"
|
|
2457
|
+
@validationChanged="e => addonConfigValidationChanged(v.name, e)"
|
|
2447
2458
|
/>
|
|
2448
2459
|
</Tab>
|
|
2449
2460
|
|
|
@@ -7,7 +7,7 @@ import { labelForAddon } from '@shell/utils/cluster';
|
|
|
7
7
|
import { _EDIT } from '@shell/config/query-params';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
|
-
emits: ['additional-manifest-changed', 'update-questions', 'update-values'],
|
|
10
|
+
emits: ['additional-manifest-changed', 'update-questions', 'update-values', 'validationChanged'],
|
|
11
11
|
|
|
12
12
|
components: {
|
|
13
13
|
Banner,
|
|
@@ -60,7 +60,13 @@ export default {
|
|
|
60
60
|
isEdit() {
|
|
61
61
|
return this.mode === _EDIT;
|
|
62
62
|
}
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
methods: {
|
|
66
|
+
handleValidationChanged(e) {
|
|
67
|
+
this.$emit('validationChanged', e);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
64
70
|
};
|
|
65
71
|
</script>
|
|
66
72
|
|
|
@@ -91,12 +97,14 @@ export default {
|
|
|
91
97
|
<YamlEditor
|
|
92
98
|
v-else
|
|
93
99
|
ref="yaml-values"
|
|
100
|
+
data-testid="addon-yaml-editor"
|
|
94
101
|
:value="initYamlEditor(addonVersion.name)"
|
|
95
102
|
:scrolling="true"
|
|
96
103
|
:as-object="true"
|
|
97
104
|
:editor-mode="mode === 'view' ? 'VIEW_CODE' : 'EDIT_CODE'"
|
|
98
105
|
:hide-preview-buttons="true"
|
|
99
106
|
@update:value="$emit('update-values', addonVersion.name, $event)"
|
|
107
|
+
@validationChanged="handleValidationChanged"
|
|
100
108
|
/>
|
|
101
109
|
<div class="spacer" />
|
|
102
110
|
</div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { clone } from '@shell/utils/object';
|
|
2
3
|
import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
|
|
3
4
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
5
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
@@ -6,6 +7,7 @@ import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthS
|
|
|
6
7
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
7
8
|
import SecretSelector from '@shell/components/form/SecretSelector';
|
|
8
9
|
import { SECRET_TYPES as TYPES } from '@shell/config/secret';
|
|
10
|
+
import { isBase64 } from '@shell/utils/string';
|
|
9
11
|
import { base64Decode, base64Encode } from '@shell/utils/crypto';
|
|
10
12
|
|
|
11
13
|
export default {
|
|
@@ -42,7 +44,7 @@ export default {
|
|
|
42
44
|
},
|
|
43
45
|
|
|
44
46
|
data() {
|
|
45
|
-
const configMap = this.value.spec.rkeConfig?.registries?.configs || {};
|
|
47
|
+
const configMap = clone(this.value.spec.rkeConfig?.registries?.configs) || {};
|
|
46
48
|
const entries = [];
|
|
47
49
|
|
|
48
50
|
const defaultAddValue = {
|
|
@@ -57,7 +59,11 @@ export default {
|
|
|
57
59
|
if (configMap[hostname]) {
|
|
58
60
|
configMap[hostname].insecureSkipVerify = configMap[hostname].insecureSkipVerify ?? defaultAddValue.insecureSkipVerify;
|
|
59
61
|
configMap[hostname].authConfigSecretName = configMap[hostname].authConfigSecretName ?? defaultAddValue.authConfigSecretName;
|
|
60
|
-
|
|
62
|
+
|
|
63
|
+
const caBundle = configMap[hostname].caBundle ?? defaultAddValue.caBundle;
|
|
64
|
+
|
|
65
|
+
configMap[hostname].caBundle = isBase64(caBundle) ? base64Decode(caBundle) : caBundle;
|
|
66
|
+
|
|
61
67
|
configMap[hostname].tlsSecretName = configMap[hostname].tlsSecretName ?? defaultAddValue.tlsSecretName;
|
|
62
68
|
}
|
|
63
69
|
entries.push({
|
package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts
CHANGED
|
@@ -23,10 +23,13 @@ describe('component: RegistryConfigs', () => {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
describe('key CA Cert Bundle', () => {
|
|
26
|
-
it(
|
|
26
|
+
it.each([
|
|
27
|
+
['source is plain text', 'Zm9vYmFy', 'foobar'],
|
|
28
|
+
['source is base64', 'foobar', 'foobar'],
|
|
29
|
+
])('should display key, %p', (_, sourceCaBundle, displayedCaBundle) => {
|
|
27
30
|
const value = clone(PROV_CLUSTER);
|
|
28
31
|
|
|
29
|
-
value.spec.rkeConfig.registries.configs = { foo: { caBundle:
|
|
32
|
+
value.spec.rkeConfig.registries.configs = { foo: { caBundle: sourceCaBundle } };
|
|
30
33
|
|
|
31
34
|
mountOptions.propsData.value = value;
|
|
32
35
|
|
|
@@ -37,7 +40,7 @@ describe('component: RegistryConfigs', () => {
|
|
|
37
40
|
|
|
38
41
|
const registry = wrapper.findComponent('[data-testid^="registry-caBundle"]');
|
|
39
42
|
|
|
40
|
-
expect(registry.props().value).toBe(
|
|
43
|
+
expect(registry.props().value).toBe(displayedCaBundle);
|
|
41
44
|
});
|
|
42
45
|
|
|
43
46
|
it('should update key in base64 format', async() => {
|
|
@@ -250,7 +250,6 @@ export default {
|
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
this.selectContainer(container);
|
|
254
253
|
if (this.realMode === _CLONE && this.value.type === WORKLOAD_TYPES.JOB) {
|
|
255
254
|
this.cleanUpClonedJobData();
|
|
256
255
|
}
|
|
@@ -280,12 +279,10 @@ export default {
|
|
|
280
279
|
podFsGroup: podTemplateSpec.securityContext?.fsGroup,
|
|
281
280
|
savePvcHookName: 'savePvcHook',
|
|
282
281
|
tabWeightMap: TAB_WEIGHT_MAP,
|
|
283
|
-
fvFormRuleSets: [
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
isNamespaceNew: false,
|
|
288
|
-
idKey: ID_KEY
|
|
282
|
+
fvFormRuleSets: [],
|
|
283
|
+
fvReportedValidationPaths: ['spec'],
|
|
284
|
+
isNamespaceNew: false,
|
|
285
|
+
idKey: ID_KEY
|
|
289
286
|
};
|
|
290
287
|
},
|
|
291
288
|
|
|
@@ -605,6 +602,15 @@ export default {
|
|
|
605
602
|
this.value['type'] = neu;
|
|
606
603
|
delete this.value.apiVersion;
|
|
607
604
|
},
|
|
605
|
+
|
|
606
|
+
container: {
|
|
607
|
+
handler(c) {
|
|
608
|
+
this.fvFormRuleSets = [{
|
|
609
|
+
path: 'image', rootObject: c, rules: ['required'], translationKey: 'workload.container.image'
|
|
610
|
+
}];
|
|
611
|
+
},
|
|
612
|
+
immediate: true
|
|
613
|
+
}
|
|
608
614
|
},
|
|
609
615
|
|
|
610
616
|
created() {
|
|
@@ -612,6 +618,8 @@ export default {
|
|
|
612
618
|
this.registerBeforeHook(this.getPorts, 'getPorts');
|
|
613
619
|
|
|
614
620
|
this.registerAfterHook(this.saveService, 'saveService');
|
|
621
|
+
|
|
622
|
+
this.selectContainer(this.container);
|
|
615
623
|
},
|
|
616
624
|
|
|
617
625
|
methods: {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
3
|
-
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
2
|
+
import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
|
|
4
3
|
|
|
5
4
|
export default {
|
|
6
5
|
name: 'ListApps',
|
|
7
|
-
components: {
|
|
8
|
-
mixins: [ResourceFetch],
|
|
6
|
+
components: { PaginatedResourceTable },
|
|
9
7
|
|
|
10
8
|
props: {
|
|
11
9
|
resource: {
|
|
@@ -25,20 +23,15 @@ export default {
|
|
|
25
23
|
|
|
26
24
|
async fetch() {
|
|
27
25
|
await this.$store.dispatch('catalog/load');
|
|
28
|
-
|
|
29
|
-
await this.$fetchType(this.resource);
|
|
30
26
|
},
|
|
31
27
|
};
|
|
32
28
|
</script>
|
|
33
29
|
|
|
34
30
|
<template>
|
|
35
|
-
<
|
|
31
|
+
<PaginatedResourceTable
|
|
36
32
|
class="apps"
|
|
37
33
|
:schema="schema"
|
|
38
|
-
:rows="rows"
|
|
39
|
-
:loading="loading"
|
|
40
34
|
:use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
|
|
41
|
-
:force-update-live-and-delayed="forceUpdateLiveAndDelayed"
|
|
42
35
|
data-testid="installed-app-catalog-list"
|
|
43
36
|
>
|
|
44
37
|
<template #cell:upgrade="{row}">
|
|
@@ -56,7 +49,7 @@ export default {
|
|
|
56
49
|
class="text-muted"
|
|
57
50
|
/>
|
|
58
51
|
</template>
|
|
59
|
-
</
|
|
52
|
+
</PaginatedResourceTable>
|
|
60
53
|
</template>
|
|
61
54
|
|
|
62
55
|
<style scoped>
|
|
@@ -1,47 +1,81 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PaginatedResourceTable from '@shell/components/PaginatedResourceTable.vue';
|
|
3
3
|
import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
4
|
+
import ClusterRepo from '@shell/models/catalog.cattle.io.clusterrepo';
|
|
5
|
+
import { PaginationArgs, PaginationParamFilter } from '@shell/types/store/pagination.types';
|
|
6
|
+
import { defineComponent } from 'vue';
|
|
4
7
|
|
|
5
|
-
export default {
|
|
6
|
-
name:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
required: true,
|
|
12
|
-
},
|
|
8
|
+
export default defineComponent({
|
|
9
|
+
name: 'ListClusterReposApps',
|
|
10
|
+
|
|
11
|
+
components: { PaginatedResourceTable },
|
|
12
|
+
|
|
13
|
+
props: {
|
|
13
14
|
schema: {
|
|
14
15
|
type: Object,
|
|
15
16
|
required: true,
|
|
16
17
|
},
|
|
17
|
-
rows: {
|
|
18
|
-
type: Array,
|
|
19
|
-
required: true,
|
|
20
|
-
},
|
|
21
|
-
loading: {
|
|
22
|
-
type: Boolean,
|
|
23
|
-
required: false,
|
|
24
|
-
},
|
|
25
18
|
useQueryParamsForSimpleFiltering: {
|
|
26
19
|
type: Boolean,
|
|
27
20
|
default: false
|
|
28
21
|
}
|
|
29
22
|
},
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
methods: {
|
|
25
|
+
/**
|
|
26
|
+
* Filter out hidden repos from list of all repos
|
|
27
|
+
*/
|
|
28
|
+
filterRowsLocal(rows: ClusterRepo[]) {
|
|
29
|
+
return rows.filter((repo) => !(repo?.metadata?.annotations?.[CATALOG_ANNOTATIONS.HIDDEN_REPO] === 'true'));
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Filter out hidden repos via api
|
|
34
|
+
*/
|
|
35
|
+
filterRowsApi(pagination: PaginationArgs): PaginationArgs {
|
|
36
|
+
if (!pagination.filters) {
|
|
37
|
+
pagination.filters = [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const field = `metadata.annotations[${ CATALOG_ANNOTATIONS.HIDDEN_REPO }]`;
|
|
41
|
+
|
|
42
|
+
let existing: PaginationParamFilter | null = null;
|
|
43
|
+
|
|
44
|
+
for (let i = 0; i < pagination.filters.length; i++) {
|
|
45
|
+
const filter = pagination.filters[i];
|
|
46
|
+
|
|
47
|
+
if (!!filter.fields.find((f) => f.field === field)) {
|
|
48
|
+
existing = filter;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const required = PaginationParamFilter.createSingleField({
|
|
54
|
+
field,
|
|
55
|
+
exact: true,
|
|
56
|
+
value: 'true',
|
|
57
|
+
equals: false
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!!existing) {
|
|
61
|
+
Object.assign(existing, required);
|
|
62
|
+
} else {
|
|
63
|
+
pagination.filters.push(required);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return pagination;
|
|
34
67
|
}
|
|
35
68
|
}
|
|
36
|
-
|
|
69
|
+
|
|
70
|
+
});
|
|
37
71
|
</script>
|
|
38
72
|
|
|
39
73
|
<template>
|
|
40
74
|
<div>
|
|
41
|
-
<
|
|
75
|
+
<PaginatedResourceTable
|
|
42
76
|
:schema="schema"
|
|
43
|
-
:
|
|
44
|
-
:
|
|
77
|
+
:local-filter="filterRowsLocal"
|
|
78
|
+
:api-filter="filterRowsApi"
|
|
45
79
|
:use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
|
|
46
80
|
data-testid="app-cluster-repo-list"
|
|
47
81
|
/>
|
|
@@ -115,11 +115,11 @@ export default {
|
|
|
115
115
|
>
|
|
116
116
|
<template #cell:deploymentsReady="{row}">
|
|
117
117
|
<span
|
|
118
|
-
v-if="row.status && (row.status.summary.desiredReady !== row.status.summary.ready)"
|
|
118
|
+
v-if="row.status && row.status.summary && (row.status.summary.desiredReady !== row.status.summary.ready)"
|
|
119
119
|
class="text-warning"
|
|
120
120
|
>
|
|
121
121
|
{{ row.status.summary.ready }}/{{ row.status.summary.desiredReady }}</span>
|
|
122
|
-
<span v-else-if="row.status">{{ row.status.summary.desiredReady }}</span>
|
|
122
|
+
<span v-else-if="row.status && row.status.summary">{{ row.status.summary.desiredReady }}</span>
|
|
123
123
|
<span v-else>-</span>
|
|
124
124
|
</template>
|
|
125
125
|
</ResourceTable>
|
|
@@ -9,6 +9,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
|
|
9
9
|
import { MANAGEMENT } from '@shell/config/types';
|
|
10
10
|
import { SETTING } from '@shell/config/settings';
|
|
11
11
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
12
|
+
import { getVendor } from '@shell/config/private-label';
|
|
12
13
|
|
|
13
14
|
export default {
|
|
14
15
|
components: {
|
|
@@ -63,6 +64,7 @@ export default {
|
|
|
63
64
|
serverUrl: '',
|
|
64
65
|
noUrlSet: false,
|
|
65
66
|
showModal: false,
|
|
67
|
+
vendor: getVendor(),
|
|
66
68
|
};
|
|
67
69
|
},
|
|
68
70
|
|
|
@@ -93,6 +95,9 @@ export default {
|
|
|
93
95
|
watch: {
|
|
94
96
|
showPromptUpdate(show) {
|
|
95
97
|
if (show) {
|
|
98
|
+
// Clear last error
|
|
99
|
+
this.error = null;
|
|
100
|
+
|
|
96
101
|
this.showModal = true;
|
|
97
102
|
} else {
|
|
98
103
|
this.showModal = false;
|
|
@@ -138,7 +143,9 @@ export default {
|
|
|
138
143
|
btnCB(true);
|
|
139
144
|
this.close();
|
|
140
145
|
} catch (err) {
|
|
141
|
-
|
|
146
|
+
// An error occurred, so toggle back the value - the call failed, so the change was not made
|
|
147
|
+
this.update.spec.value = !this.update.enabled;
|
|
148
|
+
this.error = err.message || err;
|
|
142
149
|
btnCB(false);
|
|
143
150
|
}
|
|
144
151
|
},
|
|
@@ -214,7 +221,7 @@ export default {
|
|
|
214
221
|
v-if="showModal"
|
|
215
222
|
class="update-modal"
|
|
216
223
|
name="toggleFlag"
|
|
217
|
-
:width="
|
|
224
|
+
:width="450"
|
|
218
225
|
height="auto"
|
|
219
226
|
styles="max-height: 100vh;"
|
|
220
227
|
:click-to-close="!restart || !waiting"
|
|
@@ -227,7 +234,7 @@ export default {
|
|
|
227
234
|
>
|
|
228
235
|
<template #title>
|
|
229
236
|
<h4 class="text-default-text">
|
|
230
|
-
|
|
237
|
+
{{ t('featureFlags.title') }}
|
|
231
238
|
</h4>
|
|
232
239
|
</template>
|
|
233
240
|
<template #body>
|
|
@@ -263,8 +270,8 @@ export default {
|
|
|
263
270
|
</span>
|
|
264
271
|
<Banner
|
|
265
272
|
v-if="restart"
|
|
266
|
-
color="
|
|
267
|
-
:label="t('featureFlags.restartRequired')"
|
|
273
|
+
color="error"
|
|
274
|
+
:label="t('featureFlags.restartRequired', vendor)"
|
|
268
275
|
/>
|
|
269
276
|
</div>
|
|
270
277
|
<div class="text-error mb-10">
|