dashboard-shell-shell 3.0.5-test.8 → 3.0.5-tsh.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/brand/csp/favicon.png +0 -0
- package/assets/icons/iconfont.css +4 -1
- package/assets/images/pl/dark/logo.png +0 -0
- package/assets/styles/all.scss +23 -3
- 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 +60 -0
- package/assets/translations/zh-hans.yaml +164 -21
- 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 +52 -112
- 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 +11 -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/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 +31 -28
- package/components/form/Members/MembershipEditor.vue +3 -3
- package/components/form/Members/ProjectMembershipEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +4 -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 +28 -25
- 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/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 +6 -0
- package/components/nav/Header.vue +17 -137
- package/components/nav/NamespaceFilter.vue +14 -19
- package/components/nav/TopLevelMenu.vue +99 -125
- 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/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/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +32 -8
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +24 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +39 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +32 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +16 -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/login.vue +1 -1
- package/pages/auth/setup.vue +36 -17
- 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/pkg/tsconfig.json +9 -9
- package/pkg/vue.config.js +1 -1
- 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/type-map.js +0 -2
- package/utils/error.js +23 -3
- package/utils/errorTranslate.json +377 -8
- package/utils/errorTranslateNew.json +39 -0
- package/vue.config.js +1 -1
|
@@ -323,12 +323,12 @@ export default {
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
&.as-text-area .codemirror-container{
|
|
326
|
-
min-height:
|
|
326
|
+
min-height: 32px !important;
|
|
327
327
|
position: relative;
|
|
328
328
|
display: block;
|
|
329
329
|
box-sizing: border-box;
|
|
330
330
|
width: 100%;
|
|
331
|
-
padding: 10px;
|
|
331
|
+
padding: 8px 10px 0 10px !important;
|
|
332
332
|
background-color: var(--input-bg);
|
|
333
333
|
border-radius: var(--border-radius);
|
|
334
334
|
border: solid var(--border-width) var(--input-border);
|
|
@@ -418,7 +418,7 @@ export default {
|
|
|
418
418
|
|
|
419
419
|
.code-mirror {
|
|
420
420
|
position: relative;
|
|
421
|
-
margin-bottom:
|
|
421
|
+
margin-bottom: 0 !important;
|
|
422
422
|
|
|
423
423
|
.escape-text {
|
|
424
424
|
font-size: 12px;
|
|
@@ -498,5 +498,7 @@ export default {
|
|
|
498
498
|
}
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
|
-
|
|
501
|
+
.CodeMirror-scroll {
|
|
502
|
+
min-height: 350px;
|
|
503
|
+
}
|
|
502
504
|
</style>
|
|
@@ -135,7 +135,7 @@ export default {
|
|
|
135
135
|
:amountTemplateValues="amountTemplateValues"
|
|
136
136
|
:formattedPercentage="formattedPercentage"
|
|
137
137
|
>
|
|
138
|
-
<p>{{ formattedPercentage + '(共' + amountTemplateValues.total + ' ' + amountTemplateValues.unit + ',' + reserveText + ' ' + amountTemplateValues.used + ' ' + amountTemplateValues.unit + ')' }}</p>
|
|
138
|
+
<p>{{ formattedPercentage + '(共' + (amountTemplateValues.total || 0) + ' ' + (amountTemplateValues.unit || 'GiB') + ',' + (reserveText || '') + ' ' + (amountTemplateValues.used || 0) + ' ' + (amountTemplateValues.unit || 'GiB') + ')' }}</p>
|
|
139
139
|
</slot>
|
|
140
140
|
</div>
|
|
141
141
|
</template>
|
|
@@ -177,7 +177,7 @@ export default {
|
|
|
177
177
|
</div>
|
|
178
178
|
</div>
|
|
179
179
|
|
|
180
|
-
<div class="row
|
|
180
|
+
<div class="row">
|
|
181
181
|
<span class="col span-6">
|
|
182
182
|
<UnitInput
|
|
183
183
|
v-model:value="requestsCpu"
|
|
@@ -206,7 +206,7 @@ export default {
|
|
|
206
206
|
</span>
|
|
207
207
|
</div>
|
|
208
208
|
|
|
209
|
-
<div class="row
|
|
209
|
+
<div class="row">
|
|
210
210
|
<span class="col span-6">
|
|
211
211
|
<UnitInput
|
|
212
212
|
v-model:value="limitsCpu"
|
|
@@ -623,13 +623,14 @@ export default {
|
|
|
623
623
|
/>
|
|
624
624
|
<span v-else>{{ subtype.label }}</span>
|
|
625
625
|
</h5>
|
|
626
|
-
|
|
626
|
+
<!-- 禅道 3541 隐藏 更多信息 -->
|
|
627
|
+
<!-- <a
|
|
627
628
|
v-if="subtype.docLink"
|
|
628
629
|
:href="subtype.docLink"
|
|
629
630
|
target="_blank"
|
|
630
631
|
rel="noopener nofollow"
|
|
631
632
|
class="flex-right"
|
|
632
|
-
>{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a>
|
|
633
|
+
>{{ t('generic.moreInfo') }} <i class="icon icon-external-link" /></a> -->
|
|
633
634
|
</div>
|
|
634
635
|
<hr
|
|
635
636
|
v-if="subtype.description"
|
|
@@ -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,17 +103,15 @@ export default {
|
|
|
103
103
|
this.sortedRoles.global.push(...remainingGlobalRoles);
|
|
104
104
|
// End sort of global roles
|
|
105
105
|
|
|
106
|
+
delete this.sortedRoles.builtin
|
|
107
|
+
delete this.sortedRoles.custom
|
|
108
|
+
|
|
106
109
|
this.update();
|
|
107
110
|
}
|
|
108
111
|
} catch (e) { }
|
|
109
112
|
},
|
|
110
113
|
data() {
|
|
111
|
-
|
|
112
|
-
const topLevelPermissions = sessionStorage.getItem('TOPLEVELPERMISSIONS') || ''
|
|
113
|
-
|
|
114
114
|
return {
|
|
115
|
-
topLevelPermissions,
|
|
116
|
-
|
|
117
115
|
// This not only identifies global roles but the order here is the order we want to display them in the UI
|
|
118
116
|
globalPermissions: [
|
|
119
117
|
'admin',
|
|
@@ -333,119 +331,60 @@ export default {
|
|
|
333
331
|
|
|
334
332
|
<div v-else>
|
|
335
333
|
<form v-if="selectedRoles">
|
|
336
|
-
<
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
334
|
+
<div
|
|
335
|
+
v-for="(sortedRole, roleType) in sortedRoles"
|
|
336
|
+
:key="roleType"
|
|
337
|
+
class="role-group mb-10"
|
|
338
|
+
>
|
|
339
|
+
<Card
|
|
340
|
+
v-if="Object.keys(sortedRole).length"
|
|
341
|
+
:show-highlight-border="false"
|
|
342
|
+
:show-actions="false"
|
|
341
343
|
>
|
|
342
|
-
<
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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>
|
|
344
|
+
<template v-slot:title>
|
|
345
|
+
<div class="type-title">
|
|
346
|
+
<h3>{{ t(`rbac.globalRoles.types.${roleType}.label`) }}</h3>
|
|
347
|
+
<div class="type-description">
|
|
348
|
+
{{ t(`rbac.globalRoles.types.${roleType}.description`, { isUser }) }}
|
|
353
349
|
</div>
|
|
354
|
-
</
|
|
355
|
-
|
|
350
|
+
</div>
|
|
351
|
+
</template>
|
|
352
|
+
<template v-slot:body>
|
|
353
|
+
<div
|
|
354
|
+
class="checkbox-section"
|
|
355
|
+
:class="'checkbox-section--' + roleType"
|
|
356
|
+
>
|
|
356
357
|
<div
|
|
357
|
-
|
|
358
|
-
:
|
|
358
|
+
v-for="(role, i) in sortedRoles[roleType]"
|
|
359
|
+
:key="i"
|
|
360
|
+
class="checkbox mb-10 mr-10"
|
|
359
361
|
>
|
|
360
|
-
<
|
|
361
|
-
v-
|
|
362
|
-
:
|
|
363
|
-
|
|
362
|
+
<Checkbox
|
|
363
|
+
v-model:value="selectedRoles"
|
|
364
|
+
:value-when-true="role.id"
|
|
365
|
+
:disabled="!!assignOnlyRoles[role.id]"
|
|
366
|
+
:label="role.nameDisplay"
|
|
367
|
+
:description="role.descriptionDisplay"
|
|
368
|
+
:mode="mode"
|
|
369
|
+
:data-testId="'grb-checkbox-' + role.id"
|
|
370
|
+
@update:value="checkboxChanged"
|
|
364
371
|
>
|
|
365
|
-
<
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
>
|
|
375
|
-
|
|
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"
|
|
398
|
-
>
|
|
399
|
-
<Card
|
|
400
|
-
v-if="Object.keys(sortedRole).length"
|
|
401
|
-
:show-highlight-border="false"
|
|
402
|
-
:show-actions="false"
|
|
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>
|
|
372
|
+
<template #label>
|
|
373
|
+
<div class="checkbox-label-slot">
|
|
374
|
+
<span class="checkbox-label">{{ role.nameDisplay }}</span>
|
|
375
|
+
<i
|
|
376
|
+
v-if="!!assignOnlyRoles[role.id]"
|
|
377
|
+
v-clean-tooltip="t('rbac.globalRoles.assignOnlyRole')"
|
|
378
|
+
class="checkbox-info icon icon-info icon-lg"
|
|
379
|
+
/>
|
|
380
|
+
</div>
|
|
381
|
+
</template>
|
|
382
|
+
</Checkbox>
|
|
410
383
|
</div>
|
|
411
|
-
</
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
:class="'checkbox-section--' + roleType"
|
|
416
|
-
>
|
|
417
|
-
<div
|
|
418
|
-
v-for="(role, i) in sortedRoles[roleType]"
|
|
419
|
-
:key="i"
|
|
420
|
-
class="checkbox mb-10 mr-10"
|
|
421
|
-
>
|
|
422
|
-
<Checkbox
|
|
423
|
-
v-model:value="selectedRoles"
|
|
424
|
-
:value-when-true="role.id"
|
|
425
|
-
:disabled="!!assignOnlyRoles[role.id]"
|
|
426
|
-
:label="role.nameDisplay"
|
|
427
|
-
:description="role.descriptionDisplay"
|
|
428
|
-
:mode="mode"
|
|
429
|
-
:data-testId="'grb-checkbox-' + role.id"
|
|
430
|
-
@update:value="checkboxChanged"
|
|
431
|
-
>
|
|
432
|
-
<template #label>
|
|
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>
|
|
444
|
-
</div>
|
|
445
|
-
</template>
|
|
446
|
-
</Card>
|
|
447
|
-
</div>
|
|
448
|
-
</template>
|
|
384
|
+
</div>
|
|
385
|
+
</template>
|
|
386
|
+
</Card>
|
|
387
|
+
</div>
|
|
449
388
|
</form>
|
|
450
389
|
</div>
|
|
451
390
|
</template>
|
|
@@ -490,4 +429,5 @@ export default {
|
|
|
490
429
|
}
|
|
491
430
|
}
|
|
492
431
|
}
|
|
432
|
+
|
|
493
433
|
</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
|
}
|