dashboard-shell-shell 1.0.112 → 1.0.113
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/.DS_Store +0 -0
- package/assets/icons/demo.css +539 -0
- package/assets/icons/demo_index.html +1131 -0
- package/assets/icons/iconfont.css +200 -0
- package/assets/icons/iconfont.js +1 -0
- package/assets/icons/iconfont.json +296 -0
- package/assets/icons/iconfont.ttf +0 -0
- package/assets/icons/iconfont.woff +0 -0
- package/assets/icons/iconfont.woff2 +0 -0
- package/assets/images/API.svg +3 -0
- package/assets/images/login/password.svg +20 -0
- package/assets/images/login/user.svg +6 -0
- package/assets/images/login-bg.png +0 -0
- package/assets/images/login-left.png +0 -0
- package/assets/images/login-logo.svg +19 -0
- package/assets/images/logo.png +0 -0
- package/assets/images/pl/harvester.png +0 -0
- package/assets/images/promp-yellow.svg +5 -0
- package/assets/images/user.png +0 -0
- package/assets/styles/all.scss +63 -0
- package/assets/styles/app.scss +2 -0
- package/assets/styles/base/_basic.scss +8 -2
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_typography.scss +2 -1
- package/assets/styles/base/_variables.scss +10 -2
- package/assets/styles/global/_button.scss +37 -25
- package/assets/styles/global/_columns.scss +3 -1
- package/assets/styles/global/_form.scss +45 -13
- package/assets/styles/global/_labeled-input.scss +50 -25
- package/assets/styles/global/_layout.scss +9 -3
- package/assets/styles/global/_select.scss +20 -13
- package/assets/styles/global/_table.scss +1 -1
- package/assets/styles/global/_tooltip.scss +47 -6
- package/assets/styles/themes/_dark.scss +1 -0
- package/assets/styles/themes/_light.scss +59 -46
- package/assets/styles/themes/_suse.scss +1 -0
- package/assets/styles/vendor/vue-select.scss +18 -7
- package/assets/translations/en-us.yaml +93 -12
- package/assets/translations/zh-hans.yaml +278 -141
- package/components/ActionDropdown.vue +1 -1
- package/components/ActionDropdownShell.vue +71 -0
- package/components/ActionMenu.vue +2 -2
- package/components/ActionMenuShell.vue +1 -0
- package/components/AppModal.vue +78 -6
- package/components/AssignTo.vue +25 -11
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/ButtonDropdown.vue +26 -4
- package/components/ButtonGroup.vue +4 -0
- package/components/ButtonMultiAction.vue +1 -0
- package/components/CommunityLinks.vue +3 -3
- package/components/ConsumptionGauge.vue +24 -5
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +12 -7
- package/components/CruResourceFooter.vue +2 -2
- package/components/DashboardOptions.vue +21 -15
- package/components/DetailText.vue +5 -0
- package/components/DisableAuthProviderModal.vue +1 -0
- package/components/DotState.vue +84 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +56 -14
- package/components/FixedBanner.vue +19 -12
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrafanaDashboard.vue +4 -4
- package/components/GrowlManager.vue +4 -1
- package/components/HardwareResourceGauge.vue +39 -3
- package/components/InfoBox.vue +3 -3
- package/components/InputOrDisplay.vue +28 -2
- package/components/LabelValue.vue +16 -1
- package/components/LandingPagePreference.vue +5 -3
- package/components/LocaleSelector.vue +39 -93
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +2 -0
- package/components/MoveModal.vue +1 -0
- package/components/PromptChangePassword.vue +1 -1
- package/components/PromptModal.vue +15 -2
- package/components/PromptRemove.vue +28 -8
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +188 -43
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +49 -14
- package/components/ResourceList/Masthead.vue +80 -18
- package/components/ResourceTable.vue +60 -19
- package/components/SideNav.vue +32 -12
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +34 -5
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +649 -142
- package/components/SortableTable/paging.js +36 -28
- package/components/SortableTable/selection.js +0 -11
- package/components/StatusBadge.vue +77 -0
- package/components/Tabbed/Tab.vue +3 -3
- package/components/Tabbed/index.vue +44 -26
- package/components/Wizard.vue +2 -2
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/Principal.vue +10 -3
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/form/ArrayList.vue +123 -85
- package/components/form/ArrayListGrouped.vue +10 -2
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/Footer.vue +8 -5
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/KeyValue.vue +16 -7
- package/components/form/LabeledSelect.vue +59 -76
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +35 -12
- package/components/form/NameNsDescription.vue +147 -115
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/Password.vue +11 -5
- package/components/form/PodAffinity.vue +43 -44
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
- package/components/form/SSHKnownHosts/index.vue +16 -2
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +41 -7
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/UnitInput.vue +2 -2
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/formatter/BadgeStateFormatter.vue +8 -5
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +60 -27
- package/components/nav/Header.vue +39 -13
- package/components/nav/Jump.vue +7 -0
- package/components/nav/NamespaceFilter.vue +14 -8
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.vue +5 -17
- package/components/nav/Type.vue +32 -35
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -0
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -1
- package/package.json +1 -1
- package/store/type-map.js +29 -2
- package/utils/error.js +30 -8
- package/utils/errorTranslate.json +916 -0
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
|
@@ -103,24 +103,26 @@ export default {
|
|
|
103
103
|
<template>
|
|
104
104
|
<div class="graph-options">
|
|
105
105
|
<div v-if="hasSummaryAndDetail">
|
|
106
|
-
<ButtonGroup
|
|
107
|
-
v-model:value="value.type"
|
|
108
|
-
:options="detailSummaryOptions"
|
|
106
|
+
<ButtonGroup
|
|
107
|
+
v-model:value="value.type"
|
|
108
|
+
:options="detailSummaryOptions"
|
|
109
109
|
/>
|
|
110
110
|
</div>
|
|
111
111
|
<div v-else>
|
|
112
112
|
<div />
|
|
113
113
|
</div>
|
|
114
114
|
<div class="range-refresh">
|
|
115
|
-
<LabeledSelect
|
|
116
|
-
v-model:value="value.range"
|
|
117
|
-
:options="rangeOptions"
|
|
118
|
-
|
|
115
|
+
<LabeledSelect
|
|
116
|
+
v-model:value="value.range"
|
|
117
|
+
:options="rangeOptions"
|
|
118
|
+
class="gafanana-select"
|
|
119
|
+
:label="t('graphOptions.range')"
|
|
119
120
|
/>
|
|
120
|
-
<LabeledSelect
|
|
121
|
-
v-model:value="value.refreshRate"
|
|
122
|
-
:options="refreshOptions"
|
|
123
|
-
|
|
121
|
+
<LabeledSelect
|
|
122
|
+
v-model:value="value.refreshRate"
|
|
123
|
+
:options="refreshOptions"
|
|
124
|
+
class="gafanana-select"
|
|
125
|
+
:label="t('graphOptions.refresh')"
|
|
124
126
|
/>
|
|
125
127
|
</div>
|
|
126
128
|
</div>
|
|
@@ -131,17 +133,21 @@ export default {
|
|
|
131
133
|
&, .range-refresh {
|
|
132
134
|
display: flex;
|
|
133
135
|
flex-direction: row;
|
|
134
|
-
justify-content: flex-end;
|
|
136
|
+
/* justify-content: flex-end; */
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
& {
|
|
138
|
-
justify-content: space-between;
|
|
140
|
+
/* justify-content: space-between; */
|
|
139
141
|
align-items: center;
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
.labeled-select {
|
|
144
|
+
/* .labeled-select {
|
|
143
145
|
width: 100px;
|
|
144
146
|
margin-left: 10px;
|
|
145
|
-
}
|
|
147
|
+
} */
|
|
148
|
+
}
|
|
149
|
+
.gafanana-select{
|
|
150
|
+
width: 300px;
|
|
151
|
+
margin-left: 10px;
|
|
146
152
|
}
|
|
147
153
|
</style>
|
|
@@ -58,6 +58,10 @@ export default {
|
|
|
58
58
|
},
|
|
59
59
|
|
|
60
60
|
computed: {
|
|
61
|
+
itemLabel() {
|
|
62
|
+
return this.labelKey ? this.t(this.labelKey) : this.label ? this.label : this.t('labels.annotations.singular');
|
|
63
|
+
},
|
|
64
|
+
|
|
61
65
|
isBinary() {
|
|
62
66
|
if ( this.binary === null ) {
|
|
63
67
|
return typeof this.value === 'string' && !asciiLike(this.value);
|
|
@@ -186,6 +190,7 @@ export default {
|
|
|
186
190
|
:text="value"
|
|
187
191
|
class="role-tertiary"
|
|
188
192
|
action-color=""
|
|
193
|
+
:aria-label="t('detailText.copyAriaLabel', {item: itemLabel })"
|
|
189
194
|
/>
|
|
190
195
|
</div>
|
|
191
196
|
</template>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Vue, { PropType, defineComponent } from 'vue';
|
|
3
|
+
import { mapGetters } from 'vuex';
|
|
4
|
+
|
|
5
|
+
interface Dot {
|
|
6
|
+
stateBackground: string;
|
|
7
|
+
stateDisplay: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default defineComponent({
|
|
11
|
+
|
|
12
|
+
name: 'DotState',
|
|
13
|
+
|
|
14
|
+
props: {
|
|
15
|
+
value: {
|
|
16
|
+
type: Object as PropType<Dot>,
|
|
17
|
+
default: null
|
|
18
|
+
},
|
|
19
|
+
color: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: null
|
|
22
|
+
},
|
|
23
|
+
label: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: null
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
computed: {
|
|
30
|
+
...mapGetters({ t: 'i18n/t' }),
|
|
31
|
+
bg(): string | null {
|
|
32
|
+
return this.value?.stateBackground || this.color;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
msg(): string | null {
|
|
36
|
+
let text = this.value?.stateDisplay || this.label;
|
|
37
|
+
let zhText = this.t(`stateLabel.${ text }`)
|
|
38
|
+
return zhText ? zhText : text
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<div style="display: flex;flex-direction: row;align-items: center;">
|
|
47
|
+
<div :class="{ [bg]: true }"></div>
|
|
48
|
+
<span style="margin-left: 5px;">{{ msg }}</span>
|
|
49
|
+
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
</template>
|
|
53
|
+
<style lang="scss" scoped>
|
|
54
|
+
.bg-error {
|
|
55
|
+
width: 10px; /* 圆点的宽度 */
|
|
56
|
+
height: 10px; /* 圆点的高度 */
|
|
57
|
+
background-color: #DD0C17; /* 圆点的颜色 */
|
|
58
|
+
border-radius: 50%; /* 设置为圆形 */
|
|
59
|
+
}
|
|
60
|
+
.bg-darker {
|
|
61
|
+
width: 10px; /* 圆点的宽度 */
|
|
62
|
+
height: 10px; /* 圆点的高度 */
|
|
63
|
+
background-color: #DD0C17; /* 圆点的颜色 */
|
|
64
|
+
border-radius: 50%; /* 设置为圆形 */
|
|
65
|
+
}
|
|
66
|
+
.bg-success {
|
|
67
|
+
width: 10px; /* 圆点的宽度 */
|
|
68
|
+
height: 10px; /* 圆点的高度 */
|
|
69
|
+
background-color: #95F204 !important; /* 圆点的颜色 */
|
|
70
|
+
border-radius: 50%; /* 设置为圆形 */
|
|
71
|
+
}
|
|
72
|
+
.bg-warning {
|
|
73
|
+
width: 10px; /* 圆点的宽度 */
|
|
74
|
+
height: 10px; /* 圆点的高度 */
|
|
75
|
+
background-color: #DAC342; /* 圆点的颜色 */
|
|
76
|
+
border-radius: 50%; /* 设置为圆形 */
|
|
77
|
+
}
|
|
78
|
+
.bg-info {
|
|
79
|
+
width: 10px; /* 圆点的宽度 */
|
|
80
|
+
height: 10px; /* 圆点的高度 */
|
|
81
|
+
background-color: #1890FF; /* 圆点的颜色 */
|
|
82
|
+
border-radius: 50%; /* 设置为圆形 */
|
|
83
|
+
}
|
|
84
|
+
</style>
|
|
@@ -63,7 +63,7 @@ export default {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
if (projectRoleTemplateBindingSchema) {
|
|
66
|
-
this.$store.dispatch('rancher/findAll', { type: NORMAN.PROJECT_ROLE_TEMPLATE_BINDING }, { root: true })
|
|
66
|
+
this.$store.dispatch('rancher/findAll', { type: NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, opt: { force: true } }, { root: true })
|
|
67
67
|
.then((bindings) => {
|
|
68
68
|
this['projectRoleTemplateBindings'] = bindings;
|
|
69
69
|
this.loadingProjectBindings = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { mapGetters } from 'vuex';
|
|
2
|
+
import { mapGetters, useStore } from 'vuex';
|
|
3
3
|
import ResourceTable, { defaultTableSortGenerationFn } from '@shell/components/ResourceTable';
|
|
4
4
|
import { STATE, AGE, NAME, NS_SNAPSHOT_QUOTA } from '@shell/config/table-headers';
|
|
5
5
|
import { uniq } from '@shell/utils/array';
|
|
@@ -11,11 +11,13 @@ import Masthead from '@shell/components/ResourceList/Masthead';
|
|
|
11
11
|
import { mapPref, GROUP_RESOURCES, ALL_NAMESPACES, DEV } from '@shell/store/prefs';
|
|
12
12
|
import MoveModal from '@shell/components/MoveModal';
|
|
13
13
|
import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
|
|
14
|
-
|
|
14
|
+
import { escapeHtml } from '@shell/utils/string';
|
|
15
15
|
import { NAMESPACE_FILTER_ALL_ORPHANS } from '@shell/utils/namespace-filter';
|
|
16
16
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
17
17
|
import DOMPurify from 'dompurify';
|
|
18
18
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
19
|
+
import ActionMenu from '@shell/components/ActionMenuShell.vue';
|
|
20
|
+
import { useRuntimeFlag } from '@shell/composables/useRuntimeFlag';
|
|
19
21
|
|
|
20
22
|
export default {
|
|
21
23
|
name: 'ListProjectNamespace',
|
|
@@ -25,6 +27,7 @@ export default {
|
|
|
25
27
|
MoveModal,
|
|
26
28
|
ResourceTable,
|
|
27
29
|
ButtonMultiAction,
|
|
30
|
+
ActionMenu,
|
|
28
31
|
},
|
|
29
32
|
mixins: [ResourceFetch],
|
|
30
33
|
|
|
@@ -58,6 +61,13 @@ export default {
|
|
|
58
61
|
this.projects = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT, opt: { force: true } });
|
|
59
62
|
},
|
|
60
63
|
|
|
64
|
+
setup() {
|
|
65
|
+
const store = useStore();
|
|
66
|
+
const { featureDropdownMenu } = useRuntimeFlag(store);
|
|
67
|
+
|
|
68
|
+
return { featureDropdownMenu };
|
|
69
|
+
},
|
|
70
|
+
|
|
61
71
|
data() {
|
|
62
72
|
return {
|
|
63
73
|
loadResources: [NAMESPACE],
|
|
@@ -155,7 +165,7 @@ export default {
|
|
|
155
165
|
rowsWithFakeNamespaces() {
|
|
156
166
|
const fakeRows = this.projectsWithoutNamespaces.map((project) => {
|
|
157
167
|
return {
|
|
158
|
-
|
|
168
|
+
groupById: `${ ('resourceTable.groupLabel.notInAProject') }-${ project.id }`,
|
|
159
169
|
isFake: true,
|
|
160
170
|
mainRowKey: project.id,
|
|
161
171
|
nameDisplay: project.spec?.displayName, // Enable filtering by the project name
|
|
@@ -166,8 +176,8 @@ export default {
|
|
|
166
176
|
|
|
167
177
|
if (this.showMockNotInProjectGroup) {
|
|
168
178
|
fakeRows.push( {
|
|
169
|
-
|
|
170
|
-
mainRowKey:
|
|
179
|
+
groupById: this.t('resourceTable.groupLabel.notInAProject'),
|
|
180
|
+
mainRowKey: 'fake-empty',
|
|
171
181
|
});
|
|
172
182
|
}
|
|
173
183
|
|
|
@@ -273,6 +283,9 @@ export default {
|
|
|
273
283
|
},
|
|
274
284
|
showCreateNsButton() {
|
|
275
285
|
return this.groupPreference !== 'namespace';
|
|
286
|
+
},
|
|
287
|
+
projectGroupBy() {
|
|
288
|
+
return this.groupPreference === 'none' ? null : 'groupById';
|
|
276
289
|
}
|
|
277
290
|
},
|
|
278
291
|
methods: {
|
|
@@ -336,6 +349,10 @@ export default {
|
|
|
336
349
|
return location;
|
|
337
350
|
},
|
|
338
351
|
|
|
352
|
+
getProjectActions(group) {
|
|
353
|
+
return group.rows[0].project;
|
|
354
|
+
},
|
|
355
|
+
|
|
339
356
|
showProjectAction(event, group) {
|
|
340
357
|
const project = group.rows[0].project;
|
|
341
358
|
|
|
@@ -359,7 +376,13 @@ export default {
|
|
|
359
376
|
);
|
|
360
377
|
}
|
|
361
378
|
|
|
362
|
-
|
|
379
|
+
if ( row.groupById === this.notInProjectKey) {
|
|
380
|
+
return this.t('resourceTable.groupLabel.notInAProject');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const project = row.project?.nameDisplay || row.project?.id || '';
|
|
384
|
+
|
|
385
|
+
return this.t('resourceTable.groupLabel.project', { name: escapeHtml(project) }, true);
|
|
363
386
|
},
|
|
364
387
|
|
|
365
388
|
projectDescription(group) {
|
|
@@ -431,6 +454,7 @@ export default {
|
|
|
431
454
|
:schema="schema"
|
|
432
455
|
:headers="headers"
|
|
433
456
|
:rows="filteredRows"
|
|
457
|
+
:group-by="projectGroupBy"
|
|
434
458
|
:groupable="true"
|
|
435
459
|
:sort-generation-fn="sortGenerationFn"
|
|
436
460
|
:loading="loading"
|
|
@@ -457,7 +481,7 @@ export default {
|
|
|
457
481
|
{{ projectDescription(group.group) }}
|
|
458
482
|
</div>
|
|
459
483
|
</div>
|
|
460
|
-
<div class="right">
|
|
484
|
+
<div class="right mr-10">
|
|
461
485
|
<router-link
|
|
462
486
|
v-if="isNamespaceCreatable && (canSeeProjectlessNamespaces || group.group.key !== notInProjectKey)"
|
|
463
487
|
class="create-namespace btn btn-sm role-secondary mr-5"
|
|
@@ -465,13 +489,26 @@ export default {
|
|
|
465
489
|
>
|
|
466
490
|
{{ t('projectNamespaces.createNamespace') }}
|
|
467
491
|
</router-link>
|
|
468
|
-
<
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
492
|
+
<template v-if="featureDropdownMenu">
|
|
493
|
+
<ActionMenu
|
|
494
|
+
v-if="showProjectActionButton(group.group)"
|
|
495
|
+
:resource="getProjectActions(group.group)"
|
|
496
|
+
:button-aria-label="t('projectNamespaces.tableActionsLabel', { resource: projectResource(group.group) })"
|
|
497
|
+
/>
|
|
498
|
+
<div
|
|
499
|
+
v-else
|
|
500
|
+
class="invisible"
|
|
501
|
+
/>
|
|
502
|
+
</template>
|
|
503
|
+
<template v-else>
|
|
504
|
+
<ButtonMultiAction
|
|
505
|
+
class="project-action"
|
|
506
|
+
:borderless="true"
|
|
507
|
+
:aria-label="t('projectNamespaces.tableActionsLabel', { resource: projectResource(group.group) })"
|
|
508
|
+
:invisible="!showProjectActionButton(group.group)"
|
|
509
|
+
@click="showProjectAction($event, group.group)"
|
|
510
|
+
/>
|
|
511
|
+
</template>
|
|
475
512
|
</div>
|
|
476
513
|
</div>
|
|
477
514
|
</template>
|
|
@@ -536,6 +573,11 @@ export default {
|
|
|
536
573
|
</div>
|
|
537
574
|
</template>
|
|
538
575
|
<style lang="scss" scoped>
|
|
576
|
+
.invisible {
|
|
577
|
+
display: inline-block;
|
|
578
|
+
min-width: 28px;
|
|
579
|
+
}
|
|
580
|
+
|
|
539
581
|
.project-namespaces {
|
|
540
582
|
& :deep() {
|
|
541
583
|
.project-namespaces-table table {
|
|
@@ -37,7 +37,7 @@ export default {
|
|
|
37
37
|
handleLineBreaksConsentText(banner) {
|
|
38
38
|
if (banner.text?.length) {
|
|
39
39
|
// split text by newline char
|
|
40
|
-
const textArray = banner.text.split(
|
|
40
|
+
const textArray = banner.text.split('\n').filter((element) => element);
|
|
41
41
|
|
|
42
42
|
if (textArray.length > 1) {
|
|
43
43
|
textArray.forEach((str, i) => {
|
|
@@ -130,11 +130,11 @@ export default {
|
|
|
130
130
|
|
|
131
131
|
if (isEmpty(banner)) {
|
|
132
132
|
if (showHeader && this.header) {
|
|
133
|
-
bannerContent = bannerHeader || {};
|
|
133
|
+
bannerContent = this.handleLineBreaksConsentText(bannerHeader) || {};
|
|
134
134
|
} else if (showConsent && this.consent) {
|
|
135
135
|
bannerContent = this.handleLineBreaksConsentText(bannerConsent) || {};
|
|
136
136
|
} else if (showFooter && this.footer) {
|
|
137
|
-
bannerContent = bannerFooter || {};
|
|
137
|
+
bannerContent = this.handleLineBreaksConsentText(bannerFooter) || {};
|
|
138
138
|
} else {
|
|
139
139
|
bannerContent = {};
|
|
140
140
|
}
|
|
@@ -168,16 +168,20 @@ export default {
|
|
|
168
168
|
>
|
|
169
169
|
<!-- text as array to support line breaks programmatically rather than just exposing HTML -->
|
|
170
170
|
<div v-if="isTextAnArray">
|
|
171
|
-
<
|
|
171
|
+
<div
|
|
172
172
|
v-for="(text, index) in banner.text"
|
|
173
173
|
:key="index"
|
|
174
|
+
class="array-row"
|
|
174
175
|
>
|
|
175
176
|
{{ text }}
|
|
176
|
-
</
|
|
177
|
+
</div>
|
|
177
178
|
</div>
|
|
178
|
-
<
|
|
179
|
+
<div
|
|
180
|
+
v-else
|
|
181
|
+
class="single-row"
|
|
182
|
+
>
|
|
179
183
|
{{ banner.text }}
|
|
180
|
-
</
|
|
184
|
+
</div>
|
|
181
185
|
</div>
|
|
182
186
|
<div v-else-if="showDialog">
|
|
183
187
|
<div class="banner-dialog-glass" />
|
|
@@ -192,16 +196,20 @@ export default {
|
|
|
192
196
|
>
|
|
193
197
|
<!-- text as array to support line breaks programmatically rather than just exposing HTML -->
|
|
194
198
|
<div v-if="isTextAnArray">
|
|
195
|
-
<
|
|
199
|
+
<div
|
|
196
200
|
v-for="(text, index) in banner.text"
|
|
197
201
|
:key="index"
|
|
202
|
+
class="array-row"
|
|
198
203
|
>
|
|
199
204
|
{{ text }}
|
|
200
|
-
</
|
|
205
|
+
</div>
|
|
201
206
|
</div>
|
|
202
|
-
<
|
|
207
|
+
<div
|
|
208
|
+
v-else
|
|
209
|
+
class="single-row"
|
|
210
|
+
>
|
|
203
211
|
{{ banner.text }}
|
|
204
|
-
</
|
|
212
|
+
</div>
|
|
205
213
|
</div>
|
|
206
214
|
<button
|
|
207
215
|
class="btn role-primary"
|
|
@@ -223,7 +231,6 @@ export default {
|
|
|
223
231
|
padding: 0 20px;
|
|
224
232
|
|
|
225
233
|
&.banner-consent {
|
|
226
|
-
position: absolute;
|
|
227
234
|
height: unset;
|
|
228
235
|
min-height: 2em;
|
|
229
236
|
overflow: hidden;
|
|
@@ -49,6 +49,10 @@ export default {
|
|
|
49
49
|
userId: {
|
|
50
50
|
type: String,
|
|
51
51
|
default: ''
|
|
52
|
+
},
|
|
53
|
+
watchOverride: {
|
|
54
|
+
type: Boolean,
|
|
55
|
+
default: true,
|
|
52
56
|
}
|
|
53
57
|
},
|
|
54
58
|
async fetch() {
|
|
@@ -138,7 +142,7 @@ export default {
|
|
|
138
142
|
this.update();
|
|
139
143
|
},
|
|
140
144
|
userId(userId, oldUserId) {
|
|
141
|
-
if (userId === oldUserId) {
|
|
145
|
+
if (userId === oldUserId || this.watchOverride === true) {
|
|
142
146
|
return;
|
|
143
147
|
}
|
|
144
148
|
this.update();
|
|
@@ -262,22 +262,22 @@ export default {
|
|
|
262
262
|
<div v-if="loading">
|
|
263
263
|
<Loading />
|
|
264
264
|
</div>
|
|
265
|
-
<div
|
|
265
|
+
<!-- <div
|
|
266
266
|
v-if="!loading && !error"
|
|
267
267
|
class="external-link"
|
|
268
|
-
>
|
|
268
|
+
> -->
|
|
269
269
|
<!-- https://github.com/harvester/harvester-installer/pull/512/files -->
|
|
270
270
|
<!-- It is necessary to include the parameter referer when accessing the Grafana page. -->
|
|
271
271
|
<!-- This parameter is required by the backend to identify the origin of the request from which cluster -->
|
|
272
272
|
<!-- The matching mechanism as follows: -->
|
|
273
273
|
<!-- ~.*/k8s/clusters/(c-m-.+)/.* -->
|
|
274
274
|
<!-- ~.*/dashboard/harvester/c/(c-m-.+)/.* -->
|
|
275
|
-
<a
|
|
275
|
+
<!-- <a
|
|
276
276
|
:href="grafanaUrl"
|
|
277
277
|
target="_blank"
|
|
278
278
|
rel="noopener nofollow"
|
|
279
279
|
>{{ t('grafanaDashboard.grafana') }} <i class="icon icon-external-link" /></a>
|
|
280
|
-
</div>
|
|
280
|
+
</div> -->
|
|
281
281
|
</div>
|
|
282
282
|
</template>
|
|
283
283
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { mapState } from 'vuex';
|
|
3
|
+
import { translateError } from '@shell/utils/error'
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
data() {
|
|
@@ -25,6 +26,7 @@ export default {
|
|
|
25
26
|
},
|
|
26
27
|
|
|
27
28
|
methods: {
|
|
29
|
+
translateError,
|
|
28
30
|
close(growl) {
|
|
29
31
|
this.$store.dispatch('growl/remove', growl.id);
|
|
30
32
|
},
|
|
@@ -107,6 +109,7 @@ export default {
|
|
|
107
109
|
@click="close(growl)"
|
|
108
110
|
/>
|
|
109
111
|
<div
|
|
112
|
+
v-if="growl.title"
|
|
110
113
|
:id="`growl-title-${ growl.id }`"
|
|
111
114
|
class="growl-text-title"
|
|
112
115
|
>
|
|
@@ -117,7 +120,7 @@ export default {
|
|
|
117
120
|
:id="`growl-message-${ growl.id }`"
|
|
118
121
|
:class="{ 'has-title': !!growl.title }"
|
|
119
122
|
>
|
|
120
|
-
|
|
123
|
+
{{ translateError(growl.message) }}
|
|
121
124
|
</p>
|
|
122
125
|
</div>
|
|
123
126
|
</div>
|
|
@@ -85,8 +85,9 @@ export default {
|
|
|
85
85
|
:capacity="reserved.total"
|
|
86
86
|
:used="reserved.useful"
|
|
87
87
|
:color-stops="colorStops"
|
|
88
|
+
:reserveText="`已分配`"
|
|
88
89
|
>
|
|
89
|
-
<template #title>
|
|
90
|
+
<!-- <template #title>
|
|
90
91
|
<span>
|
|
91
92
|
{{ reservedTitle ?? t('clusterIndexPage.hardwareResourceGauge.reserved') }}
|
|
92
93
|
<span class="values text-muted">
|
|
@@ -108,6 +109,23 @@ export default {
|
|
|
108
109
|
<span>
|
|
109
110
|
{{ percentage(reserved) }}
|
|
110
111
|
</span>
|
|
112
|
+
</template> -->
|
|
113
|
+
<template #content>
|
|
114
|
+
<span>
|
|
115
|
+
{{ percentage(reserved) }}(
|
|
116
|
+
共 <span v-if="reserved.formattedTotal">
|
|
117
|
+
{{ reserved.formattedTotal }}
|
|
118
|
+
</span>
|
|
119
|
+
<span v-else>
|
|
120
|
+
{{ maxDecimalPlaces(reserved.total) }} {{ reserved.units }}
|
|
121
|
+
</span>,{{ reservedTitle === '分配'? '已分配': '预留' }} <span v-if="reserved.formattedUseful">
|
|
122
|
+
{{ reserved.formattedUseful }} {{ reserved.units }}
|
|
123
|
+
</span>
|
|
124
|
+
<span v-else>
|
|
125
|
+
{{ maxDecimalPlaces(reserved.useful) }} {{ reserved.units }}
|
|
126
|
+
</span>
|
|
127
|
+
)
|
|
128
|
+
</span>
|
|
111
129
|
</template>
|
|
112
130
|
</ConsumptionGauge>
|
|
113
131
|
</div>
|
|
@@ -119,8 +137,26 @@ export default {
|
|
|
119
137
|
:capacity="used.total"
|
|
120
138
|
:used="used.useful"
|
|
121
139
|
:color-stops="colorStops"
|
|
140
|
+
:reserveText="`已使用`"
|
|
122
141
|
>
|
|
123
|
-
|
|
142
|
+
<template #content>
|
|
143
|
+
<span>
|
|
144
|
+
{{ percentage(used) }}(
|
|
145
|
+
共 <span v-if="used.formattedTotal">
|
|
146
|
+
{{ used.formattedTotal }}
|
|
147
|
+
</span>
|
|
148
|
+
<span v-else>
|
|
149
|
+
{{ maxDecimalPlaces(used.total) }} {{ used.units }}
|
|
150
|
+
</span>,已使用 <span v-if="used.formattedUseful">
|
|
151
|
+
{{ used.formattedUseful }} {{ used.units }}
|
|
152
|
+
</span>
|
|
153
|
+
<span v-else>
|
|
154
|
+
{{ maxDecimalPlaces(used.useful) }} {{ used.units }}
|
|
155
|
+
</span>
|
|
156
|
+
)
|
|
157
|
+
</span>
|
|
158
|
+
</template>
|
|
159
|
+
<!-- <template #title>
|
|
124
160
|
<span>
|
|
125
161
|
{{ usedTitle ?? t('clusterIndexPage.hardwareResourceGauge.used') }}
|
|
126
162
|
<span class="values text-muted">
|
|
@@ -142,7 +178,7 @@ export default {
|
|
|
142
178
|
<span>
|
|
143
179
|
{{ percentage(used) }}
|
|
144
180
|
</span>
|
|
145
|
-
</template>
|
|
181
|
+
</template> -->
|
|
146
182
|
</ConsumptionGauge>
|
|
147
183
|
</div>
|
|
148
184
|
</div>
|
package/components/InfoBox.vue
CHANGED
|
@@ -26,8 +26,8 @@ export default {
|
|
|
26
26
|
|
|
27
27
|
<style lang="scss" scoped>
|
|
28
28
|
.info-box {
|
|
29
|
-
border:
|
|
30
|
-
padding:
|
|
29
|
+
border: 1px solid var(--tabbed-border);
|
|
30
|
+
padding: 20px;
|
|
31
31
|
margin-bottom: 20px;
|
|
32
32
|
border-radius: var(--border-radius);
|
|
33
33
|
flex-grow: 1;
|
|
@@ -81,4 +81,4 @@ export default {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
</style>
|
|
84
|
+
</style>
|
|
@@ -45,7 +45,9 @@ export default {
|
|
|
45
45
|
</div>
|
|
46
46
|
<div class="value">
|
|
47
47
|
<slot name="value">
|
|
48
|
-
|
|
48
|
+
<span v-clean-tooltip="displayValue">
|
|
49
|
+
{{ displayValue }}
|
|
50
|
+
</span>
|
|
49
51
|
</slot>
|
|
50
52
|
</div>
|
|
51
53
|
</div>
|
|
@@ -53,7 +55,7 @@ export default {
|
|
|
53
55
|
</template>
|
|
54
56
|
|
|
55
57
|
<style lang="scss" scoped>
|
|
56
|
-
.label {
|
|
58
|
+
/* .label {
|
|
57
59
|
display: flex;
|
|
58
60
|
flex-direction: column;
|
|
59
61
|
|
|
@@ -61,5 +63,29 @@ export default {
|
|
|
61
63
|
font-size: 14px;
|
|
62
64
|
line-height: $input-line-height;
|
|
63
65
|
}
|
|
66
|
+
} */
|
|
67
|
+
.label {
|
|
68
|
+
display: flex;
|
|
69
|
+
/* align-items: center; */
|
|
70
|
+
/* flex-direction: column; */
|
|
71
|
+
|
|
72
|
+
.text-label{
|
|
73
|
+
width: 160px;
|
|
74
|
+
line-height: 32px;
|
|
75
|
+
}
|
|
76
|
+
.value {
|
|
77
|
+
/* font-size: 14px; */
|
|
78
|
+
/* line-height: $input-line-height; */
|
|
79
|
+
line-height: 32px;
|
|
80
|
+
flex: 1;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
text-overflow: ellipsis;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
|
|
85
|
+
ul{
|
|
86
|
+
line-height: $input-line-height;
|
|
87
|
+
list-style:none;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
64
90
|
}
|
|
65
91
|
</style>
|
|
@@ -30,7 +30,7 @@ export default {
|
|
|
30
30
|
</template>
|
|
31
31
|
|
|
32
32
|
<style lang="scss" scoped>
|
|
33
|
-
.label {
|
|
33
|
+
/* .label {
|
|
34
34
|
display: flex;
|
|
35
35
|
flex-direction: column;
|
|
36
36
|
|
|
@@ -38,5 +38,20 @@ export default {
|
|
|
38
38
|
font-size: 14px;
|
|
39
39
|
line-height: $input-line-height;
|
|
40
40
|
}
|
|
41
|
+
} */
|
|
42
|
+
.label {
|
|
43
|
+
display: flex;
|
|
44
|
+
/* flex-direction: column; */
|
|
45
|
+
align-items: center;
|
|
46
|
+
.text-label{
|
|
47
|
+
width: 160px;
|
|
48
|
+
line-height: 32px;
|
|
49
|
+
}
|
|
50
|
+
.value {
|
|
51
|
+
line-height: $input-line-height;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
text-overflow: ellipsis;
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
}
|
|
41
56
|
}
|
|
42
57
|
</style>
|