@rancher/shell 3.0.5-rc.8 → 3.0.5
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/_color.scss +4 -1
- package/assets/styles/global/_tooltip.scss +7 -4
- package/assets/styles/themes/_dark.scss +11 -0
- package/assets/styles/themes/_light.scss +13 -1
- package/assets/styles/themes/_modern.scss +22 -0
- package/assets/translations/en-us.yaml +147 -19
- package/assets/translations/zh-hans.yaml +0 -1
- package/chart/monitoring/grafana/index.vue +8 -2
- package/components/ActionMenuShell.vue +3 -1
- package/components/Cron/CronExpressionEditor.vue +299 -0
- package/components/Cron/CronExpressionEditorModal.vue +247 -0
- package/components/Cron/CronTooltip.vue +87 -0
- package/components/Cron/types.ts +13 -0
- package/components/ForceDirectedTreeChart/composable.ts +11 -0
- package/components/PodSecurityAdmission.vue +2 -0
- package/components/PromptModal.vue +1 -1
- package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +1 -0
- package/components/Resource/Detail/CopyToClipboard.vue +78 -0
- package/components/Resource/Detail/FetchLoader/__tests__/composables.test.ts +69 -0
- package/components/Resource/Detail/FetchLoader/composables.ts +27 -0
- package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
- package/components/Resource/Detail/Metadata/Annotations/index.vue +1 -1
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +13 -61
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +33 -6
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +24 -38
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +25 -5
- package/components/Resource/Detail/Metadata/KeyValue.vue +12 -23
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +144 -0
- package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -0
- package/components/Resource/Detail/Metadata/Labels/index.vue +1 -0
- package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +30 -32
- package/components/Resource/Detail/Metadata/__tests__/KeyValueRow.test.ts +108 -0
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +0 -3
- package/components/Resource/Detail/Metadata/__tests__/index.test.ts +12 -5
- package/components/Resource/Detail/Metadata/composables.ts +1 -4
- package/components/Resource/Detail/Metadata/index.vue +1 -0
- package/components/Resource/Detail/Preview/Content.vue +63 -0
- package/components/Resource/Detail/Preview/Preview.vue +128 -0
- package/components/Resource/Detail/Preview/__tests__/Content.spec.ts +71 -0
- package/components/Resource/Detail/Preview/__tests__/Preview.spec.ts +121 -0
- package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +141 -0
- package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +136 -0
- package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +245 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +226 -0
- package/components/Resource/Detail/SpacedRow.vue +1 -0
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +0 -5
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
- package/components/Resource/Detail/TitleBar/composables.ts +1 -3
- package/components/Resource/Detail/TitleBar/index.vue +2 -29
- package/components/Resource/Detail/ViewOptions/composable.ts +9 -0
- package/components/Resource/Detail/ViewOptions/index.vue +41 -0
- package/components/Resource/Detail/__tests__/CopyToClipboard.spec.ts +82 -0
- package/components/ResourceDetail/Masthead/legacy.vue +0 -19
- package/components/ResourceDetail/index.vue +1 -26
- package/components/ResourceTable.vue +24 -0
- package/components/SortableTable/index.vue +7 -1
- package/components/SortableTable/paging.js +3 -0
- package/components/Tabbed/Tab.vue +43 -1
- package/components/Tabbed/index.vue +3 -1
- package/components/__tests__/Cron/CronExpressionEditor.test.ts +151 -0
- package/components/__tests__/Cron/CronExpressionEditorModal.test.ts +81 -0
- package/components/auth/login/saml.vue +86 -0
- package/components/form/LabeledSelect.vue +8 -8
- package/components/form/ProjectMemberEditor.vue +2 -0
- package/components/form/ResourceTabs/composable.ts +54 -0
- package/components/form/ResourceTabs/index.vue +10 -7
- package/components/form/Select.vue +13 -10
- package/components/form/__tests__/LabeledSelect.test.ts +133 -0
- package/components/form/__tests__/Select.test.ts +134 -0
- package/components/nav/Header.vue +6 -5
- package/composables/useExtensionManager.ts +17 -0
- package/config/home-links.js +12 -0
- package/config/labels-annotations.js +0 -1
- package/config/page-actions.js +0 -1
- package/config/product/explorer.js +3 -1
- package/config/product/fleet.js +2 -7
- package/config/product/manager.js +0 -5
- package/config/query-params.js +1 -0
- package/config/router/navigation-guards/clusters.js +2 -1
- package/config/router/navigation-guards/products.js +1 -1
- package/config/store.js +2 -0
- package/core/extension-manager-impl.js +518 -0
- package/core/plugins.js +35 -468
- package/core/types.ts +8 -2
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +1 -0
- package/detail/catalog.cattle.io.app.vue +7 -4
- package/detail/fleet.cattle.io.bundle.vue +1 -5
- package/detail/fleet.cattle.io.cluster.vue +3 -2
- package/detail/fleet.cattle.io.gitrepo.vue +76 -49
- package/detail/fleet.cattle.io.helmop.vue +78 -49
- package/dialog/AddonConfigConfirmationDialog.vue +1 -1
- package/dialog/GenericPrompt.vue +1 -1
- package/dialog/ImportDialog.vue +9 -2
- package/dialog/InstallExtensionDialog.vue +18 -10
- package/dialog/SloDialog.vue +1 -1
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -1
- package/edit/__tests__/resources.cattle.io.restore.test.ts +106 -0
- package/edit/auth/oidc.vue +106 -6
- package/edit/auth/saml.vue +5 -5
- package/edit/cloudcredential.vue +31 -17
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +10 -2
- package/edit/fleet.cattle.io.cluster.vue +19 -0
- package/edit/fleet.cattle.io.gitrepo.vue +23 -16
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +12 -11
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +11 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +14 -19
- package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -3
- 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/edit/resources.cattle.io.restore.vue +5 -8
- package/initialize/install-plugins.js +1 -3
- package/list/__tests__/workload.test.ts +1 -0
- package/list/workload.vue +8 -1
- package/machine-config/components/GCEImage.vue +6 -5
- package/machine-config/google.vue +11 -6
- package/mixins/__tests__/auth-config.test.ts +4 -6
- package/mixins/__tests__/chart.test.ts +139 -1
- package/mixins/auth-config.js +33 -10
- package/mixins/chart.js +58 -18
- package/models/__tests__/namespace.test.ts +69 -0
- package/models/apps.statefulset.js +8 -10
- package/models/chart.js +5 -1
- package/models/fleet-application.js +16 -46
- package/models/fleet.cattle.io.bundle.js +1 -38
- package/models/fleet.cattle.io.gitrepo.js +4 -0
- package/models/fleet.cattle.io.helmop.js +4 -0
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/management.cattle.io.project.js +12 -0
- package/models/namespace.js +30 -0
- package/models/workload.js +4 -1
- package/package.json +10 -10
- package/pages/auth/login.vue +8 -3
- package/pages/auth/logout.vue +6 -5
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +26 -11
- package/pages/c/_cluster/apps/charts/chart.vue +29 -20
- package/pages/c/_cluster/apps/charts/index.vue +1 -0
- package/pages/c/_cluster/apps/charts/install.vue +6 -5
- package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +102 -12
- package/pages/c/_cluster/explorer/tools/index.vue +145 -254
- package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -1
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +12 -2
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
- package/pages/c/_cluster/uiplugins/__tests__/index.spec.ts +318 -0
- package/pages/c/_cluster/uiplugins/index.vue +221 -363
- package/pages/home.vue +1 -9
- package/plugins/axios.js +3 -2
- package/plugins/dashboard-store/resource-class.js +49 -0
- package/plugins/ember-cookie.js +7 -3
- package/plugins/steve/subscribe.js +4 -2
- package/public/index.html +2 -1
- package/rancher-components/Card/Card.vue +1 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
- package/rancher-components/Form/Radio/RadioButton.vue +1 -1
- package/rancher-components/Form/Radio/RadioGroup.vue +1 -1
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -11
- package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.test.ts +53 -0
- package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +65 -0
- package/rancher-components/Pill/RcCounterBadge/index.ts +1 -0
- package/rancher-components/Pill/RcCounterBadge/types.ts +7 -0
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +1 -1
- package/rancher-components/Pill/RcStatusBadge/index.ts +1 -1
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -3
- package/rancher-components/Pill/RcStatusIndicator/types.ts +1 -1
- package/rancher-components/Pill/RcTag/RcTag.test.ts +64 -0
- package/rancher-components/Pill/RcTag/RcTag.vue +94 -0
- package/rancher-components/Pill/RcTag/index.ts +1 -0
- package/rancher-components/Pill/RcTag/types.ts +9 -0
- package/rancher-components/Pill/types.ts +1 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +1 -0
- package/rancher-components/RcItemCard/RcItemCardAction.vue +12 -0
- package/scripts/test-plugins-build.sh +0 -1
- package/store/__tests__/catalog.test.ts +63 -0
- package/store/__tests__/cookies.test.ts +72 -0
- package/store/auth.js +33 -10
- package/store/catalog.js +2 -2
- package/store/cookies.ts +30 -0
- package/store/prefs.js +10 -5
- package/store/type-map.js +3 -15
- package/types/extension-manager.ts +26 -0
- package/types/shell/index.d.ts +123 -27
- package/utils/__tests__/product.test.ts +129 -0
- package/utils/__tests__/resource.test.ts +87 -0
- package/utils/alertmanagerconfig.js +2 -2
- package/utils/auth.js +4 -77
- package/utils/product.ts +39 -0
- package/utils/resource.ts +35 -0
- package/utils/select.js +0 -24
- package/utils/validators/formRules/__tests__/index.test.ts +3 -0
- package/utils/validators/formRules/index.ts +2 -1
- package/vue.config.js +1 -1
- package/components/Resource/Detail/Metadata/Rectangle.vue +0 -34
- package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +0 -24
- package/components/ResourceDetail/Masthead/__tests__/legacy.test.ts +0 -65
- package/utils/cookie-universal.js +0 -10
- /package/components/{ForceDirectedTreeChart.vue → ForceDirectedTreeChart/index.vue} +0 -0
|
@@ -186,4 +186,73 @@ describe('class Namespace', () => {
|
|
|
186
186
|
it.todo('should return the resourceQuota');
|
|
187
187
|
it.todo('should set the resourceQuota as reactive Vue property');
|
|
188
188
|
it.todo('should reset project with cleanForNew');
|
|
189
|
+
|
|
190
|
+
describe('glance', () => {
|
|
191
|
+
it('should return projectGlance instead of namespace when namespace is in a project', () => {
|
|
192
|
+
const t = jest.fn((key) => key);
|
|
193
|
+
const ctx = { rootGetters: { 'i18n/t': t } };
|
|
194
|
+
const namespace = new Namespace({}, ctx);
|
|
195
|
+
|
|
196
|
+
const project = {
|
|
197
|
+
detailLocation: 'project-detail',
|
|
198
|
+
nameDisplay: 'My Project',
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
jest.spyOn(namespace, 'project', 'get').mockReturnValue(project);
|
|
202
|
+
Object.defineProperty(namespace, '_glance', { get: jest.fn(() => [{ name: 'namespace' }, { name: 'other' }]) });
|
|
203
|
+
|
|
204
|
+
const result = namespace.glance;
|
|
205
|
+
|
|
206
|
+
expect(result).toHaveLength(2);
|
|
207
|
+
expect(result[0].name).toBe('project');
|
|
208
|
+
expect(result[0].label).toBe('component.resource.detail.glance.project');
|
|
209
|
+
expect(result[0].formatter).toBe('Link');
|
|
210
|
+
expect(result[0].formatterOpts?.to).toBe('project-detail');
|
|
211
|
+
expect(result[0].content).toBe('My Project');
|
|
212
|
+
expect(result[1].name).toBe('other');
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should remove namespace from glance when namespace is not in a project', () => {
|
|
216
|
+
const namespace = new Namespace({});
|
|
217
|
+
|
|
218
|
+
jest.spyOn(namespace, 'project', 'get').mockReturnValue(null);
|
|
219
|
+
Object.defineProperty(namespace, '_glance', { get: jest.fn(() => [{ name: 'namespace' }, { name: 'other' }]) });
|
|
220
|
+
|
|
221
|
+
const result = namespace.glance;
|
|
222
|
+
|
|
223
|
+
expect(result).toHaveLength(1);
|
|
224
|
+
expect(result[0].name).toBe('other');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe('projectGlance', () => {
|
|
229
|
+
it('should return undefined if namespace is not in a project', () => {
|
|
230
|
+
const namespace = new Namespace({});
|
|
231
|
+
|
|
232
|
+
jest.spyOn(namespace, 'project', 'get').mockReturnValue(null);
|
|
233
|
+
|
|
234
|
+
expect(namespace.projectGlance).toBeUndefined();
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should return project glance information if namespace is in a project', () => {
|
|
238
|
+
const t = jest.fn((key) => key);
|
|
239
|
+
const ctx = { rootGetters: { 'i18n/t': t } };
|
|
240
|
+
const namespace = new Namespace({}, ctx);
|
|
241
|
+
|
|
242
|
+
const project = {
|
|
243
|
+
detailLocation: 'project-detail',
|
|
244
|
+
nameDisplay: 'My Project',
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
jest.spyOn(namespace, 'project', 'get').mockReturnValue(project);
|
|
248
|
+
|
|
249
|
+
const result = namespace.projectGlance;
|
|
250
|
+
|
|
251
|
+
expect(result?.name).toBe('project');
|
|
252
|
+
expect(result?.label).toBe('component.resource.detail.glance.project');
|
|
253
|
+
expect(result?.formatter).toBe('Link');
|
|
254
|
+
expect(result?.formatterOpts.to).toBe('project-detail');
|
|
255
|
+
expect(result?.content).toBe('My Project');
|
|
256
|
+
});
|
|
257
|
+
});
|
|
189
258
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Workload from './workload';
|
|
2
|
-
import { WORKLOAD_TYPES,
|
|
2
|
+
import { WORKLOAD_TYPES, WORKLOAD_TYPE_TO_KIND_MAPPING } from '@shell/config/types';
|
|
3
3
|
|
|
4
4
|
export default class StatefulSet extends Workload {
|
|
5
5
|
async rollBack(cluster, statefulSet, revision) {
|
|
@@ -21,16 +21,14 @@ export default class StatefulSet extends Workload {
|
|
|
21
21
|
await this.rollBackWorkload(cluster, statefulSet, 'statefulsets', body);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* See fetchPods description for more info
|
|
26
|
+
*/
|
|
26
27
|
get pods() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const pods = this.$getters['podsByNamespace'](this.metadata.namespace);
|
|
32
|
-
|
|
33
|
-
return pods.filter((pod) => {
|
|
28
|
+
if (this.podMatchExpression) {
|
|
29
|
+
// Given https://github.com/rancher/dashboard/issues/7555 we want to avoid scenarios where we show pods that have an applicable label but aren't applicable (?!)
|
|
30
|
+
// super.pods is the pods that match the statefulsets podSelector, so start from that and then filter further by pod's owner
|
|
31
|
+
return super.pods.filter((pod) => {
|
|
34
32
|
// a bit of a duplication of podRelationship, but always safe to check...
|
|
35
33
|
if (pod.metadata?.ownerReferences?.length) {
|
|
36
34
|
const ownerReferencesStatefulSet = pod.metadata?.ownerReferences?.find((own) => own.kind === WORKLOAD_TYPE_TO_KIND_MAPPING[WORKLOAD_TYPES.STATEFUL_SET]);
|
package/models/chart.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { compatibleVersionsFor, APP_UPGRADE_STATUS } from '@shell/store/catalog';
|
|
2
2
|
import {
|
|
3
|
-
REPO_TYPE, REPO, CHART, VERSION, _FLAGGED, HIDE_SIDE_NAV, CATEGORY, TAG
|
|
3
|
+
REPO_TYPE, REPO, CHART, VERSION, _FLAGGED, HIDE_SIDE_NAV, CATEGORY, TAG, DEPRECATED as DEPRECATED_QUERY
|
|
4
4
|
} from '@shell/config/query-params';
|
|
5
5
|
import { BLANK_CLUSTER } from '@shell/store/store-types.js';
|
|
6
6
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
@@ -29,6 +29,10 @@ export default class Chart extends SteveModel {
|
|
|
29
29
|
[VERSION]: version,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
if (this.deprecated) {
|
|
33
|
+
out[DEPRECATED_QUERY] = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
if ( from ) {
|
|
33
37
|
out[from] = _FLAGGED;
|
|
34
38
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { matching, convertSelectorObj } from '@shell/utils/selector';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
3
|
import { escapeHtml } from '@shell/utils/string';
|
|
4
|
-
import { FLEET
|
|
4
|
+
import { FLEET } from '@shell/config/types';
|
|
5
5
|
import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
6
6
|
import { addObject, addObjects, findBy } from '@shell/utils/array';
|
|
7
7
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
@@ -29,8 +29,19 @@ function normalizeStateCounts(data) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export default class FleetApplication extends SteveModel {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
async getCurrentUser() {
|
|
33
|
+
const user = this.$rootGetters['auth/v3User'];
|
|
34
|
+
|
|
35
|
+
if (user?.id) {
|
|
36
|
+
return user;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const res = await this.$dispatch('rancher/request', {
|
|
40
|
+
url: '/v3/users?me=true',
|
|
41
|
+
method: 'get',
|
|
42
|
+
}, { root: true });
|
|
43
|
+
|
|
44
|
+
return res?.data?.[0] || {};
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
pause() {
|
|
@@ -48,10 +59,6 @@ export default class FleetApplication extends SteveModel {
|
|
|
48
59
|
delete this.metadata.labels[FLEET_ANNOTATIONS.CREATED_BY_USER_ID];
|
|
49
60
|
}
|
|
50
61
|
|
|
51
|
-
if (this.metadata?.labels?.[FLEET_ANNOTATIONS.CREATED_BY_USER_NAME]) {
|
|
52
|
-
delete this.metadata.labels[FLEET_ANNOTATIONS.CREATED_BY_USER_NAME];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
62
|
super.goToClone();
|
|
56
63
|
}
|
|
57
64
|
|
|
@@ -144,11 +151,11 @@ export default class FleetApplication extends SteveModel {
|
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
statusResourceCountsForCluster(clusterId) {
|
|
147
|
-
if (!this.targetClusters.some((c) => c.id === clusterId)) {
|
|
154
|
+
if (!(this.targetClusters || []).some((c) => c.id === clusterId)) {
|
|
148
155
|
return {};
|
|
149
156
|
}
|
|
150
157
|
|
|
151
|
-
return this.status?.perClusterResourceCounts[clusterId] || { desiredReady: 0 };
|
|
158
|
+
return this.status?.perClusterResourceCounts?.[clusterId] || { desiredReady: 0 };
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
get resourcesStatuses() {
|
|
@@ -224,43 +231,6 @@ export default class FleetApplication extends SteveModel {
|
|
|
224
231
|
return primaryDisplayStatusFromCount(resourceCounts) || STATES_ENUM.ACTIVE;
|
|
225
232
|
}
|
|
226
233
|
|
|
227
|
-
get authorId() {
|
|
228
|
-
return this.metadata?.labels?.[FLEET_ANNOTATIONS.CREATED_BY_USER_ID];
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
get author() {
|
|
232
|
-
if (this.authorId) {
|
|
233
|
-
return this.$rootGetters['management/byId'](MANAGEMENT.USER, this.authorId);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
get createdBy() {
|
|
240
|
-
const displayName = this.metadata?.labels?.[FLEET_ANNOTATIONS.CREATED_BY_USER_NAME];
|
|
241
|
-
|
|
242
|
-
if (!displayName) {
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return {
|
|
247
|
-
displayName,
|
|
248
|
-
location: !this.author ? null : {
|
|
249
|
-
name: 'c-cluster-product-resource-id',
|
|
250
|
-
params: {
|
|
251
|
-
cluster: '_',
|
|
252
|
-
product: 'auth',
|
|
253
|
-
resource: MANAGEMENT.USER,
|
|
254
|
-
id: this.author.id,
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
get showCreatedBy() {
|
|
261
|
-
return !!this.createdBy;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
234
|
get clustersList() {
|
|
265
235
|
return this.$getters['all'](FLEET.CLUSTER);
|
|
266
236
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { escapeHtml, ucFirst } from '@shell/utils/string';
|
|
2
2
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
3
3
|
import { addObject, addObjects, findBy } from '@shell/utils/array';
|
|
4
|
-
import { FLEET
|
|
4
|
+
import { FLEET } from '@shell/config/types';
|
|
5
5
|
import { FLEET as FLEET_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
6
6
|
import { convertSelectorObj, matching } from '@shell/utils/selector';
|
|
7
7
|
|
|
@@ -129,41 +129,4 @@ export default class FleetBundle extends SteveModel {
|
|
|
129
129
|
);
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
get authorId() {
|
|
134
|
-
return this.metadata?.labels?.[FLEET_ANNOTATIONS.CREATED_BY_USER_ID];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
get author() {
|
|
138
|
-
if (this.authorId) {
|
|
139
|
-
return this.$rootGetters['management/byId'](MANAGEMENT.USER, this.authorId);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
get createdBy() {
|
|
146
|
-
const displayName = this.metadata?.labels?.[FLEET_ANNOTATIONS.CREATED_BY_USER_NAME];
|
|
147
|
-
|
|
148
|
-
if (!displayName) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
displayName,
|
|
154
|
-
location: !this.author ? null : {
|
|
155
|
-
name: 'c-cluster-product-resource-id',
|
|
156
|
-
params: {
|
|
157
|
-
cluster: '_',
|
|
158
|
-
product: 'auth',
|
|
159
|
-
resource: MANAGEMENT.USER,
|
|
160
|
-
id: this.author.id,
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
get showCreatedBy() {
|
|
167
|
-
return !!this.createdBy;
|
|
168
|
-
}
|
|
169
132
|
}
|
|
@@ -199,4 +199,8 @@ export default class HelmOp extends FleetApplication {
|
|
|
199
199
|
get bundleDeployments() {
|
|
200
200
|
return this.$getters['matching'](FLEET.BUNDLE_DEPLOYMENT, { [FLEET_ANNOTATIONS.HELM_NAME]: this.name });
|
|
201
201
|
}
|
|
202
|
+
|
|
203
|
+
get fullDetailPageOverride() {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
202
206
|
}
|
|
@@ -278,7 +278,7 @@ export default class MgmtCluster extends SteveModel {
|
|
|
278
278
|
|
|
279
279
|
// Color to use as the underline for the icon in the app bar
|
|
280
280
|
get iconColor() {
|
|
281
|
-
return this.metadata?.annotations[CLUSTER_BADGE.COLOR];
|
|
281
|
+
return this.metadata?.annotations?.[CLUSTER_BADGE.COLOR];
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
// Custom badge to show for the Cluster (if the appropriate annotations are set)
|
|
@@ -179,4 +179,16 @@ export default class Project extends HybridModel {
|
|
|
179
179
|
get confirmRemove() {
|
|
180
180
|
return true;
|
|
181
181
|
}
|
|
182
|
+
|
|
183
|
+
get glance() {
|
|
184
|
+
const glance = [...this._glance];
|
|
185
|
+
|
|
186
|
+
const namespaceIndex = glance.findIndex((item) => item.name === 'namespace');
|
|
187
|
+
|
|
188
|
+
if (namespaceIndex > -1) {
|
|
189
|
+
glance.splice(namespaceIndex, 1);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return glance;
|
|
193
|
+
}
|
|
182
194
|
}
|
package/models/namespace.js
CHANGED
|
@@ -269,4 +269,34 @@ export default class Namespace extends SteveModel {
|
|
|
269
269
|
get hideDetailLocation() {
|
|
270
270
|
return !!this.$rootGetters['currentProduct'].hideNamespaceLocation;
|
|
271
271
|
}
|
|
272
|
+
|
|
273
|
+
get glance() {
|
|
274
|
+
const glance = [...this._glance];
|
|
275
|
+
|
|
276
|
+
const namespaceIndex = glance.findIndex((item) => item.name === 'namespace');
|
|
277
|
+
|
|
278
|
+
if (namespaceIndex > -1) {
|
|
279
|
+
glance.splice(namespaceIndex, 1, this.projectGlance);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// projectGlance could be undefined
|
|
283
|
+
return glance.filter(Boolean);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
get projectGlance() {
|
|
287
|
+
// Not all namespaces are in a project
|
|
288
|
+
if (!this.project) {
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
name: 'project',
|
|
294
|
+
label: this.t('component.resource.detail.glance.project'),
|
|
295
|
+
formatter: 'Link',
|
|
296
|
+
formatterOpts: {
|
|
297
|
+
to: this.project.detailLocation, row: {}, options: { internal: true }
|
|
298
|
+
},
|
|
299
|
+
content: this.project.nameDisplay
|
|
300
|
+
};
|
|
301
|
+
}
|
|
272
302
|
}
|
package/models/workload.js
CHANGED
|
@@ -43,7 +43,7 @@ export default class Workload extends WorkloadService {
|
|
|
43
43
|
insertAt(out, 0, {
|
|
44
44
|
action: 'toggleRollbackModal',
|
|
45
45
|
label: this.t('action.rollback'),
|
|
46
|
-
icon: 'icon icon-
|
|
46
|
+
icon: 'icon icon-downgrade-alt',
|
|
47
47
|
enabled: !!this.links.update,
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -595,6 +595,9 @@ export default class Workload extends WorkloadService {
|
|
|
595
595
|
return selector;
|
|
596
596
|
}
|
|
597
597
|
|
|
598
|
+
/**
|
|
599
|
+
* Match Expression version of the podSelector
|
|
600
|
+
*/
|
|
598
601
|
get podMatchExpression() {
|
|
599
602
|
return this.podSelector ? parse(this.podSelector) : null;
|
|
600
603
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rancher/shell",
|
|
3
|
-
"version": "3.0.5
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "Rancher Dashboard Shell",
|
|
5
5
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@aws-sdk/client-ec2": "3.863.0",
|
|
31
|
-
"@aws-sdk/client-eks": "3.
|
|
31
|
+
"@aws-sdk/client-eks": "3.879.0",
|
|
32
32
|
"@aws-sdk/client-iam": "3.863.0",
|
|
33
33
|
"@aws-sdk/client-kms": "3.863.0",
|
|
34
34
|
"@smithy/fetch-http-handler": "5.1.1",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"add": "2.0.6",
|
|
53
53
|
"ansi_up": "5.0.0",
|
|
54
54
|
"axios-retry": "3.1.9",
|
|
55
|
-
"axios": "1.
|
|
55
|
+
"axios": "1.12.2",
|
|
56
56
|
"babel-eslint": "10.1.0",
|
|
57
57
|
"babel-plugin-module-resolver": "4.0.0",
|
|
58
58
|
"babel-preset-vue": "2.0.2",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"color": "4.2.3",
|
|
65
65
|
"cookie-universal": "2.2.2",
|
|
66
66
|
"cookie": "0.7.0",
|
|
67
|
-
"core-js": "3.
|
|
67
|
+
"core-js": "3.45.0",
|
|
68
68
|
"cron-validator": "1.4.0",
|
|
69
69
|
"cronstrue": "2.53.0",
|
|
70
70
|
"cross-env": "7.0.3",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"cypress": "11.1.0",
|
|
75
75
|
"d3-selection": "3.0.0",
|
|
76
76
|
"d3": "7.3.0",
|
|
77
|
-
"dayjs": "1.
|
|
77
|
+
"dayjs": "1.11.18",
|
|
78
78
|
"defu": "5.0.1",
|
|
79
79
|
"diff2html": "3.4.24",
|
|
80
80
|
"dompurify": "3.2.5",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"eslint-import-resolver-node": "0.3.9",
|
|
85
85
|
"eslint-module-utils": "2.6.1",
|
|
86
86
|
"eslint-plugin-cypress": "2.12.1",
|
|
87
|
-
"eslint-plugin-import": "2.
|
|
87
|
+
"eslint-plugin-import": "2.32.0",
|
|
88
88
|
"eslint-plugin-jest": "24.4.0",
|
|
89
89
|
"eslint-plugin-n": "15.2.0",
|
|
90
90
|
"eslint-plugin-vue": "9.32.0",
|
|
@@ -130,15 +130,15 @@
|
|
|
130
130
|
"ufo": "0.7.11",
|
|
131
131
|
"unfetch": "4.2.0",
|
|
132
132
|
"url-parse": "1.5.10",
|
|
133
|
-
"vue-router": "4.5.
|
|
133
|
+
"vue-router": "4.5.1",
|
|
134
134
|
"vue-select": "4.0.0-beta.6",
|
|
135
135
|
"vue-server-renderer": "2.7.16",
|
|
136
|
-
"vue": "
|
|
136
|
+
"vue": "3.5.18",
|
|
137
137
|
"vue3-resize": "0.2.0",
|
|
138
138
|
"vue3-virtual-scroll-list": "0.2.1",
|
|
139
139
|
"vuedraggable": "4.1.0",
|
|
140
140
|
"vuex": "4.1.0",
|
|
141
|
-
"webpack-bundle-analyzer": "4.
|
|
141
|
+
"webpack-bundle-analyzer": "4.10.2",
|
|
142
142
|
"webpack-virtual-modules": "0.4.3",
|
|
143
143
|
"worker-loader": "3.0.8",
|
|
144
144
|
"xterm-addon-canvas": "0.5.0",
|
|
@@ -172,4 +172,4 @@
|
|
|
172
172
|
".vue"
|
|
173
173
|
]
|
|
174
174
|
}
|
|
175
|
-
}
|
|
175
|
+
}
|
package/pages/auth/login.vue
CHANGED
|
@@ -134,7 +134,8 @@ export default {
|
|
|
134
134
|
},
|
|
135
135
|
|
|
136
136
|
async fetch() {
|
|
137
|
-
const
|
|
137
|
+
const cookie = this.$store.getters['cookies/get']({ key: USERNAME, options: { parseJSON: false } });
|
|
138
|
+
const username = cookie || '';
|
|
138
139
|
|
|
139
140
|
this.username = username;
|
|
140
141
|
this.remember = !!username;
|
|
@@ -272,15 +273,19 @@ export default {
|
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
if ( this.remember ) {
|
|
275
|
-
|
|
276
|
+
const options = {
|
|
276
277
|
encode: (x) => x,
|
|
277
278
|
maxAge: 86400 * 365,
|
|
278
279
|
path: '/',
|
|
279
280
|
sameSite: true,
|
|
280
281
|
secure: true,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
this.$store.commit('cookies/set', {
|
|
285
|
+
key: USERNAME, value: this.username, options
|
|
281
286
|
});
|
|
282
287
|
} else {
|
|
283
|
-
this.$cookies
|
|
288
|
+
this.$store.commit('cookies/remove', { key: USERNAME });
|
|
284
289
|
}
|
|
285
290
|
|
|
286
291
|
// User logged with local login - we don't do any redirect/reload, so the boot-time plugin will not run again to laod the plugins
|
package/pages/auth/logout.vue
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { configType } from '@shell/models/management.cattle.io.authconfig';
|
|
3
|
+
import { SLO_AUTH_PROVIDERS } from '@shell/store/auth';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
async fetch() {
|
|
6
7
|
const publicAuthProviders = await this.$store.dispatch('auth/getAuthProviders');
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
+
const sloAuthProvider = publicAuthProviders.find((authProvider) => SLO_AUTH_PROVIDERS.includes(configType[authProvider?.id]));
|
|
9
10
|
|
|
10
|
-
if (!!
|
|
11
|
-
const { logoutAllSupported, logoutAllEnabled, logoutAllForced } =
|
|
11
|
+
if (!!sloAuthProvider) {
|
|
12
|
+
const { logoutAllSupported, logoutAllEnabled, logoutAllForced } = sloAuthProvider;
|
|
12
13
|
|
|
13
14
|
if (logoutAllSupported && logoutAllEnabled && logoutAllForced) {
|
|
14
|
-
//
|
|
15
|
+
// force SLO (logout from all apps)
|
|
15
16
|
await this.$store.dispatch('auth/logout', {
|
|
16
|
-
force: true, slo: true, provider:
|
|
17
|
+
force: true, slo: true, provider: sloAuthProvider
|
|
17
18
|
}, { root: true });
|
|
18
19
|
} else {
|
|
19
20
|
// simple logout
|
|
@@ -5,12 +5,15 @@ interface FooterItem {
|
|
|
5
5
|
icon?: string;
|
|
6
6
|
iconTooltip?: Record<{key?: string, text?: string}>;
|
|
7
7
|
labels: string[];
|
|
8
|
+
labelTooltip?: string;
|
|
9
|
+
type?: string;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
const emit = defineEmits<{(e: 'click:item', type: string, label: string): void; }>();
|
|
11
13
|
|
|
12
14
|
defineProps<{
|
|
13
15
|
items: FooterItem[];
|
|
16
|
+
clickable?: boolean;
|
|
14
17
|
}>();
|
|
15
18
|
|
|
16
19
|
function onClickItem(type: string, label: string) {
|
|
@@ -32,20 +35,32 @@ function onClickItem(type: string, label: string) {
|
|
|
32
35
|
v-clean-tooltip="t(footerItem.iconTooltip?.key)"
|
|
33
36
|
:class="['icon', 'app-chart-card-footer-item-icon', footerItem.icon]"
|
|
34
37
|
/>
|
|
35
|
-
<
|
|
38
|
+
<template
|
|
36
39
|
v-for="(label, j) in footerItem.labels"
|
|
37
40
|
:key="j"
|
|
38
|
-
v-clean-tooltip="footerItem.labelTooltip"
|
|
39
|
-
class="app-chart-card-footer-item-text secondary-text-link"
|
|
40
|
-
data-testid="app-chart-card-footer-item-text"
|
|
41
|
-
tabindex="0"
|
|
42
|
-
:aria-label="t('catalog.charts.appChartCard.footerItem.ariaLabel')"
|
|
43
|
-
@click="onClickItem(footerItem.type, label)"
|
|
44
|
-
@keydown.enter="onClickItem(footerItem.type, label)"
|
|
45
|
-
@keydown.space.prevent="onClickItem(footerItem.type, label)"
|
|
46
41
|
>
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
<rc-item-card-action
|
|
43
|
+
v-if="clickable && footerItem.type"
|
|
44
|
+
v-clean-tooltip="footerItem.labelTooltip"
|
|
45
|
+
class="app-chart-card-footer-item-text secondary-text-link"
|
|
46
|
+
data-testid="app-chart-card-footer-item-text"
|
|
47
|
+
tabindex="0"
|
|
48
|
+
:aria-label="t('catalog.charts.appChartCard.footerItem.ariaLabel')"
|
|
49
|
+
@click="onClickItem(footerItem.type, label)"
|
|
50
|
+
>
|
|
51
|
+
{{ label }}
|
|
52
|
+
<span v-if="footerItem.labels.length > 1 && j !== footerItem.labels.length - 1">, </span>
|
|
53
|
+
</rc-item-card-action>
|
|
54
|
+
<span
|
|
55
|
+
v-else
|
|
56
|
+
v-clean-tooltip="footerItem.labelTooltip"
|
|
57
|
+
class="app-chart-card-footer-item-text"
|
|
58
|
+
data-testid="app-chart-card-footer-item-text"
|
|
59
|
+
>
|
|
60
|
+
{{ label }}
|
|
61
|
+
<span v-if="footerItem.labels.length > 1 && j !== footerItem.labels.length - 1">, </span>
|
|
62
|
+
</span>
|
|
63
|
+
</template>
|
|
49
64
|
</div>
|
|
50
65
|
</div>
|
|
51
66
|
</template>
|
|
@@ -6,7 +6,7 @@ import ChartReadme from '@shell/components/ChartReadme';
|
|
|
6
6
|
import LazyImage from '@shell/components/LazyImage';
|
|
7
7
|
import isEqual from 'lodash/isEqual';
|
|
8
8
|
import {
|
|
9
|
-
CHART, REPO, REPO_TYPE, VERSION, SEARCH_QUERY, CATEGORY, TAG
|
|
9
|
+
CHART, REPO, REPO_TYPE, VERSION, SEARCH_QUERY, CATEGORY, TAG, DEPRECATED
|
|
10
10
|
} from '@shell/config/query-params';
|
|
11
11
|
import { DATE_FORMAT } from '@shell/store/prefs';
|
|
12
12
|
import { ZERO_TIME } from '@shell/config/types';
|
|
@@ -50,7 +50,14 @@ export default {
|
|
|
50
50
|
...mapGetters(['currentCluster']),
|
|
51
51
|
|
|
52
52
|
headerContent() {
|
|
53
|
-
return
|
|
53
|
+
return {
|
|
54
|
+
...this.chart.cardContent,
|
|
55
|
+
subHeaderItems: this.chart.cardContent.subHeaderItems.map((item, i) => i === 0 ? ({
|
|
56
|
+
icon: 'icon-version-alt',
|
|
57
|
+
iconTooltip: { key: 'tableHeaders.version' },
|
|
58
|
+
label: this.query.versionName
|
|
59
|
+
}) : item)
|
|
60
|
+
};
|
|
54
61
|
},
|
|
55
62
|
|
|
56
63
|
versions() {
|
|
@@ -144,10 +151,11 @@ export default {
|
|
|
144
151
|
product: this.$store.getters['productId'],
|
|
145
152
|
},
|
|
146
153
|
query: {
|
|
147
|
-
[REPO_TYPE]:
|
|
148
|
-
[REPO]:
|
|
149
|
-
[CHART]:
|
|
150
|
-
[VERSION]:
|
|
154
|
+
[REPO_TYPE]: this.query.repoType,
|
|
155
|
+
[REPO]: this.query.repoName,
|
|
156
|
+
[CHART]: this.query.chartName,
|
|
157
|
+
[VERSION]: this.query.versionName,
|
|
158
|
+
[DEPRECATED]: this.query.deprecated,
|
|
151
159
|
}
|
|
152
160
|
});
|
|
153
161
|
},
|
|
@@ -210,17 +218,6 @@ export default {
|
|
|
210
218
|
<template>
|
|
211
219
|
<Loading v-if="$fetchState.pending" />
|
|
212
220
|
<main v-else>
|
|
213
|
-
<Banner
|
|
214
|
-
v-if="versionInfoError"
|
|
215
|
-
color="error"
|
|
216
|
-
:label="versionInfoError"
|
|
217
|
-
/>
|
|
218
|
-
<Banner
|
|
219
|
-
v-if="warningMessage"
|
|
220
|
-
color="warning"
|
|
221
|
-
:label="warningMessage"
|
|
222
|
-
data-testid="deprecation-and-experimental-banner"
|
|
223
|
-
/>
|
|
224
221
|
<div
|
|
225
222
|
v-if="chart"
|
|
226
223
|
class="chart-header"
|
|
@@ -284,6 +281,7 @@ export default {
|
|
|
284
281
|
</div>
|
|
285
282
|
<div class="header-bottom">
|
|
286
283
|
<AppChartCardFooter
|
|
284
|
+
:clickable="true"
|
|
287
285
|
:items="headerContent.footerItems"
|
|
288
286
|
@click:item="handleHeaderItemClick"
|
|
289
287
|
/>
|
|
@@ -296,15 +294,26 @@ export default {
|
|
|
296
294
|
@click.prevent="install"
|
|
297
295
|
>
|
|
298
296
|
<i
|
|
299
|
-
|
|
300
|
-
class="icon icon-upgrade-alt mmr-2"
|
|
297
|
+
:class="['icon', action.icon, 'mmr-2']"
|
|
301
298
|
/>
|
|
302
|
-
{{ t(`
|
|
299
|
+
{{ t(`catalog.chart.chartButton.action.${action.tKey}` ) }}
|
|
303
300
|
</RcButton>
|
|
304
301
|
</div>
|
|
305
302
|
|
|
306
303
|
<div class="dashed-spacer" />
|
|
307
304
|
|
|
305
|
+
<Banner
|
|
306
|
+
v-if="versionInfoError"
|
|
307
|
+
color="error"
|
|
308
|
+
:label="versionInfoError"
|
|
309
|
+
/>
|
|
310
|
+
<Banner
|
|
311
|
+
v-if="warningMessage"
|
|
312
|
+
color="warning"
|
|
313
|
+
:label="warningMessage"
|
|
314
|
+
data-testid="deprecation-and-experimental-banner"
|
|
315
|
+
/>
|
|
316
|
+
|
|
308
317
|
<div
|
|
309
318
|
v-if="requires.length || warnings.length || targetedAppWarning || osWarning"
|
|
310
319
|
class="chart-banners"
|