dashboard-shell-shell 1.0.1000000117 → 1.0.1000000118

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.
Files changed (124) hide show
  1. package/assets/styles/base/_functions.scss +0 -0
  2. package/assets/styles/base/_mixins.scss +1 -1
  3. package/assets/styles/global/_button.scss +10 -17
  4. package/assets/styles/global/_form.scss +2 -2
  5. package/assets/styles/global/_labeled-input.scss +2 -6
  6. package/assets/styles/global/_select.scss +7 -6
  7. package/assets/styles/global/_table.scss +2 -3
  8. package/assets/styles/global/_tooltip.scss +1 -8
  9. package/assets/styles/themes/_dark.scss +0 -2
  10. package/assets/styles/themes/_light.scss +2 -5
  11. package/assets/styles/vendor/vue-select.scss +1 -2
  12. package/assets/translations/en-us.yaml +3 -1
  13. package/assets/translations/zh-hans.yaml +28 -51
  14. package/components/ActionDropdown.vue +0 -1
  15. package/components/ActionMenuShell.vue +3 -6
  16. package/components/BrandImage.vue +0 -22
  17. package/components/ClusterIconMenu.vue +1 -1
  18. package/components/CodeMirror.vue +0 -1
  19. package/components/CruResource.vue +1 -1
  20. package/components/CruResourceFooter.vue +1 -1
  21. package/components/ExplorerProjectsNamespaces.vue +24 -4
  22. package/components/GlobalRoleBindings.vue +48 -112
  23. package/components/IndentedPanel.vue +10 -4
  24. package/components/PromptRemove.vue +3 -3
  25. package/components/ResourceDetail/Masthead.vue +242 -190
  26. package/components/ResourceDetail/index.vue +5 -20
  27. package/components/ResourceList/Masthead.vue +84 -146
  28. package/components/ResourceList/ResourceLoadingIndicator.vue +2 -5
  29. package/components/ResourceTable.vue +1 -76
  30. package/components/SideNav.vue +29 -66
  31. package/components/SortableTable/THead.vue +0 -6
  32. package/components/SortableTable/index.vue +388 -481
  33. package/components/Tabbed/index.vue +5 -4
  34. package/components/auth/Principal.vue +2 -3
  35. package/components/auth/RoleDetailEdit.vue +5 -58
  36. package/components/auth/SelectPrincipal.vue +0 -1
  37. package/components/form/BannerSettings.vue +16 -18
  38. package/components/form/ChangePassword.vue +4 -4
  39. package/components/form/ColorInput.vue +8 -32
  40. package/components/form/Footer.vue +1 -1
  41. package/components/form/InputWithSelect.vue +0 -2
  42. package/components/form/KeyValue.vue +7 -31
  43. package/components/form/LabeledSelect.vue +178 -178
  44. package/components/form/Members/ClusterPermissionsEditor.vue +2 -1
  45. package/components/form/Members/MembershipEditor.vue +1 -1
  46. package/components/form/NameNsDescription.vue +11 -24
  47. package/components/form/Password.vue +2 -6
  48. package/components/form/ResourceQuota/Namespace.vue +1 -1
  49. package/components/form/ResourceQuota/NamespaceRow.vue +10 -13
  50. package/components/form/ResourceQuota/ProjectRow.vue +1 -0
  51. package/components/form/Select.vue +2 -2
  52. package/components/nav/Favorite.vue +1 -5
  53. package/components/nav/Group.vue +23 -69
  54. package/components/nav/Header.vue +17 -82
  55. package/components/nav/HeaderPageActionMenu.vue +0 -1
  56. package/components/nav/NamespaceFilter.vue +3 -0
  57. package/components/nav/TopLevelMenu.vue +119 -182
  58. package/components/nav/Type.vue +11 -48
  59. package/components/rancherResourceDetail/Masthead.vue +769 -0
  60. package/components/rancherResourceDetail/__tests__/Masthead.test.ts +65 -0
  61. package/components/rancherResourceDetail/index.vue +591 -0
  62. package/components/rancherResourceList/Masthead.vue +375 -0
  63. package/components/rancherResourceList/ResourceLoadingIndicator.vue +140 -0
  64. package/components/rancherResourceList/index.vue +307 -0
  65. package/components/rancherResourceList/resource-list.config.js +7 -0
  66. package/components/rancherResourceTable.vue +783 -0
  67. package/components/rancherSortableTable/THead.vue +561 -0
  68. package/components/rancherSortableTable/actions.js +153 -0
  69. package/components/rancherSortableTable/advanced-filtering.js +272 -0
  70. package/components/rancherSortableTable/debug.js +117 -0
  71. package/components/rancherSortableTable/filtering.js +290 -0
  72. package/components/rancherSortableTable/grouping.js +48 -0
  73. package/components/rancherSortableTable/index.vue +2712 -0
  74. package/components/rancherSortableTable/paging.js +155 -0
  75. package/components/rancherSortableTable/selection.js +629 -0
  76. package/components/rancherSortableTable/sortable-config.ts +4 -0
  77. package/components/rancherSortableTable/sorting.js +129 -0
  78. package/composables/useClickOutside.ts +1 -1
  79. package/config/product/auth.js +7 -16
  80. package/config/product/explorer.js +1 -1
  81. package/config/product/settings.js +8 -17
  82. package/config/settings.ts +0 -28
  83. package/edit/management.cattle.io.user.vue +4 -17
  84. package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
  85. package/edit/token.vue +1 -1
  86. package/list/harvesterhci.io.management.cluster.vue +0 -17
  87. package/list/management.cattle.io.setting.vue +13 -22
  88. package/list/management.cattle.io.user.vue +14 -25
  89. package/list/provisioning.cattle.io.cluster.vue +7 -6
  90. package/mixins/brand.js +0 -17
  91. package/package.json +1 -1
  92. package/pages/auth/login.vue +29 -84
  93. package/pages/c/_cluster/auth/roles/index.vue +14 -61
  94. package/pages/c/_cluster/settings/banners.vue +101 -174
  95. package/pages/c/_cluster/settings/brand.vue +301 -348
  96. package/pages/c/_cluster/settings/performance.vue +38 -61
  97. package/pages/home.vue +21 -70
  98. package/pages/prefs.vue +23 -25
  99. package/pkg/tsconfig.json +9 -9
  100. package/pkg/vue.config.js +1 -1
  101. package/promptRemove/mixin/roleDeletionCheck.js +2 -2
  102. package/scripts/clean +0 -0
  103. package/scripts/extension/bundle +0 -0
  104. package/scripts/extension/helm/scripts/package +0 -0
  105. package/scripts/extension/helm/scripts/patch +0 -0
  106. package/scripts/extension/helm/scripts/version +0 -0
  107. package/scripts/extension/helmpatch +0 -0
  108. package/scripts/extension/parse-tag-name +0 -0
  109. package/scripts/extension/publish +0 -0
  110. package/scripts/publish-shell.sh +60 -86
  111. package/scripts/serve-pkgs +0 -0
  112. package/scripts/sync-shell-deps +0 -0
  113. package/scripts/typegen.sh +28 -44
  114. package/store/i18n.js +5 -5
  115. package/store/prefs.js +5 -17
  116. package/store/type-map.js +1 -2
  117. package/types/cloud-shell/index.d.ts +11014 -0
  118. package/types/shell/index.d.ts +1 -1
  119. package/utils/error.js +0 -4
  120. package/utils/router.js +3 -3
  121. package/vue.config.js +6 -1
  122. package/assets/images/action.svg +0 -6
  123. package/assets/images/pl/logo.png +0 -0
  124. /package/components/{ResourceList → rancherResourceList}/Masthead-btn.vue +0 -0
@@ -0,0 +1,375 @@
1
+ <script>
2
+ import { mapGetters } from 'vuex';
3
+ import Favorite from '@shell/components/nav/Favorite';
4
+ import TypeDescription from '@shell/components/TypeDescription';
5
+ import { get } from '@shell/utils/object';
6
+ import { AS, _YAML } from '@shell/config/query-params';
7
+ import ResourceLoadingIndicator from './ResourceLoadingIndicator';
8
+ import TabTitle from '@shell/components/TabTitle';
9
+ import { harvesterhci2cloud, cloud2harvesterhci } from '@shell/utils/router'
10
+
11
+ /**
12
+ * Resource List Masthead component.
13
+ */
14
+ export default {
15
+
16
+ name: 'MastheadResourceList',
17
+
18
+ components: {
19
+ Favorite,
20
+ TypeDescription,
21
+ ResourceLoadingIndicator,
22
+ TabTitle
23
+ },
24
+ props: {
25
+ resource: {
26
+ type: String,
27
+ required: true,
28
+ },
29
+ favoriteResource: {
30
+ type: String,
31
+ default: null
32
+ },
33
+ schema: {
34
+ type: Object,
35
+ default: null,
36
+ },
37
+ typeDisplay: {
38
+ type: String,
39
+ default: null,
40
+ },
41
+ isCreatable: {
42
+ type: Boolean,
43
+ default: null,
44
+ },
45
+ isYamlCreatable: {
46
+ type: Boolean,
47
+ default: null,
48
+ },
49
+ createLocation: {
50
+ type: Object,
51
+ default: null,
52
+ },
53
+ yamlCreateLocation: {
54
+ type: Object,
55
+ default: null,
56
+ },
57
+ createButtonLabel: {
58
+ type: String,
59
+ default: null
60
+ },
61
+ loadResources: {
62
+ type: Array,
63
+ default: () => []
64
+ },
65
+
66
+ loadIndeterminate: {
67
+ type: Boolean,
68
+ default: false
69
+ },
70
+
71
+ showIncrementalLoadingIndicator: {
72
+ type: Boolean,
73
+ default: false
74
+ },
75
+
76
+ /**
77
+ * Inherited global identifier prefix for tests
78
+ * Define a term based on the parent component to avoid conflicts on multiple components
79
+ */
80
+ componentTestid: {
81
+ type: String,
82
+ default: 'masthead'
83
+ },
84
+
85
+ mainButtonVisible: {
86
+ type: Boolean,
87
+ default: true
88
+ },
89
+ },
90
+
91
+ data() {
92
+ const params = { ...this.$route.params };
93
+
94
+ params.resource = params.resource
95
+
96
+ const formRoute = { name: `${ this.$route.name }-create`, params };
97
+
98
+ const hasEditComponent = this.$store.getters['type-map/hasCustomEdit'](this.resource);
99
+
100
+ const yamlRoute = {
101
+ name: `${ this.$route.name }-create`,
102
+ params,
103
+ query: { [AS]: _YAML },
104
+ };
105
+
106
+ const tabList = ['集群配置'];
107
+
108
+ const description = ''
109
+ return {
110
+ formRoute,
111
+ yamlRoute,
112
+ hasEditComponent,
113
+ tabList,
114
+ description
115
+ };
116
+ },
117
+
118
+ computed: {
119
+ get,
120
+ ...mapGetters(['isExplorer', 'currentCluster']),
121
+
122
+ resourceName() {
123
+ if (this.schema) {
124
+ return this.$store.getters['type-map/labelFor'](this.schema);
125
+ }
126
+
127
+ return this.resource;
128
+ },
129
+
130
+ _typeDisplay() {
131
+ if ( this.typeDisplay !== null) {
132
+ return this.typeDisplay;
133
+ }
134
+
135
+ if ( !this.schema ) {
136
+ return '?';
137
+ }
138
+
139
+ return this.$store.getters['type-map/labelFor'](this.schema, 99);
140
+ },
141
+ _descriptionDisplay() {
142
+ const key = this.$route.path.split('/'.pop());
143
+
144
+ return this.$store.getters['i18n/t'](`typeDescription."${ key.toLowerCase() }"`);
145
+ },
146
+ demoDisplay() {
147
+ // const product = this.$store.getters['productId'];
148
+ // const productId = this.$store.getters['type-map/groupForBasicType'](this.$store.getters['productId'], this._createLocation.params.resource);
149
+
150
+ // const parts = productId?.split('::') || [];
151
+ // const newString = 'root';
152
+
153
+ // if (!parts.includes(newString)) {
154
+ // parts.unshift(newString); // 将字符串添加到数组第一位
155
+ // }
156
+
157
+ // const partsEn = parts.map((item) => {
158
+ // return this.$store.getters['i18n/t'](`typeLabel."${ item.toLowerCase() }"`);
159
+ // });
160
+
161
+ // return partsEn;
162
+
163
+ const breadcrumbList = {
164
+ 'harvesterhci.io.management.cluster': {
165
+ origin: 'Harvester 集群',
166
+ bread: ['虚拟化管理'],
167
+ description: '还没有添加描述。。。。'
168
+ },
169
+ 'management.cattle.io.user': {
170
+ origin: '用户',
171
+ bread: ['用户 & 认证'],
172
+ description: '还没有添加描述。。。。'
173
+ },
174
+ 'management.cattle.io.setting':{
175
+ origin: '基础设置',
176
+ bread: ['全局设置'],
177
+ description: '还没有添加描述。。。。'
178
+ },
179
+ 'management.cattle.io.feature':{
180
+ origin: '功能开关',
181
+ bread: ['全局设置'],
182
+ description: '还没有添加描述。。。。'
183
+ },
184
+ }
185
+ const resourcePath = this.$route.params.resource || ''
186
+
187
+ const breadcrumb = []
188
+ if (breadcrumbList[resourcePath] && Object.keys(breadcrumbList[resourcePath]).length > 0) {
189
+ breadcrumb.push(...breadcrumbList[resourcePath].bread)
190
+ this.description = breadcrumbList[resourcePath].description
191
+ }
192
+
193
+ return breadcrumb
194
+ },
195
+
196
+ _isYamlCreatable() {
197
+ if ( this.isYamlCreatable !== null) {
198
+ return this.isYamlCreatable;
199
+ }
200
+
201
+ return this.schema && this._isCreatable && this.$store.getters['type-map/optionsFor'](this.resource).canYaml;
202
+ },
203
+
204
+ _isCreatable() {
205
+ // Does not take into account hasEditComponent, such that _isYamlCreatable works
206
+ if ( this.isCreatable !== null) {
207
+ return this.isCreatable;
208
+ }
209
+
210
+ // blocked-post means you can post through norman, but not through steve.
211
+ if ( this.schema && !this.schema?.collectionMethods.find((x) => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
212
+ return false;
213
+ }
214
+
215
+ return this.$store.getters['type-map/optionsFor'](this.resource).isCreatable;
216
+ },
217
+
218
+ _createLocation() {
219
+ return this.createLocation || this.formRoute;
220
+ },
221
+
222
+ _yamlCreateLocation() {
223
+ return this.yamlCreateLocation || this.yamlRoute;
224
+ },
225
+
226
+ _createButtonlabel() {
227
+ return this.createButtonLabel || this.t('resourceList.head.create');
228
+ },
229
+ }
230
+ };
231
+ </script>
232
+
233
+ <template>
234
+ <!-- 顶部 header,带有子标题(subheader)样式类 -->
235
+ <header class="with-subheader">
236
+ <div style="display: flex;width: 100%;">
237
+ <div style="flex: 1;">
238
+ <!-- 标题区域 -->
239
+ <div class="title">
240
+ <div class="excram-list">
241
+ <span
242
+ v-for="(item,index) in demoDisplay"
243
+ :key="index"
244
+ >
245
+ <span v-if="item">{{ item }}</span>
246
+ <span v-if="item">/</span>
247
+ </span>
248
+ <span class="excram-last-name">{{ _typeDisplay }}</span>
249
+ </div>
250
+ <h1 style="display: flex;align-items: center;" class="m-0 descrip-name">
251
+ <TabTitle>{{ _typeDisplay }}</TabTitle>
252
+ <!-- 子标题区域 -->
253
+ <div class="sub-header">
254
+ <slot name="subHeader">
255
+ <!--Slot content-->
256
+ </slot>
257
+ </div>
258
+
259
+ <!-- <Favorite
260
+ v-if="isExplorer"
261
+ :resource="favoriteResource || resource"
262
+ /> -->
263
+
264
+ <ResourceLoadingIndicator
265
+ style="margin-left: 10px;"
266
+ v-if="showIncrementalLoadingIndicator"
267
+ :resources="loadResources"
268
+ :indeterminate="loadIndeterminate"
269
+ />
270
+ </h1>
271
+
272
+ <!-- 插槽:typeDescription,用于插入类型描述组件 -->
273
+ <div v-if="description" class="masthod-title-description">
274
+ {{ description }}
275
+ </div>
276
+
277
+ </div>
278
+
279
+
280
+ </div>
281
+
282
+ <!-- 操作按钮区域 -->
283
+ <div
284
+ v-if="!(tabList.includes(_typeDisplay)) && mainButtonVisible"
285
+ class="actions-container"
286
+ style="min-height: 32px;align-self: flex-end;"
287
+ >
288
+ <slot name="actions">
289
+ <div class="actions">
290
+ <slot name="extraActions" />
291
+
292
+ <slot name="createButton">
293
+ <router-link
294
+ v-if="hasEditComponent && _isCreatable"
295
+ :to="_createLocation"
296
+ class="btn role-primary"
297
+ :data-testid="componentTestid+'-create'"
298
+ >
299
+ {{ _createButtonlabel }}
300
+ </router-link>
301
+ <router-link
302
+ v-else-if="_isYamlCreatable"
303
+ :to="_yamlCreateLocation"
304
+ class="btn role-primary"
305
+ :data-testid="componentTestid+'-create-yaml'"
306
+ >
307
+ {{ t("resourceList.head.createFromYaml") }}
308
+ </router-link>
309
+ </slot>
310
+ </div>
311
+ </slot>
312
+ </div>
313
+ </div>
314
+ <div
315
+ v-if="!(tabList.includes(_typeDisplay))"
316
+ style="width: 110%;height: 1px;background-color: #D7D7D7;margin-top: 16px;margin-left: -20px;margin-right: -20px;"
317
+ />
318
+ </header>
319
+ </template>
320
+
321
+ <style lang="scss" scoped>
322
+
323
+ .title {
324
+ /* align-items: center;
325
+ display: flex; */
326
+ h1 {
327
+ margin: 0;
328
+ }
329
+ }
330
+
331
+ header {
332
+ /* margin-bottom: 20px; */
333
+ }
334
+
335
+ header.with-subheader {
336
+ /* grid-template-areas:
337
+ 'type-banner type-banner'
338
+ 'title actions'
339
+ 'sub-header sub-header'
340
+ 'state-banner state-banner'; */
341
+ position: relative;
342
+ display: flex;
343
+ margin-bottom: 16px;
344
+ flex-direction: column;
345
+ }
346
+ .excram-list{
347
+ font-size: 14px;
348
+ line-height: 22px;
349
+ margin-bottom: 20px;
350
+ font-family: 'Microsoft YaHei';
351
+ }
352
+ .excram-last-name{
353
+ color: var(--primary);
354
+ }
355
+ .descrip-name{
356
+ font-size: 26px;
357
+ font-family: 'Microsoft YaHei';
358
+ }
359
+ .masthod-title-description{
360
+ font-family: 'Microsoft YaHei';
361
+ margin-top: 20px;
362
+ }
363
+ .actions-container{
364
+ /* display: flex; */
365
+ /* margin-left: 0px; */
366
+ }
367
+
368
+ .sub-header {
369
+ font-size: 16px;
370
+ margin-left: 5px;
371
+ .btn {
372
+ text-align: left !important;
373
+ }
374
+ }
375
+ </style>
@@ -0,0 +1,140 @@
1
+ <script>
2
+ import { COUNT } from '@shell/config/types';
3
+
4
+ /**
5
+ * Loading Indicator for resources - used when we are loading resources incrementally, by page
6
+ */
7
+ export default {
8
+
9
+ name: 'ResourceLoadingIndicator',
10
+
11
+ props: {
12
+ resources: {
13
+ type: Array,
14
+ required: true,
15
+ },
16
+ indeterminate: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
20
+ },
21
+
22
+ data() {
23
+ const inStore = this.$store.getters['currentStore'](this.resource);
24
+
25
+ return { inStore };
26
+ },
27
+
28
+ computed: {
29
+ // Count of rows - either from the data provided or from the rows for the first resource
30
+ rowsCount() {
31
+ if (this.resources.length > 0) {
32
+ const existingData = this.$store.getters[`${ this.inStore }/all`](this.resources[0]) || [];
33
+
34
+ return (existingData || []).length;
35
+ }
36
+
37
+ return 0;
38
+ },
39
+
40
+ // Have we loaded all resources for the types that are needed
41
+ haveAll() {
42
+ return this.resources.reduce((acc, r) => {
43
+ return acc && this.$store.getters[`${ this.inStore }/haveAll`](r);
44
+ }, true);
45
+ },
46
+
47
+ // Total of all counts of all resources for all of the resources being loaded
48
+ total() {
49
+ const clusterCounts = this.$store.getters[`${ this.inStore }/all`](COUNT);
50
+
51
+ return this.resources.reduce((acc, r) => {
52
+ const resourceCounts = clusterCounts?.[0]?.counts?.[r];
53
+ const resourceCount = resourceCounts?.summary?.count;
54
+ const count = resourceCount || 0;
55
+
56
+ return acc + count;
57
+ }, 0);
58
+ },
59
+
60
+ // Total count of all of the resources for all of the resources being loaded
61
+ count() {
62
+ return this.resources.reduce((acc, r) => {
63
+ return acc + (this.$store.getters[`${ this.inStore }/all`](r) || []).length;
64
+ }, 0);
65
+ },
66
+
67
+ // Width style to enable the progress bar style presentation
68
+ width() {
69
+ const progress = Math.ceil(100 * (this.count / this.total));
70
+
71
+ return `${ progress }%`;
72
+ }
73
+ },
74
+ };
75
+ </script>
76
+
77
+ <template>
78
+ <div
79
+ v-if="count && !haveAll"
80
+ class="resource-loading-indicator"
81
+ >
82
+ <div class="inner">
83
+ <div class="resource-loader">
84
+ <div class="rl-bg">
85
+ <i class="icon icon-spinner icon-spin" /><span>{{ t( 'resourceLoadingIndicator.loading' ) }} <span v-if="!indeterminate">{{ count }} / {{ total }}</span></span>
86
+ </div>
87
+ </div>
88
+ <div
89
+ class="resource-loader"
90
+ :style="{width}"
91
+ >
92
+ <div class="rl-fg">
93
+ <i class="icon icon-spinner icon-spin" /><span>{{ t( 'resourceLoadingIndicator.loading' ) }} <span v-if="!indeterminate">{{ count }} / {{ total }}</span></span>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </template>
99
+
100
+ <style lang="scss" scoped>
101
+ .resource-loading-indicator {
102
+ border: 1px solid var(--link);
103
+ border-radius: 10px;
104
+ position: relative;
105
+ width: min-content;
106
+ overflow: hidden;
107
+
108
+ .resource-loader:last-child {
109
+ position: absolute;
110
+ top: 0;
111
+
112
+ background-color: var(--link);
113
+ color: var(--link-text);
114
+ overflow: hidden;
115
+ white-space: nowrap;
116
+ }
117
+
118
+ .resource-loader {
119
+ padding: 1px 10px;
120
+ width: max-content;
121
+ height: 20px;
122
+
123
+ .rl-fg, .rl-bg {
124
+ display: flex;
125
+ align-content: center;
126
+ font-size: 12px;
127
+
128
+ > i {
129
+ font-size: 18px;
130
+ line-height: 18px;
131
+ }
132
+
133
+ > span {
134
+ margin-top: 2px;
135
+ margin-left: 5px;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ </style>