dashboard-shell-shell 3.0.5-test.9 → 3.0.5-tsh-rh02
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/brand/csp/favicon.png +0 -0
- package/assets/icons/iconfont.css +4 -1
- package/assets/iconsNew/demo.css +539 -0
- package/assets/iconsNew/demo.css:Zone.Identifier +0 -0
- package/assets/iconsNew/demo_index.html +303 -0
- package/assets/iconsNew/demo_index.html:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.css +43 -0
- package/assets/iconsNew/iconfont.css:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.js +1 -0
- package/assets/iconsNew/iconfont.js:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.json +44 -0
- package/assets/iconsNew/iconfont.json:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.ttf +0 -0
- package/assets/iconsNew/iconfont.ttf:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.woff +0 -0
- package/assets/iconsNew/iconfont.woff2 +0 -0
- package/assets/iconsNew/iconfont.woff2:Zone.Identifier +0 -0
- package/assets/iconsNew/iconfont.woff:Zone.Identifier +0 -0
- package/assets/images/login-logo.svg +9 -19
- package/assets/images/login-logo1.svg +9 -0
- package/assets/images/logo.svg +11 -0
- package/assets/images/pl/dark/logo.png +0 -0
- package/assets/images/pl/logo.svg +11 -0
- package/assets/styles/all.scss +23 -3
- package/assets/styles/app.scss +1 -0
- package/assets/styles/base/_helpers.scss +1 -1
- package/assets/styles/base/_variables.scss +2 -2
- package/assets/styles/fonts/_icons.scss +3 -2
- package/assets/styles/global/_button.scss +1 -1
- package/assets/styles/global/_form.scss +1 -0
- package/assets/styles/global/_select.scss +1 -1
- package/assets/styles/global/_tooltip.scss +5 -1
- package/assets/styles/themes/_light.scss +3 -3
- package/assets/styles/vendor/vue-select.scss +2 -1
- package/assets/translations/en-us.yaml +67 -0
- package/assets/translations/zh-hans.yaml +226 -24
- package/components/ButtonDropdown.vue +3 -1
- package/components/ClusterIconMenu.vue +1 -1
- package/components/CodeMirror.vue +6 -4
- package/components/ConsumptionGauge.vue +1 -1
- package/components/ContainerResourceLimit.vue +2 -2
- package/components/CruResource.vue +3 -2
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +22 -19
- package/components/Drawer/ResourceDetailDrawer/index.vue +3 -3
- package/components/ExplorerMembers.vue +10 -1
- package/components/GlobalRoleBindings.vue +69 -114
- package/components/PodSecurityAdmission.vue +1 -1
- package/components/PromptRemove.vue +23 -1
- package/components/RelatedResources.vue +3 -0
- package/components/Resource/Detail/TitleBar/composables.ts +16 -1
- package/components/Resource/Detail/TitleBar/index.vue +37 -24
- package/components/ResourceDetail/Masthead/index.vue +1 -1
- package/components/ResourceDetail/Masthead/latest.vue +1 -1
- package/components/ResourceDetail/Masthead/legacy.vue +8 -7
- package/components/ResourceDetail/legacy.vue +15 -15
- package/components/ResourceList/Masthead.vue +16 -15
- package/components/ResourceTable.vue +16 -0
- package/components/SideNav.vue +21 -21
- package/components/SingleClusterInfo.vue +2 -1
- package/components/SortableTable/THead.vue +46 -1
- package/components/SortableTable/index.vue +54 -18
- package/components/Tabbed/index.vue +6 -1
- package/components/actionButton/index.vue +649 -0
- package/components/auth/Principal.vue +16 -8
- package/components/auth/RoleDetailEdit.vue +11 -7
- package/components/breadcrumb/index.vue +13 -210
- package/components/form/ArrayList.vue +164 -147
- package/components/form/ArrayListGrouped.vue +5 -3
- package/components/form/ChangePassword.vue +1 -1
- package/components/form/ClusterAppearance.vue +4 -3
- package/components/form/Command.vue +4 -5
- package/components/form/Conditions.vue +15 -1
- package/components/form/Footer.vue +1 -0
- package/components/form/HealthCheck.vue +0 -2
- package/components/form/HookOption.vue +87 -58
- package/components/form/InputWithSelect.vue +8 -7
- package/components/form/KeyValue.vue +20 -2
- package/components/form/LabeledSelect.vue +3 -1
- package/components/form/Labels.vue +2 -2
- package/components/form/MatchExpressions.vue +4 -4
- package/components/form/Members/ClusterMembershipEditor.vue +1 -1
- package/components/form/Members/ClusterPermissionsEditor.vue +60 -41
- package/components/form/Members/MembershipEditor.vue +4 -4
- package/components/form/Members/ProjectMembershipEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +3 -2
- package/components/form/Networking.vue +6 -9
- package/components/form/NodeAffinity.vue +29 -28
- package/components/form/PodAffinity.vue +23 -23
- package/components/form/Probe.vue +15 -11
- package/components/form/ProjectMemberEditor.vue +66 -48
- package/components/form/ResourceQuota/Namespace.vue +4 -4
- package/components/form/ResourceQuota/NamespaceRow.vue +11 -9
- package/components/form/ResourceQuota/Project.vue +4 -4
- package/components/form/ResourceQuota/ProjectRow.vue +36 -30
- package/components/form/ResourceSelector.vue +1 -1
- package/components/form/SecretSelector.vue +24 -23
- package/components/form/Security.vue +1 -3
- package/components/form/Select.vue +7 -1
- package/components/form/ServiceNameSelect.vue +2 -5
- package/components/form/ServicePorts.vue +149 -75
- package/components/form/Tolerations.vue +13 -9
- package/components/form/ValueFromResource.vue +110 -96
- package/components/formatter/WorkloadHealthScale.vue +4 -3
- package/components/nav/Group.vue +8 -1
- package/components/nav/Header.vue +51 -174
- package/components/nav/NamespaceFilter.vue +14 -19
- package/components/nav/TopLevelMenu.vue +101 -134
- package/components/nav/Type.vue +11 -3
- package/config/menuRouteMap.js +10 -0
- package/config/product/explorer.js +32 -10
- package/config/product/manager.js +28 -17
- package/config/product/uiplugins.js +13 -10
- package/config/router/navigation-guards/index.js +61 -3
- package/detail/node.vue +28 -23
- package/dialog/AddCustomBadgeDialog.vue +17 -9
- package/dialog/RollbackWorkloadDialog.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
- package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
- package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
- package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
- package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
- package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
- package/edit/configmap.vue +4 -0
- package/edit/logging-flow/index.vue +1 -2
- package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +3 -3
- package/edit/logging.banzaicloud.io.output/providers/azurestorage.vue +19 -19
- package/edit/logging.banzaicloud.io.output/providers/cloudwatch.vue +23 -23
- package/edit/logging.banzaicloud.io.output/providers/datadog.vue +19 -19
- package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +14 -14
- package/edit/logging.banzaicloud.io.output/providers/forward.vue +12 -12
- package/edit/logging.banzaicloud.io.output/providers/gcs.vue +23 -23
- package/edit/logging.banzaicloud.io.output/providers/gelf.vue +6 -6
- package/edit/logging.banzaicloud.io.output/providers/kafka.vue +10 -10
- package/edit/logging.banzaicloud.io.output/providers/kinesisStream.vue +8 -8
- package/edit/logging.banzaicloud.io.output/providers/logdna.vue +17 -17
- package/edit/logging.banzaicloud.io.output/providers/logz.vue +7 -7
- package/edit/logging.banzaicloud.io.output/providers/loki.vue +12 -12
- package/edit/logging.banzaicloud.io.output/providers/newrelic.vue +3 -3
- package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +14 -14
- package/edit/logging.banzaicloud.io.output/providers/redis.vue +6 -6
- package/edit/logging.banzaicloud.io.output/providers/s3.vue +23 -23
- package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +13 -13
- package/edit/logging.banzaicloud.io.output/providers/sumologic.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/syslog.vue +54 -54
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +32 -8
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +32 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +52 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +45 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +31 -0
- package/edit/networking.k8s.io.ingress/Certificate.vue +14 -5
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
- package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
- package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
- package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
- package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
- package/edit/persistentvolume/index.vue +3 -1
- package/edit/persistentvolumeclaim.vue +2 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -1
- package/edit/secret/index.vue +2 -2
- package/edit/service.vue +4 -1
- package/edit/storage.k8s.io.storageclass/index.vue +10 -8
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
- package/edit/workload/Job.vue +31 -34
- package/edit/workload/Upgrading.vue +5 -5
- package/edit/workload/index.vue +19 -15
- package/edit/workload/storage/Mount.vue +1 -0
- package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
- package/edit/workload/storage/azureDisk.vue +14 -10
- package/edit/workload/storage/azureFile.vue +9 -7
- package/edit/workload/storage/csi/index.vue +6 -9
- package/edit/workload/storage/emptyDir.vue +7 -5
- package/edit/workload/storage/gcePersistentDisk.vue +9 -7
- package/edit/workload/storage/hostPath.vue +7 -5
- package/edit/workload/storage/nfs.vue +8 -6
- package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
- package/edit/workload/storage/secret.vue +9 -6
- package/edit/workload/storage/vsphereVolume.vue +11 -7
- package/initialize/app-extended.js +7 -1
- package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +8 -6
- package/mixins/create-edit-view/impl.js +10 -0
- package/models/provisioning.cattle.io.cluster.js +19 -18
- package/models/workload.js +2 -2
- package/package.json +1 -1
- package/pages/account/index.vue +93 -58
- package/pages/auth/setup.vue +36 -17
- package/pages/c/_cluster/auth/roles/index.vue +27 -3
- package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +2 -1
- package/pages/c/_cluster/explorer/tools/index.vue +6 -6
- package/pages/home.vue +55 -13
- package/plugins/dashboard-store/actions.js +1 -1
- package/rancher-components/Banner/Banner.vue +14 -2
- package/rancher-components/Form/Radio/RadioGroup.vue +9 -1
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +31 -2
- package/scripts/build-pkg.sh +18 -23
- package/scripts/publish-shell.sh +1 -1
- package/store/i18n.js +1 -0
- package/store/index.js +4 -4
- package/store/type-map.js +0 -2
- package/types/shell/index.d.ts +8 -0
- package/utils/error.js +23 -3
- package/utils/errorTranslate.json +402 -8
- package/utils/errorTranslateNew.json +39 -0
- package/utils/roleFiltering.js +33 -0
|
@@ -16,25 +16,19 @@ const store = useStore();
|
|
|
16
16
|
const i18n = useI18n(store);
|
|
17
17
|
</script>
|
|
18
18
|
<template>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
:initial-value="props.resource"
|
|
33
|
-
:use-tabbed-hash="false /* Have to disable hashing on child components or it modifies the url and closes the drawer */"
|
|
34
|
-
as="config"
|
|
35
|
-
/>
|
|
36
|
-
</div>
|
|
37
|
-
</Tab>
|
|
19
|
+
<div class="container">
|
|
20
|
+
<component
|
|
21
|
+
:is="props.component"
|
|
22
|
+
:value="props.resource"
|
|
23
|
+
:liveValue="props.resource"
|
|
24
|
+
:resourceType="props.resourceType"
|
|
25
|
+
:mode="_VIEW"
|
|
26
|
+
:real-mode="_VIEW"
|
|
27
|
+
:initial-value="props.resource"
|
|
28
|
+
:use-tabbed-hash="false /* Have to disable hashing on child components or it modifies the url and closes the drawer */"
|
|
29
|
+
as="config"
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
38
32
|
</template>
|
|
39
33
|
|
|
40
34
|
<style lang="scss" scoped>
|
|
@@ -45,6 +39,15 @@ const i18n = useI18n(store);
|
|
|
45
39
|
max-width: 100%;
|
|
46
40
|
width: 100%;
|
|
47
41
|
position: relative;
|
|
42
|
+
// Handle the loading indicator
|
|
43
|
+
:deep() .overlay-content-mode {
|
|
44
|
+
left: 0;
|
|
45
|
+
top: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:deep() .cru-resource-footer {
|
|
49
|
+
display: none;
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
.config-tab {
|
|
50
53
|
|
|
@@ -3,7 +3,7 @@ import Drawer from '@shell/components/Drawer/Chrome.vue';
|
|
|
3
3
|
import { useI18n } from '@shell/composables/useI18n';
|
|
4
4
|
import { useStore } from 'vuex';
|
|
5
5
|
import Tabbed from '@shell/components/Tabbed/index.vue';
|
|
6
|
-
import YamlTab, { Props as YamlProps } from '@shell/components/Drawer/ResourceDetailDrawer/YamlTab.vue';
|
|
6
|
+
// import YamlTab, { Props as YamlProps } from '@shell/components/Drawer/ResourceDetailDrawer/YamlTab.vue';
|
|
7
7
|
import { useDefaultConfigTabProps, useDefaultYamlTabProps } from '@shell/components/Drawer/ResourceDetailDrawer/composables';
|
|
8
8
|
import ConfigTab from '@shell/components/Drawer/ResourceDetailDrawer/ConfigTab.vue';
|
|
9
9
|
import { computed, ref } from 'vue';
|
|
@@ -87,10 +87,10 @@ const canEdit = computed(() => {
|
|
|
87
87
|
v-if="configTabProps"
|
|
88
88
|
v-bind="configTabProps"
|
|
89
89
|
/>
|
|
90
|
-
<YamlTab
|
|
90
|
+
<!-- <YamlTab
|
|
91
91
|
v-if="yamlTabProps"
|
|
92
92
|
v-bind="yamlTabProps"
|
|
93
|
-
/>
|
|
93
|
+
/> -->
|
|
94
94
|
</Tabbed>
|
|
95
95
|
</template>
|
|
96
96
|
<template #additional-actions>
|
|
@@ -115,6 +115,10 @@ export default {
|
|
|
115
115
|
labelKey: 'tableHeaders.role',
|
|
116
116
|
value: 'roleTemplate.nameDisplay'
|
|
117
117
|
},
|
|
118
|
+
{
|
|
119
|
+
name: '操作',
|
|
120
|
+
labelKey: 'tableHeaders.action',
|
|
121
|
+
},
|
|
118
122
|
],
|
|
119
123
|
loadingProjectBindings: true,
|
|
120
124
|
loadingClusterBindings: true
|
|
@@ -361,12 +365,13 @@ export default {
|
|
|
361
365
|
v-trim-whitespace
|
|
362
366
|
class="group-tab"
|
|
363
367
|
>
|
|
368
|
+
|
|
364
369
|
<div
|
|
365
370
|
v-clean-html="getProjectLabel(group)"
|
|
366
371
|
class="project-name"
|
|
367
372
|
/>
|
|
368
373
|
</div>
|
|
369
|
-
<div class="right">
|
|
374
|
+
<div class="right" style="margin-right: 80px;">
|
|
370
375
|
<button
|
|
371
376
|
v-if="canEditProjectMembers"
|
|
372
377
|
type="button"
|
|
@@ -460,8 +465,12 @@ export default {
|
|
|
460
465
|
& :deep() .group-bar{
|
|
461
466
|
display: flex;
|
|
462
467
|
justify-content: space-between;
|
|
468
|
+
align-items: center;
|
|
463
469
|
}
|
|
464
470
|
}
|
|
471
|
+
.role-secondary.btn-sm:focus, .role-secondary.btn-sm.focused{
|
|
472
|
+
border: 1px solid #d7d7d7;
|
|
473
|
+
}
|
|
465
474
|
.cluster-add {
|
|
466
475
|
justify-content: flex-end;
|
|
467
476
|
}
|
|
@@ -103,23 +103,36 @@ export default {
|
|
|
103
103
|
this.sortedRoles.global.push(...remainingGlobalRoles);
|
|
104
104
|
// End sort of global roles
|
|
105
105
|
|
|
106
|
+
if (!(sessionStorage.getItem('TOPLEVELPERMISSIONS') && sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin')) {
|
|
107
|
+
delete this.sortedRoles.builtin
|
|
108
|
+
delete this.sortedRoles.custom
|
|
109
|
+
}
|
|
110
|
+
|
|
106
111
|
this.update();
|
|
107
112
|
}
|
|
108
113
|
} catch (e) { }
|
|
109
114
|
},
|
|
110
115
|
data() {
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
let globalPermissions = [
|
|
118
|
+
'admin',
|
|
119
|
+
'safe-admin',
|
|
120
|
+
'tenant',
|
|
121
|
+
]
|
|
116
122
|
|
|
117
|
-
|
|
118
|
-
globalPermissions
|
|
123
|
+
if (sessionStorage.getItem('TOPLEVELPERMISSIONS') === 'superadmin') {
|
|
124
|
+
globalPermissions = [
|
|
119
125
|
'admin',
|
|
126
|
+
'safe-admin',
|
|
120
127
|
'user',
|
|
121
128
|
'user-base',
|
|
122
|
-
|
|
129
|
+
'tenant',
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
// This not only identifies global roles but the order here is the order we want to display them in the UI
|
|
135
|
+
globalPermissions,
|
|
123
136
|
globalRoleBindings: null,
|
|
124
137
|
sortedRoles: null,
|
|
125
138
|
selectedRoles: [],
|
|
@@ -333,119 +346,60 @@ export default {
|
|
|
333
346
|
|
|
334
347
|
<div v-else>
|
|
335
348
|
<form v-if="selectedRoles">
|
|
336
|
-
<
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
:show-actions="false"
|
|
346
|
-
>
|
|
347
|
-
<template v-slot:title>
|
|
348
|
-
<div class="type-title">
|
|
349
|
-
<h3>{{ t(`rbac.globalRoles.types.${roleType}.label`) }}</h3>
|
|
350
|
-
<div class="type-description">
|
|
351
|
-
{{ t(`rbac.globalRoles.types.${roleType}.description`, { isUser }) }}
|
|
352
|
-
</div>
|
|
353
|
-
</div>
|
|
354
|
-
</template>
|
|
355
|
-
<template v-slot:body>
|
|
356
|
-
<div
|
|
357
|
-
class="checkbox-section"
|
|
358
|
-
:class="'checkbox-section--' + roleType"
|
|
359
|
-
>
|
|
360
|
-
<div
|
|
361
|
-
v-for="(role, i) in sortedRoles[roleType]"
|
|
362
|
-
:key="i"
|
|
363
|
-
class="checkbox mb-10 mr-10"
|
|
364
|
-
>
|
|
365
|
-
<Checkbox
|
|
366
|
-
v-model:value="selectedRoles"
|
|
367
|
-
:value-when-true="role.id"
|
|
368
|
-
:disabled="!!assignOnlyRoles[role.id]"
|
|
369
|
-
:label="role.nameDisplay"
|
|
370
|
-
:description="role.descriptionDisplay"
|
|
371
|
-
:mode="mode"
|
|
372
|
-
:data-testId="'grb-checkbox-' + role.id"
|
|
373
|
-
@update:value="checkboxChanged"
|
|
374
|
-
>
|
|
375
|
-
<template #label>
|
|
376
|
-
<div class="checkbox-label-slot">
|
|
377
|
-
<span class="checkbox-label">{{ role.nameDisplay }}</span>
|
|
378
|
-
<i
|
|
379
|
-
v-if="!!assignOnlyRoles[role.id]"
|
|
380
|
-
v-clean-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
381
|
-
class="checkbox-info icon icon-info icon-lg"
|
|
382
|
-
/>
|
|
383
|
-
</div>
|
|
384
|
-
</template>
|
|
385
|
-
</Checkbox>
|
|
386
|
-
</div>
|
|
387
|
-
</div>
|
|
388
|
-
</template>
|
|
389
|
-
</Card>
|
|
390
|
-
</div>
|
|
391
|
-
</template>
|
|
392
|
-
|
|
393
|
-
<template v-else>
|
|
394
|
-
<div
|
|
395
|
-
v-for="(sortedRole, roleType) in { global: sortedRoles['global'] }"
|
|
396
|
-
:key="roleType"
|
|
397
|
-
class="role-group mb-10"
|
|
349
|
+
<div
|
|
350
|
+
v-for="(sortedRole, roleType) in sortedRoles"
|
|
351
|
+
:key="roleType"
|
|
352
|
+
class="role-group mb-10"
|
|
353
|
+
>
|
|
354
|
+
<Card
|
|
355
|
+
v-if="Object.keys(sortedRole).length"
|
|
356
|
+
:show-highlight-border="false"
|
|
357
|
+
:show-actions="false"
|
|
398
358
|
>
|
|
399
|
-
<
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
<template v-slot:title>
|
|
405
|
-
<div class="type-title">
|
|
406
|
-
<h3>{{ t(`rbac.globalRoles.types.${roleType}.label`) }}</h3>
|
|
407
|
-
<div class="type-description">
|
|
408
|
-
{{ t(`rbac.globalRoles.types.${roleType}.description`, { isUser }) }}
|
|
409
|
-
</div>
|
|
359
|
+
<template v-slot:title>
|
|
360
|
+
<div class="type-title">
|
|
361
|
+
<h3>{{ t(`rbac.globalRoles.types.${roleType}.label`) }}</h3>
|
|
362
|
+
<div class="type-description">
|
|
363
|
+
{{ t(`rbac.globalRoles.types.${roleType}.description`, { isUser }) }}
|
|
410
364
|
</div>
|
|
411
|
-
</
|
|
412
|
-
|
|
365
|
+
</div>
|
|
366
|
+
</template>
|
|
367
|
+
<template v-slot:body>
|
|
368
|
+
<div
|
|
369
|
+
class="checkbox-section"
|
|
370
|
+
:class="'checkbox-section--' + roleType"
|
|
371
|
+
>
|
|
413
372
|
<div
|
|
414
|
-
|
|
415
|
-
:
|
|
373
|
+
v-for="(role, i) in sortedRoles[roleType]"
|
|
374
|
+
:key="i"
|
|
375
|
+
class="checkbox mb-10 mr-10"
|
|
416
376
|
>
|
|
417
|
-
<
|
|
418
|
-
v-
|
|
419
|
-
:
|
|
420
|
-
|
|
377
|
+
<Checkbox
|
|
378
|
+
v-model:value="selectedRoles"
|
|
379
|
+
:value-when-true="role.id"
|
|
380
|
+
:disabled="!!assignOnlyRoles[role.id]"
|
|
381
|
+
:label="role.nameDisplay"
|
|
382
|
+
:description="role.descriptionDisplay"
|
|
383
|
+
:mode="mode"
|
|
384
|
+
:data-testId="'grb-checkbox-' + role.id"
|
|
385
|
+
@update:value="checkboxChanged"
|
|
421
386
|
>
|
|
422
|
-
<
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
>
|
|
432
|
-
|
|
433
|
-
<div class="checkbox-label-slot">
|
|
434
|
-
<span class="checkbox-label">{{ role.nameDisplay }}</span>
|
|
435
|
-
<i
|
|
436
|
-
v-if="!!assignOnlyRoles[role.id]"
|
|
437
|
-
v-clean-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
438
|
-
class="checkbox-info icon icon-info icon-lg"
|
|
439
|
-
/>
|
|
440
|
-
</div>
|
|
441
|
-
</template>
|
|
442
|
-
</Checkbox>
|
|
443
|
-
</div>
|
|
387
|
+
<template #label>
|
|
388
|
+
<div class="checkbox-label-slot">
|
|
389
|
+
<span class="checkbox-label">{{ role.nameDisplay }}</span>
|
|
390
|
+
<i
|
|
391
|
+
v-if="!!assignOnlyRoles[role.id]"
|
|
392
|
+
v-clean-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
393
|
+
class="checkbox-info icon icon-info icon-lg"
|
|
394
|
+
/>
|
|
395
|
+
</div>
|
|
396
|
+
</template>
|
|
397
|
+
</Checkbox>
|
|
444
398
|
</div>
|
|
445
|
-
</
|
|
446
|
-
</
|
|
447
|
-
</
|
|
448
|
-
</
|
|
399
|
+
</div>
|
|
400
|
+
</template>
|
|
401
|
+
</Card>
|
|
402
|
+
</div>
|
|
449
403
|
</form>
|
|
450
404
|
</div>
|
|
451
405
|
</template>
|
|
@@ -490,4 +444,5 @@ export default {
|
|
|
490
444
|
}
|
|
491
445
|
}
|
|
492
446
|
}
|
|
447
|
+
|
|
493
448
|
</style>
|
|
@@ -83,6 +83,22 @@ export default {
|
|
|
83
83
|
return this.$store.getters['type-map/labelFor'](schema, this.toRemove.length);
|
|
84
84
|
},
|
|
85
85
|
|
|
86
|
+
typeZh() {
|
|
87
|
+
const typeLabel = this.type
|
|
88
|
+
|
|
89
|
+
const lowerKey = typeLabel.toLowerCase();
|
|
90
|
+
const i18nKey = `promptRemoveText.${lowerKey}`;
|
|
91
|
+
|
|
92
|
+
console.log(i18nKey, ' i18nKey-------------------------');
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if (this.t(i18nKey)) {
|
|
96
|
+
return this.t(i18nKey);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return typeLabel;
|
|
100
|
+
},
|
|
101
|
+
|
|
86
102
|
selfLinks() {
|
|
87
103
|
return this.toRemove.map((resource) => {
|
|
88
104
|
return get(resource, 'links.self');
|
|
@@ -296,6 +312,12 @@ export default {
|
|
|
296
312
|
this.done();
|
|
297
313
|
} catch (err) {
|
|
298
314
|
this.error = err.message || err;
|
|
315
|
+
if (this.error.includes('not supported')) {
|
|
316
|
+
this.$store.dispatch('growl/error', {
|
|
317
|
+
title: '权限不足',
|
|
318
|
+
message: '当前用户不允许删除集群'
|
|
319
|
+
}, { root: true });
|
|
320
|
+
}
|
|
299
321
|
btnCB(false);
|
|
300
322
|
}
|
|
301
323
|
},
|
|
@@ -380,7 +402,7 @@ export default {
|
|
|
380
402
|
:needs-confirm="needsConfirm"
|
|
381
403
|
:value="toRemove"
|
|
382
404
|
:names="names"
|
|
383
|
-
:type="
|
|
405
|
+
:type="typeZh"
|
|
384
406
|
:done-location="doneLocation"
|
|
385
407
|
@errors="e => error = e"
|
|
386
408
|
@done="done"
|
|
@@ -14,7 +14,22 @@ export const useDefaultTitleBarProps = (resource: any, resourceSubtype?: Ref<str
|
|
|
14
14
|
const resourceSubtypeValue = toValue(resourceSubtype);
|
|
15
15
|
const currentStore = store.getters['currentStore'](resourceValue.type);
|
|
16
16
|
const schema = store.getters[`${ currentStore }/schemaFor`](resourceValue.type);
|
|
17
|
-
|
|
17
|
+
let resourceTypeLabel = resourceValue.parentNameOverride || store.getters['type-map/labelFor'](schema);
|
|
18
|
+
|
|
19
|
+
// 转换为中文
|
|
20
|
+
const displayName_zh_hans: Record<string, string> = {
|
|
21
|
+
'GlobalRole': '全局角色',
|
|
22
|
+
'RoleTemplate': '集群角色',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (displayName_zh_hans[resourceTypeLabel]) {
|
|
26
|
+
resourceTypeLabel = displayName_zh_hans[resourceTypeLabel]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (resourceTypeLabel == '集群角色' && (route.query?.roleContext == 'NAMESPACE' || resource?.parentLocationOverride?.hash == '#NAMESPACE')) {
|
|
30
|
+
resourceTypeLabel = '项目或资源组角色'
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
const resourceName = resourceSubtypeValue ? `${ resourceSubtypeValue } - ${ resourceValue.nameDisplay }` : resourceValue.nameDisplay;
|
|
19
34
|
const resourceTo = resourceValue.listLocation || {
|
|
20
35
|
name: 'c-cluster-product-resource',
|
|
@@ -38,7 +38,6 @@ export interface TitleBarProps {
|
|
|
38
38
|
showViewOptions?: boolean;
|
|
39
39
|
|
|
40
40
|
onShowConfiguration?: (returnFocusSelector: string) => void;
|
|
41
|
-
value?: any;
|
|
42
41
|
parentRouteOverride?: string;
|
|
43
42
|
}
|
|
44
43
|
|
|
@@ -47,9 +46,10 @@ const showConfigurationIcon = require(`@shell/assets/images/icons/document.svg`)
|
|
|
47
46
|
|
|
48
47
|
<script setup lang="ts">
|
|
49
48
|
const {
|
|
50
|
-
parentRouteOverride,
|
|
49
|
+
parentRouteOverride, resource, resourceTypeLabel, resourceTo, resourceName, description, badge, showViewOptions, onShowConfiguration,
|
|
51
50
|
} = defineProps<TitleBarProps>();
|
|
52
51
|
|
|
52
|
+
|
|
53
53
|
const store = useStore();
|
|
54
54
|
const i18n = useI18n(store);
|
|
55
55
|
const router = useRouter();
|
|
@@ -61,8 +61,6 @@ const showConfigurationReturnFocusSelector = computed(() => `[data-testid="${ sh
|
|
|
61
61
|
|
|
62
62
|
const configTabProps = useDefaultConfigTabProps(resource);
|
|
63
63
|
|
|
64
|
-
console.log(configTabProps, ' configTabProps---------------------------------1');
|
|
65
|
-
|
|
66
64
|
|
|
67
65
|
const currentView = ref(router?.currentRoute?.value?.query?.as || _CONFIG);
|
|
68
66
|
const viewOptions = computed(() => {
|
|
@@ -84,39 +82,42 @@ const viewOptions = computed(() => {
|
|
|
84
82
|
|
|
85
83
|
const Svg = require('~shell/assets/images/API.svg')
|
|
86
84
|
|
|
87
|
-
const parent = computed(() =>{
|
|
88
|
-
|
|
85
|
+
const parent = computed(() => {
|
|
86
|
+
|
|
89
87
|
const product = store.getters['currentProduct'].name;
|
|
90
88
|
|
|
91
89
|
const defaultLocation = {
|
|
92
|
-
name:
|
|
90
|
+
name: 'c-cluster-product-resource',
|
|
93
91
|
params: {
|
|
94
|
-
resource
|
|
92
|
+
resource,
|
|
95
93
|
product,
|
|
96
94
|
}
|
|
97
95
|
};
|
|
98
96
|
|
|
99
|
-
const location =
|
|
97
|
+
const location = resource?.parentLocationOverride || defaultLocation;
|
|
100
98
|
|
|
101
99
|
if (parentRouteOverride) {
|
|
102
100
|
location.name = parentRouteOverride;
|
|
103
101
|
}
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
return out;
|
|
110
|
-
})
|
|
103
|
+
return { location };
|
|
104
|
+
});
|
|
111
105
|
|
|
112
106
|
const menuIcon = computed(() => {
|
|
113
107
|
const product = store.getters['productId'];
|
|
108
|
+
const resources = parent.value.location?.params?.resource || '';
|
|
109
|
+
return store.getters['type-map/groupsForVirTypes'](product, resources) || 'default menuIcon';
|
|
110
|
+
});
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
})
|
|
112
|
+
const hiddenTypes = [
|
|
113
|
+
'harvesterhci.io.virtualmachinebackup',
|
|
114
|
+
];
|
|
119
115
|
|
|
116
|
+
const shouldShowConfiguration = computed(() =>
|
|
117
|
+
onShowConfiguration &&
|
|
118
|
+
configTabProps &&
|
|
119
|
+
!hiddenTypes.includes(resource?.type)
|
|
120
|
+
);
|
|
120
121
|
|
|
121
122
|
watch(
|
|
122
123
|
() => currentView.value,
|
|
@@ -128,10 +129,10 @@ watch(
|
|
|
128
129
|
|
|
129
130
|
<template>
|
|
130
131
|
<div class="title-bar">
|
|
131
|
-
<breadcrumb :resource="resource"/>
|
|
132
|
+
<breadcrumb :resourceTypeLabel="resourceTypeLabel" :resource="resource"/>
|
|
132
133
|
<Top>
|
|
133
134
|
<Title class="title">
|
|
134
|
-
<span
|
|
135
|
+
<span class="detailIcon-span">
|
|
135
136
|
<img
|
|
136
137
|
v-if="parentRouteOverride === 'account' && resource=== 'token'"
|
|
137
138
|
:src="Svg"
|
|
@@ -189,18 +190,18 @@ watch(
|
|
|
189
190
|
:options="viewOptions"
|
|
190
191
|
/>
|
|
191
192
|
<RcButton
|
|
192
|
-
v-if="
|
|
193
|
+
v-if="shouldShowConfiguration"
|
|
193
194
|
:data-testid="showConfigurationDataTestId"
|
|
194
195
|
class="show-configuration"
|
|
195
196
|
:primary="true"
|
|
196
197
|
:aria-label="i18n.t('component.resource.detail.titleBar.ariaLabel.showConfiguration', { resource: resourceName })"
|
|
197
198
|
@click="() => emit('show-configuration', showConfigurationReturnFocusSelector)"
|
|
198
199
|
>
|
|
199
|
-
|
|
200
|
+
<!-- <img
|
|
200
201
|
:src="showConfigurationIcon"
|
|
201
202
|
class="mmr-3"
|
|
202
203
|
aria-hidden="true"
|
|
203
|
-
>
|
|
204
|
+
> -->
|
|
204
205
|
{{ i18n.t('component.resource.detail.titleBar.showConfiguration') }}
|
|
205
206
|
</RcButton>
|
|
206
207
|
<ActionMenu
|
|
@@ -222,6 +223,7 @@ watch(
|
|
|
222
223
|
</template>
|
|
223
224
|
|
|
224
225
|
<style lang="scss" scoped>
|
|
226
|
+
|
|
225
227
|
.detailIcon-span{
|
|
226
228
|
width: 24px;
|
|
227
229
|
height: 24px;
|
|
@@ -230,6 +232,17 @@ watch(
|
|
|
230
232
|
background: var(--primary);
|
|
231
233
|
margin-right: 10px;
|
|
232
234
|
}
|
|
235
|
+
.detailIcon{
|
|
236
|
+
position: absolute;
|
|
237
|
+
color: #fff;
|
|
238
|
+
font-size: 38px;
|
|
239
|
+
left: 4px;
|
|
240
|
+
top: -2px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.detailIcon-span-title{
|
|
244
|
+
font-weight: bold;
|
|
245
|
+
}
|
|
233
246
|
.resourceTypeLabelCls {
|
|
234
247
|
font-weight: 700;
|
|
235
248
|
}
|
|
@@ -254,7 +254,7 @@ export default {
|
|
|
254
254
|
},
|
|
255
255
|
|
|
256
256
|
parent() {
|
|
257
|
-
|
|
257
|
+
let displayName = this.value?.parentNameOverride || this.$store.getters['type-map/labelFor'](this.schema);
|
|
258
258
|
const product = this.$store.getters['currentProduct'].name;
|
|
259
259
|
|
|
260
260
|
const defaultLocation = {
|
|
@@ -418,14 +418,14 @@ export default {
|
|
|
418
418
|
demoDisplay() {
|
|
419
419
|
const product = this.$store.getters['productId'];
|
|
420
420
|
|
|
421
|
-
const resources = this.location?.params?.resource || ''
|
|
421
|
+
const resources = this.location?.params?.resource || this.$route.params?.resource || ''
|
|
422
422
|
|
|
423
423
|
const productId = this.$store.getters['type-map/groupForBasicType'](this.$store.getters['productId'], resources);
|
|
424
424
|
|
|
425
425
|
if (productId === undefined) {
|
|
426
426
|
return '';
|
|
427
427
|
}
|
|
428
|
-
const parts = productId
|
|
428
|
+
const parts = productId?.split('::') || [];
|
|
429
429
|
const newString = 'root';
|
|
430
430
|
|
|
431
431
|
if (!parts?.includes(newString)) {
|
|
@@ -441,9 +441,10 @@ export default {
|
|
|
441
441
|
menuIcon() {
|
|
442
442
|
const product = this.$store.getters['productId'];
|
|
443
443
|
|
|
444
|
-
const resources = this.location?.params?.resource || ''
|
|
444
|
+
const resources = this.location?.params?.resource || this.$route.params?.resource || ''
|
|
445
445
|
|
|
446
|
-
|
|
446
|
+
|
|
447
|
+
return this.$store.getters['type-map/groupsForVirTypes'](product, resources) || 'default menuIcon';
|
|
447
448
|
},
|
|
448
449
|
|
|
449
450
|
location() {
|
|
@@ -506,7 +507,7 @@ export default {
|
|
|
506
507
|
<span>/</span>
|
|
507
508
|
</span>
|
|
508
509
|
<span class="excram-last-name">
|
|
509
|
-
{{ (realMode === 'view'? '查看': realMode === 'edit' ? '编辑':'创建') + parent
|
|
510
|
+
{{ (realMode === 'view'? '查看': realMode === 'edit' ? '编辑':'创建') + parent?.displayName }}
|
|
510
511
|
</span>
|
|
511
512
|
</div>
|
|
512
513
|
<header>
|
|
@@ -530,7 +531,7 @@ export default {
|
|
|
530
531
|
:class="'icon-'+ menuIcon + ' detailIcon'"
|
|
531
532
|
/>
|
|
532
533
|
</span>
|
|
533
|
-
<span class="detailIcon-span-title">{{ realMode=== 'create'? '创建': '' }}{{ parent
|
|
534
|
+
<span class="detailIcon-span-title">{{ realMode=== 'create'? '创建': '' }}{{ parent?.displayName }}{{ realMode=== 'create'? '': '名称:' }}</span>
|
|
534
535
|
<span v-if="realMode !== 'create'">
|
|
535
536
|
<span v-if="value.detailPageHeaderActionOverride && value.detailPageHeaderActionOverride(realMode)">{{ value.detailPageHeaderActionOverride(realMode) }}</span>
|
|
536
537
|
<t
|