dashboard-shell-shell 3.0.5-test.6 → 3.0.5-test.8

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 (215) hide show
  1. package/assets/brand/harvester/favicon.png +0 -0
  2. package/assets/brand/suse/favicon.png +0 -0
  3. package/assets/icons/demo.css +539 -0
  4. package/assets/icons/demo.css:Zone.Identifier +0 -0
  5. package/assets/icons/demo_index.html +1131 -0
  6. package/assets/icons/demo_index.html:Zone.Identifier +0 -0
  7. package/assets/icons/iconfont.css +216 -0
  8. package/assets/icons/iconfont.css:Zone.Identifier +0 -0
  9. package/assets/icons/iconfont.js +1 -0
  10. package/assets/icons/iconfont.js:Zone.Identifier +0 -0
  11. package/assets/icons/iconfont.json +324 -0
  12. package/assets/icons/iconfont.json:Zone.Identifier +0 -0
  13. package/assets/icons/iconfont.ttf +0 -0
  14. package/assets/icons/iconfont.ttf:Zone.Identifier +0 -0
  15. package/assets/icons/iconfont.woff +0 -0
  16. package/assets/icons/iconfont.woff2 +0 -0
  17. package/assets/icons/iconfont.woff2:Zone.Identifier +0 -0
  18. package/assets/icons/iconfont.woff:Zone.Identifier +0 -0
  19. package/assets/images/API.svg +3 -0
  20. package/assets/images/action.svg +6 -0
  21. package/assets/images/login/password.svg +20 -0
  22. package/assets/images/login/user.svg +6 -0
  23. package/assets/images/login-bg.png +0 -0
  24. package/assets/images/login-left.png +0 -0
  25. package/assets/images/login-logo.svg +19 -0
  26. package/assets/images/logo.png +0 -0
  27. package/assets/images/pl/half-logo.svg +2 -23
  28. package/assets/images/pl/harvester.png +0 -0
  29. package/assets/images/pl/logo.png +0 -0
  30. package/assets/images/promp-yellow.svg +5 -0
  31. package/assets/images/user.png +0 -0
  32. package/assets/styles/all.scss +63 -0
  33. package/assets/styles/app.scss +4 -0
  34. package/assets/styles/base/_basic.scss +2 -2
  35. package/assets/styles/base/_mixins.scss +1 -1
  36. package/assets/styles/base/_typography.scss +2 -1
  37. package/assets/styles/base/_variables.scss +14 -7
  38. package/assets/styles/global/_button.scss +43 -25
  39. package/assets/styles/global/_columns.scss +3 -1
  40. package/assets/styles/global/_form.scss +45 -13
  41. package/assets/styles/global/_labeled-input.scss +54 -26
  42. package/assets/styles/global/_layout.scss +8 -3
  43. package/assets/styles/global/_select.scss +25 -17
  44. package/assets/styles/global/_table.scss +7 -1
  45. package/assets/styles/global/_tooltip.scss +56 -8
  46. package/assets/styles/themes/_dark.scss +3 -0
  47. package/assets/styles/themes/_light.scss +66 -43
  48. package/assets/styles/vendor/vue-select.scss +22 -9
  49. package/assets/translations/en-us.yaml +28 -4
  50. package/assets/translations/zh-hans.yaml +452 -189
  51. package/components/ActionDropdown.vue +2 -1
  52. package/components/ActionMenu.vue +2 -2
  53. package/components/ActionMenuShell.vue +2 -0
  54. package/components/AppModal.vue +46 -5
  55. package/components/BrandImage.vue +1 -0
  56. package/components/ButtonDropdown.vue +26 -4
  57. package/components/ButtonMultiAction.vue +1 -0
  58. package/components/ClusterIconMenu.vue +1 -1
  59. package/components/CodeMirror.vue +20 -6
  60. package/components/ConsumptionGauge.vue +24 -5
  61. package/components/CopyToClipboard.vue +15 -0
  62. package/components/CruResource.vue +9 -8
  63. package/components/CruResourceFooter.vue +2 -2
  64. package/components/DashboardOptions.vue +29 -17
  65. package/components/DotState.vue +84 -0
  66. package/components/Drawer/Chrome.vue +2 -2
  67. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +22 -22
  68. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +1 -1
  69. package/components/Drawer/ResourceDetailDrawer/index.vue +2 -1
  70. package/components/ExplorerMembers.vue +18 -3
  71. package/components/ExplorerProjectsNamespaces.vue +19 -5
  72. package/components/GlobalRoleBindings.vue +112 -48
  73. package/components/GrafanaDashboard.vue +4 -4
  74. package/components/GrowlManager.vue +3 -1
  75. package/components/HardwareResourceGauge.vue +39 -3
  76. package/components/IndentedPanel.vue +4 -10
  77. package/components/InfoBox.vue +3 -3
  78. package/components/InputOrDisplay.vue +28 -2
  79. package/components/LabelValue.vue +20 -1
  80. package/components/ModalWithCard.vue +12 -3
  81. package/components/PodSecurityAdmission.vue +1 -1
  82. package/components/PromptModal.vue +1 -1
  83. package/components/PromptRemove.vue +30 -11
  84. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +1 -3
  85. package/components/Resource/Detail/Metadata/KeyValue.vue +8 -4
  86. package/components/Resource/Detail/Metadata/index.vue +3 -1
  87. package/components/Resource/Detail/TitleBar/Title.vue +4 -3
  88. package/components/Resource/Detail/TitleBar/Top.vue +2 -0
  89. package/components/Resource/Detail/TitleBar/index.vue +109 -24
  90. package/components/ResourceDetail/Masthead/legacy.vue +181 -38
  91. package/components/ResourceDetail/legacy.vue +32 -14
  92. package/components/ResourceList/Masthead.vue +226 -54
  93. package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
  94. package/components/ResourceTable.vue +24 -2
  95. package/components/SideNav.vue +74 -20
  96. package/components/SortableTable/THead.vue +33 -3
  97. package/components/SortableTable/index.vue +1016 -463
  98. package/components/SortableTable/paging.js +26 -16
  99. package/components/SortableTable/selection.js +2 -2
  100. package/components/Tabbed/Tab.vue +3 -3
  101. package/components/Tabbed/index.vue +47 -29
  102. package/components/YamlEditor.vue +0 -1
  103. package/components/auth/Principal.vue +37 -13
  104. package/components/auth/RoleDetailEdit.vue +58 -7
  105. package/components/auth/SelectPrincipal.vue +1 -0
  106. package/components/breadcrumb/index.vue +316 -0
  107. package/components/form/ArrayList.vue +41 -33
  108. package/components/form/ArrayListGrouped.vue +10 -2
  109. package/components/form/ArrayListSelect.vue +1 -1
  110. package/components/form/BannerSettings.vue +64 -59
  111. package/components/form/ChangePassword.vue +4 -4
  112. package/components/form/ColorInput.vue +32 -8
  113. package/components/form/Footer.vue +11 -8
  114. package/components/form/InputWithSelect.vue +8 -5
  115. package/components/form/KeyValue.vue +47 -7
  116. package/components/form/LabeledSelect.vue +214 -242
  117. package/components/form/Labels.vue +3 -3
  118. package/components/form/MatchExpressions.vue +24 -7
  119. package/components/form/Members/ClusterPermissionsEditor.vue +1 -2
  120. package/components/form/Members/MembershipEditor.vue +1 -1
  121. package/components/form/NameNsDescription.vue +59 -20
  122. package/components/form/Password.vue +16 -7
  123. package/components/form/PodAffinity.vue +4 -5
  124. package/components/form/ResourceQuota/Namespace.vue +4 -4
  125. package/components/form/ResourceQuota/NamespaceRow.vue +18 -17
  126. package/components/form/ResourceQuota/Project.vue +4 -4
  127. package/components/form/ResourceQuota/ProjectRow.vue +3 -6
  128. package/components/form/Select.vue +5 -2
  129. package/components/form/SimpleSecretSelector.vue +29 -9
  130. package/components/form/Taints.vue +2 -1
  131. package/components/form/UnitInput.vue +8 -3
  132. package/components/form/WorkloadPorts.vue +143 -123
  133. package/components/formatter/BadgeStateFormatter.vue +8 -5
  134. package/components/formatter/LiveDate.vue +3 -3
  135. package/components/nav/Favorite.vue +5 -1
  136. package/components/nav/Group.vue +132 -99
  137. package/components/nav/Header.vue +124 -27
  138. package/components/nav/HeaderPageActionMenu.vue +1 -0
  139. package/components/nav/NamespaceFilter.vue +20 -17
  140. package/components/nav/TopLevelMenu.vue +182 -119
  141. package/components/nav/Type.vue +63 -41
  142. package/composables/useClickOutside.ts +1 -1
  143. package/config/private-label.js +15 -11
  144. package/config/product/auth.js +17 -7
  145. package/config/product/settings.js +19 -9
  146. package/config/settings.ts +28 -0
  147. package/config/table-headers.js +3 -2
  148. package/dialog/ForceMachineRemoveDialog.vue +2 -2
  149. package/dialog/ScalePoolDownDialog.vue +2 -2
  150. package/edit/management.cattle.io.user.vue +17 -4
  151. package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +19 -19
  152. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +31 -31
  153. package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +36 -12
  154. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +6 -6
  155. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +10 -10
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +4 -4
  157. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +4 -4
  158. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +1 -1
  159. package/edit/monitoring.coreos.com.receiver/types/email.vue +6 -6
  160. package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +10 -10
  161. package/edit/monitoring.coreos.com.receiver/types/pagerduty.vue +5 -5
  162. package/edit/monitoring.coreos.com.receiver/types/slack.vue +4 -4
  163. package/edit/namespace.vue +1 -2
  164. package/edit/token.vue +31 -12
  165. package/edit/workload/index.vue +4 -4
  166. package/list/management.cattle.io.setting.vue +22 -13
  167. package/list/management.cattle.io.user.vue +7 -3
  168. package/list/namespace.vue +3 -0
  169. package/list/provisioning.cattle.io.cluster.vue +6 -7
  170. package/mixins/brand.js +17 -0
  171. package/package.json +1 -1
  172. package/pages/account/pri.vue +229 -0
  173. package/pages/auth/login.vue +220 -52
  174. package/pages/auth/setup.vue +142 -19
  175. package/pages/c/_cluster/_product/namespaces.vue +5 -5
  176. package/pages/c/_cluster/auth/roles/index.vue +56 -5
  177. package/pages/c/_cluster/monitoring/monitor/index.vue +2 -2
  178. package/pages/c/_cluster/settings/banners.vue +174 -102
  179. package/pages/c/_cluster/settings/brand.vue +350 -302
  180. package/pages/c/_cluster/settings/performance.vue +61 -38
  181. package/pages/home.vue +70 -30
  182. package/pages/prefs.vue +27 -25
  183. package/plugins/dashboard-store/resource-class.js +28 -27
  184. package/promptRemove/mixin/roleDeletionCheck.js +2 -2
  185. package/public/index.html +4 -4
  186. package/rancher-components/BadgeState/BadgeState.vue +38 -55
  187. package/rancher-components/Banner/Banner.vue +12 -8
  188. package/rancher-components/Card/Card.vue +7 -8
  189. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -0
  190. package/rancher-components/Form/LabeledInput/LabeledInput.vue +42 -3
  191. package/rancher-components/Form/Radio/RadioButton.vue +35 -11
  192. package/rancher-components/Form/Radio/RadioGroup.vue +13 -5
  193. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +3 -3
  194. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -0
  195. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +12 -4
  196. package/rancher-components/RcDropdown/RcDropdown.vue +35 -7
  197. package/rancher-components/RcDropdown/RcDropdownItem.vue +2 -2
  198. package/rancher-components/RcDropdown/RcDropdownMenu.vue +12 -6
  199. package/rancher-components/RcDropdown/types.ts +1 -0
  200. package/rancher-components/StringList/StringList.vue +1 -1
  201. package/scripts/publish-shell.sh +1 -1
  202. package/static/favicon.ico +0 -0
  203. package/static/favicon.png +0 -0
  204. package/static/loading-indicator.html +3 -3
  205. package/store/i18n.js +5 -2
  206. package/store/modal.ts +3 -3
  207. package/store/prefs.js +11 -4
  208. package/store/type-map.js +32 -2
  209. package/types/shell/index.d.ts +78 -97
  210. package/utils/error.js +89 -8
  211. package/utils/errorTranslate.json +1351 -0
  212. package/utils/router.js +21 -0
  213. package/utils/select.js +26 -3
  214. package/utils/string.js +8 -5
  215. package/utils/title.ts +1 -1
@@ -8,6 +8,7 @@ import { get, clone } from '@shell/utils/object';
8
8
  import { removeObject } from '@shell/utils/array';
9
9
  import { Checkbox } from '@components/Form/Checkbox';
10
10
  import AsyncButton, { ASYNC_BUTTON_STATES } from '@shell/components/AsyncButton';
11
+ import Select from '@shell/components/form/Select';
11
12
  import ActionDropdown from '@shell/components/ActionDropdown';
12
13
  import throttle from 'lodash/throttle';
13
14
  import debounce from 'lodash/debounce';
@@ -58,13 +59,13 @@ export default {
58
59
  THead,
59
60
  Checkbox,
60
61
  AsyncButton,
62
+ Select,
61
63
  ActionDropdown,
62
64
  LabeledSelect,
63
65
  ButtonMultiAction,
64
66
  ActionMenu,
65
67
  ActionDropdownShell,
66
68
  },
67
-
68
69
  mixins: [
69
70
  filtering,
70
71
  sorting,
@@ -130,7 +131,7 @@ export default {
130
131
  },
131
132
  groupSort: {
132
133
  // Field to order groups by, defaults to groupBy
133
- type: String,
134
+ type: Array,
134
135
  default: null
135
136
  },
136
137
 
@@ -389,7 +390,26 @@ export default {
389
390
  hideManualRefreshButton: {
390
391
  type: Boolean,
391
392
  default: false
392
- }
393
+ },
394
+ isBanner: {
395
+ // Show isBanner input to filter rows
396
+ type: Boolean,
397
+ default: false
398
+ },
399
+ marginTopValue: {
400
+ type: Number,
401
+ default: 0
402
+ },
403
+ isFilterLabel: {
404
+ type: Boolean,
405
+ default: false
406
+ },
407
+ searchPlaceholder: {
408
+ // search框内的输入提示
409
+ type: String,
410
+ default: ''
411
+ },
412
+
393
413
  },
394
414
 
395
415
  data() {
@@ -404,11 +424,21 @@ export default {
404
424
 
405
425
  const isLoading = this.loading || false;
406
426
 
427
+ let isCreatable = false;
428
+ const lastPath = this.$route?.path.split('/').pop();
429
+
430
+ if (lastPath.includes('.')) {
431
+ isCreatable = this.$store.getters['type-map/optionsFor'](lastPath).isCreatable;
432
+ } else if (lastPath === 'namespace') {
433
+ isCreatable = this.$store.getters['type-map/optionsFor'](this.$route.name).isCreatable;
434
+ }
435
+
407
436
  return {
408
437
  refreshButtonPhase: isLoading ? ASYNC_BUTTON_STATES.WAITING : ASYNC_BUTTON_STATES.ACTION,
409
438
  expanded: {},
410
439
  searchQuery,
411
440
  eventualSearchQuery,
441
+ isCreatable,
412
442
  subMatches: null,
413
443
  actionOfInterest: null,
414
444
  loadingDelay: false,
@@ -416,7 +446,28 @@ export default {
416
446
  /**
417
447
  * The is the bool the DOM uses to show loading state. it's proxied from `loading` to avoid blipping the indicator (see usages)
418
448
  */
419
- isLoading
449
+ isLoading,
450
+ isMuchSelected: false,
451
+ inputPerPage: '10',
452
+ inputPage: '', // 输入的要跳至的页码
453
+ perPageOptions: [
454
+ {
455
+ label: '10条/页',
456
+ value: '10',
457
+ },
458
+ {
459
+ label: '25条/页',
460
+ value: '25',
461
+ },
462
+ {
463
+ label: '50条/页',
464
+ value: '50',
465
+ },
466
+ {
467
+ label: '100条/页',
468
+ value: '100',
469
+ }
470
+ ]
420
471
  };
421
472
  },
422
473
 
@@ -431,6 +482,13 @@ export default {
431
482
  this._onScroll = this.onScroll.bind(this);
432
483
  $main?.addEventListener('scroll', this._onScroll);
433
484
 
485
+ const tables = document.querySelectorAll('.sort-table-div');
486
+
487
+ tables.forEach((table) => {
488
+ this._onTableScroll = this.onTableScroll.bind(this, table);
489
+ table.addEventListener('scroll', this._onTableScroll.bind(this, table));
490
+ });
491
+
434
492
  this.debouncedPaginationChanged();
435
493
  },
436
494
 
@@ -445,6 +503,12 @@ export default {
445
503
  const $main = document.querySelector('main');
446
504
 
447
505
  $main?.removeEventListener('scroll', this._onScroll);
506
+ // 移除所有表格容器的滚动事件监听器
507
+ const tables = document.querySelectorAll('.sort-table-div');
508
+
509
+ tables.forEach((table) => {
510
+ table.removeEventListener('scroll', this._onTableScroll);
511
+ });
448
512
  },
449
513
 
450
514
  watch: {
@@ -494,6 +558,14 @@ export default {
494
558
  this.watcherUpdateLiveAndDelayed(neu, old);
495
559
  },
496
560
 
561
+ selectedRowsText(neu, old) {
562
+ if (neu) {
563
+ this.isMuchSelected = true;
564
+ } else {
565
+ this.isMuchSelected = false;
566
+ }
567
+ },
568
+
497
569
  // Ensure we update live and delayed columns on first load
498
570
  initalLoad: {
499
571
  handler(neu) {
@@ -549,17 +621,22 @@ export default {
549
621
  }
550
622
  };
551
623
 
552
- onMounted(() => {
553
- table.value.addEventListener('keyup', handleEnterKey);
554
- });
555
624
 
556
625
  onBeforeUnmount(() => {
557
- table.value.removeEventListener('keyup', handleEnterKey);
626
+ table.value && table.value.removeEventListener('keyup', handleEnterKey);
558
627
  });
559
628
 
560
629
  const store = useStore();
561
630
  const { featureDropdownMenu } = useRuntimeFlag(store);
562
631
 
632
+ onMounted(() => {
633
+ table.value && table.value.addEventListener('keyup', handleEnterKey);
634
+
635
+ console.log(featureDropdownMenu, ' featureDropdownMenu---------------------');
636
+
637
+
638
+ });
639
+
563
640
  return {
564
641
  table,
565
642
  featureDropdownMenu,
@@ -788,11 +865,115 @@ export default {
788
865
  },
789
866
 
790
867
  methods: {
868
+ // getTableList () {
869
+ // const q = this.eventualSearchQuery;
870
+
871
+ // this.searchQuery = q;
872
+
873
+ // if (!this.hasAdvancedFiltering && this.useQueryParamsForSimpleFiltering) {
874
+ // const route = {
875
+ // name: this.$route.name,
876
+ // params: { ...this.$route.params },
877
+ // query: { ...this.$route.query, q }
878
+ // };
879
+
880
+ // if (!q && this.$route.query?.q) {
881
+ // route.query = {};
882
+ // }
883
+
884
+ // this.$router.replace(route);
885
+ // }
886
+ // },
887
+ onTableScroll(table, e) {
888
+ // 记录最后滚动的距离
889
+ let lastScrollTop = 0;
890
+ let lastScrollLeft = 0;
891
+
892
+ // 监听容器滚动
893
+ table.addEventListener('scroll', (e) => {
894
+ // 如果当前垂直滚动距离不等于上次
895
+ if (e.target.scrollTop !== lastScrollTop) {
896
+ // 更新最后距离
897
+ lastScrollTop = e.target.scrollTop;
898
+
899
+ // 移除左右阴影样式
900
+ table.classList.remove('shadow-left');
901
+ table.classList.remove('shadow-right');
902
+
903
+ // 如果滚动到顶部,移除顶部阴影样式
904
+ // if (lastScrollTop === 0) {
905
+ // table.classList.remove('shadow-top');
906
+ // }
907
+ // // 否则添加顶部阴影样式
908
+ // else {
909
+ // table.classList.add('shadow-top');
910
+ // }
911
+
912
+ // 如果滚动到底部,移除底部阴影样式
913
+ // if (lastScrollTop + table.clientHeight === table.scrollHeight) {
914
+ // table.classList.remove('shadow-bottom');
915
+ // }
916
+ // // 否则添加底部阴影样式
917
+ // else {
918
+ // table.classList.add('shadow-bottom');
919
+ // }
920
+
921
+ // 阴影效果修正
922
+ table.classList.remove('shadow-x');
923
+ table.classList.add('shadow-y');
924
+ }
925
+
926
+ // 如果当前水平滚动距离不等于上次
927
+ else if (e.target.scrollLeft !== lastScrollLeft) {
928
+ // 更新最后距离
929
+ lastScrollLeft = e.target.scrollLeft;
930
+
931
+ // 移除上下阴影样式
932
+ // table.classList.remove('shadow-top');
933
+ // table.classList.remove('shadow-bottom');
934
+
935
+ // 如果滚动到左边,移除左边阴影样式
936
+ if (lastScrollLeft === 0) {
937
+ table.classList.remove('shadow-left');
938
+ }
939
+ // 否则添加左边阴影样式
940
+ else {
941
+ table.classList.add('shadow-left');
942
+ }
943
+
944
+ // 如果滚动到右边,移除右边阴影样式
945
+ if (lastScrollLeft + table.clientWidth === table.scrollWidth) {
946
+ table.classList.remove('shadow-right');
947
+ }
948
+ // 否则添加右边阴影样式
949
+ else {
950
+ table.classList.add('shadow-right');
951
+ }
952
+
953
+ // 阴影效果修正
954
+ table.classList.remove('shadow-y');
955
+ table.classList.add('shadow-x');
956
+ }
957
+ });
958
+ },
959
+ changePerPage(value) {
960
+ this.inputPerPage = value;
961
+ this.setgetPerPage(value);
962
+ },
963
+ handleToPage() {
964
+ this.setPage(parseInt(this.inputPage, 10));
965
+ },
791
966
  refreshTableData() {
792
967
  this.$store.dispatch('resource-fetch/doManualRefresh');
793
968
  },
794
969
  get,
795
970
  dasherize,
971
+ muchSelect(value) {
972
+ console.log(value);
973
+
974
+ this.isMuchSelected = !this.isMuchSelected;
975
+ this.onToggleAll(value);
976
+ },
796
977
 
797
978
  onScroll() {
798
979
  if (this.hasLiveColumns || this.hasDelayedColumns) {
@@ -1076,120 +1257,30 @@ export default {
1076
1257
  ref="container"
1077
1258
  :data-testid="componentTestid + '-list-container'"
1078
1259
  >
1260
+ <!-- 主标题和过滤器区域 -->
1079
1261
  <div
1080
- :class="{'titled': $slots.title && $slots.title.length}"
1081
- class="sortable-table-header"
1262
+ :class="{'titled': $slots.title && $slots.title.length, 'mb-40': isFilterLabel}"
1263
+ class="sortable-table-header mb-20"
1082
1264
  >
1083
1265
  <slot name="title" />
1266
+
1267
+ <!-- 顶部功能行区域 -->
1084
1268
  <div
1085
1269
  v-if="showHeaderRow"
1086
- class="fixed-header-actions"
1087
- :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering}"
1270
+ class="fixed-header-table-actions"
1271
+ :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering, }"
1272
+ style="display: flex;"
1088
1273
  >
1089
- <div
1090
- :class="bulkActionsClass"
1091
- class="bulk"
1092
- >
1093
- <slot name="header-left">
1094
- <template v-if="tableActions">
1095
- <button
1096
- v-for="(act) in availableActions"
1097
- :id="act.action"
1098
- :key="act.action"
1099
- v-clean-tooltip="actionTooltip"
1100
- type="button"
1101
- class="btn role-primary"
1102
- :class="{[bulkActionClass]:true}"
1103
- :disabled="!act.enabled"
1104
- :data-testid="componentTestid + '-' + act.action"
1105
- role="button"
1106
- :aria-label="act.label"
1107
- @click="applyTableAction(act, null, $event)"
1108
- @keydown.enter.stop
1109
- @mouseover="setBulkActionOfInterest(act)"
1110
- @mouseleave="setBulkActionOfInterest(null)"
1111
- >
1112
- <i
1113
- v-if="act.icon"
1114
- :class="act.icon"
1115
- />
1116
- <span v-clean-html="act.label" />
1117
- </button>
1118
- <template v-if="featureDropdownMenu">
1119
- <ActionDropdownShell
1120
- :disabled="!selectedRows.length"
1121
- :hidden-actions="hiddenActions"
1122
- :action-tooltip="actionTooltip"
1123
- @click="applyTableAction"
1124
- @mouseover="setBulkActionOfInterest"
1125
- @mouseleave="setBulkActionOfInterest"
1126
- />
1127
- </template>
1128
- <template v-else>
1129
- <ActionDropdown
1130
- :class="bulkActionsDropdownClass"
1131
- class="bulk-actions-dropdown"
1132
- :disable-button="!selectedRows.length"
1133
- size="sm"
1134
- >
1135
- <template #button-content>
1136
- <button
1137
- ref="actionDropDown"
1138
- class="btn bg-primary mr-0"
1139
- :disabled="!selectedRows.length"
1140
- >
1141
- <i class="icon icon-gear" />
1142
- <span>{{ t('sortableTable.bulkActions.collapsed.label') }}</span>
1143
- <i class="ml-10 icon icon-chevron-down" />
1144
- </button>
1145
- </template>
1146
- <template #popover-content>
1147
- <ul class="list-unstyled menu">
1148
- <li
1149
- v-for="(act, i) in hiddenActions"
1150
- :key="i"
1151
- v-close-popper
1152
- v-clean-tooltip="{
1153
- content: actionTooltip,
1154
- placement: 'right'
1155
- }"
1156
- :class="{ disabled: !act.enabled }"
1157
- @click="applyTableAction(act, null, $event)"
1158
- @mouseover="setBulkActionOfInterest(act)"
1159
- @mouseleave="setBulkActionOfInterest(null)"
1160
- >
1161
- <i
1162
- v-if="act.icon"
1163
- :class="act.icon"
1164
- />
1165
- <span v-clean-html="act.label" />
1166
- </li>
1167
- </ul>
1168
- </template>
1169
- </ActionDropdown>
1170
- </template>
1171
- <label
1172
- v-if="selectedRowsText"
1173
- :class="bulkActionAvailabilityClass"
1174
- class="action-availability"
1175
- >
1176
- {{ selectedRowsText }}
1177
- </label>
1178
- </template>
1179
- </slot>
1180
- </div>
1181
- <div
1182
- v-if="!hasAdvancedFiltering && $slots['header-middle']"
1183
- class="middle"
1184
- >
1185
- <slot name="header-middle" />
1186
- </div>
1187
1274
 
1275
+ <!-- 搜索栏、右插槽、刷新按钮、高级筛选等区域 -->
1188
1276
  <div
1189
1277
  v-if="search || hasAdvancedFiltering || isTooManyItemsToAutoUpdate || $slots['header-right']"
1190
1278
  class="search row"
1191
1279
  data-testid="search-box-filter-row"
1280
+ style="max-height: 32px;"
1192
1281
  >
1282
+
1283
+ <!-- 已应用的高级筛选 -->
1193
1284
  <ul
1194
1285
  v-if="hasAdvancedFiltering"
1195
1286
  class="advanced-filters-applied"
@@ -1206,15 +1297,9 @@ export default {
1206
1297
  <div class="bg" />
1207
1298
  </li>
1208
1299
  </ul>
1209
- <slot name="watch-controls" />
1300
+
1210
1301
  <slot name="header-right" />
1211
- <AsyncButton
1212
- v-if="!hideManualRefreshButton && isTooManyItemsToAutoUpdate"
1213
- mode="manual-refresh"
1214
- :size="manualRefreshButtonSize"
1215
- :current-phase="refreshButtonPhase"
1216
- @click="debouncedRefreshTableData"
1217
- />
1302
+
1218
1303
  <div
1219
1304
  v-if="hasAdvancedFiltering"
1220
1305
  ref="advanced-filter-group"
@@ -1270,6 +1355,8 @@ export default {
1270
1355
  </div>
1271
1356
  </div>
1272
1357
  </div>
1358
+
1359
+ <!-- 搜索描述文本(隐藏) -->
1273
1360
  <p
1274
1361
  v-else-if="search"
1275
1362
  id="describe-filter-sortable-table"
@@ -1277,375 +1364,614 @@ export default {
1277
1364
  >
1278
1365
  {{ t('sortableTable.filteringDescription') }}
1279
1366
  </p>
1280
- <input
1281
- v-if="search"
1282
- ref="searchQuery"
1283
- v-model="eventualSearchQuery"
1284
- type="search"
1285
- class="input-sm search-box"
1286
- :aria-label="t('sortableTable.searchLabel')"
1287
- aria-describedby="describe-filter-sortable-table"
1288
- :placeholder="t('sortableTable.search')"
1289
- >
1290
1367
  <slot name="header-button" />
1368
+
1369
+ <div style="display: flex;">
1370
+
1371
+ <slot name="search-main-button" />
1372
+
1373
+ <!-- 搜索输入框 -->
1374
+ <input
1375
+ v-if="search"
1376
+ ref="searchQuery"
1377
+ v-model="eventualSearchQuery"
1378
+ type="search"
1379
+ class="input-sm search-box"
1380
+ :aria-label="t('sortableTable.searchLabel')"
1381
+ aria-describedby="describe-filter-sortable-table"
1382
+ :placeholder="t('sortableTable.search')+searchPlaceholder"
1383
+ >
1384
+ <!-- <button v-if="search" @click="getTableList(eventualSearchQuery)" calss="search-btn role-secondary">
1385
+ 检索
1386
+ </button> -->
1387
+
1388
+ <!-- 手动刷新按钮 -->
1389
+ <AsyncButton
1390
+ v-if="isTooManyItemsToAutoUpdate"
1391
+ mode="manual-refresh"
1392
+ :size="manualRefreshButtonSize"
1393
+ :current-phase="refreshButtonPhase"
1394
+ @click="debouncedRefreshTableData"
1395
+ />
1396
+
1397
+ </div>
1398
+
1399
+ </div>
1400
+
1401
+ <!-- 中间区域插槽 -->
1402
+ <div
1403
+ v-if="!hasAdvancedFiltering && $slots['header-middle']"
1404
+ class="middle"
1405
+ style="margin-left: 10px;"
1406
+ >
1407
+ <slot name="header-middle" />
1291
1408
  </div>
1292
1409
  </div>
1293
1410
  </div>
1294
- <table
1295
- ref="table"
1296
- class="sortable-table"
1297
- :class="classObject"
1298
- width="100%"
1299
- role="table"
1300
- >
1301
- <THead
1302
- v-if="showHeaders"
1303
- :label-for="labelFor"
1304
- :columns="columns"
1305
- :group="group"
1306
- :group-options="advGroupOptions"
1307
- :has-advanced-filtering="hasAdvancedFiltering"
1308
- :adv-filter-hide-labels-as-cols="advFilterHideLabelsAsCols"
1309
- :table-actions="tableActions"
1310
- :table-cols-options="columnOptions"
1311
- :row-actions="rowActions"
1312
- :sub-expand-column="subExpandColumn"
1313
- :row-actions-width="rowActionsWidth"
1314
- :how-much-selected="howMuchSelected"
1315
- :sort-by="sortBy"
1316
- :default-sort-by="_defaultSortBy"
1317
- :descending="descending"
1318
- :no-rows="noRows"
1319
- :loading="isLoading && !loadingDelay"
1320
- :no-results="noResults"
1321
- @on-toggle-all="onToggleAll"
1322
- @on-sort-change="changeSort"
1323
- @col-visibility-change="changeColVisibility"
1324
- @group-value-change="(val) => $emit('group-value-change', val)"
1325
- @update-cols-options="updateColsOptions"
1326
- />
1327
1411
 
1328
- <!-- Don't display anything if we're loading and the delay has yet to pass -->
1329
- <div v-if="isLoading && !loadingDelay" />
1412
+ <div v-if="$slots['banner']">
1413
+ <slot name="banner"></slot>
1414
+ </div>
1415
+
1416
+ <div class="sort-table-div">
1417
+ <table
1418
+ ref="table"
1419
+ class="sortable-table"
1420
+ :class="classObject"
1421
+ width="100%"
1422
+ role="table"
1423
+ >
1424
+ <THead
1425
+ v-if="showHeaders"
1426
+ :label-for="labelFor"
1427
+ :columns="columns"
1428
+ :group="group"
1429
+ :group-options="advGroupOptions"
1430
+ :has-advanced-filtering="hasAdvancedFiltering"
1431
+ :adv-filter-hide-labels-as-cols="advFilterHideLabelsAsCols"
1432
+ :table-actions="tableActions"
1433
+ :table-cols-options="columnOptions"
1434
+ :row-actions="rowActions"
1435
+ :sub-expand-column="subExpandColumn"
1436
+ :row-actions-width="rowActionsWidth"
1437
+ :how-much-selected="howMuchSelected"
1438
+ :sort-by="sortBy"
1439
+ :default-sort-by="_defaultSortBy"
1440
+ :descending="descending"
1441
+ :no-rows="noRows"
1442
+ :loading="isLoading && !loadingDelay"
1443
+ :no-results="noResults"
1444
+ @on-toggle-all="onToggleAll"
1445
+ @on-sort-change="changeSort"
1446
+ @col-visibility-change="changeColVisibility"
1447
+ @group-value-change="(val) => $emit('group-value-change', val)"
1448
+ @update-cols-options="updateColsOptions"
1449
+ />
1330
1450
 
1331
- <tbody v-else-if="isLoading && !altLoading">
1332
- <slot name="loading">
1333
- <tr>
1334
- <td :colspan="fullColspan">
1335
- <div class="data-loading">
1336
- <i class="icon-spin icon icon-spinner" />
1451
+ <!-- Don't display anything if we're loading and the delay has yet to pass -->
1452
+ <div v-if="isLoading && !loadingDelay" />
1453
+
1454
+ <tbody v-else-if="isLoading && !altLoading">
1455
+ <slot name="loading">
1456
+ <tr>
1457
+ <td :colspan="fullColspan">
1458
+ <div class="data-loading">
1459
+ <i class="icon-spin icon icon-spinner" />
1460
+ <t
1461
+ k="generic.loading"
1462
+ :raw="true"
1463
+ />
1464
+ </div>
1465
+ </td>
1466
+ </tr>
1467
+ </slot>
1468
+ </tbody>
1469
+ <tbody v-else-if="noRows">
1470
+ <slot name="no-rows">
1471
+ <tr class="no-rows">
1472
+ <td :colspan="fullColspan">
1337
1473
  <t
1338
- k="generic.loading"
1339
- :raw="true"
1474
+ v-if="showNoRows"
1475
+ :k="noRowsKey"
1340
1476
  />
1341
- </div>
1342
- </td>
1343
- </tr>
1344
- </slot>
1345
- </tbody>
1346
- <tbody v-else-if="noRows">
1347
- <slot name="no-rows">
1348
- <tr class="no-rows">
1349
- <td :colspan="fullColspan">
1350
- <t
1351
- v-if="showNoRows"
1352
- :k="noRowsKey"
1353
- />
1354
- </td>
1355
- </tr>
1356
- </slot>
1357
- </tbody>
1358
- <tbody v-else-if="noResults">
1359
- <slot name="no-results">
1360
- <tr class="no-results">
1361
- <td
1362
- :colspan="fullColspan"
1363
- class="text-center"
1364
- >
1365
- <t :k="noDataKey" />
1366
- </td>
1367
- </tr>
1368
- </slot>
1369
- </tbody>
1370
- <tbody
1371
- v-for="(groupedRows) in displayRows"
1372
- v-else
1373
- :key="groupedRows.key"
1374
- tabindex="-1"
1375
- :class="{ group: groupBy }"
1376
- >
1377
- <slot
1378
- v-if="groupBy"
1379
- name="group-row"
1380
- :group="groupedRows"
1381
- :fullColspan="fullColspan"
1382
- >
1383
- <tr class="group-row">
1384
- <td :colspan="fullColspan">
1385
- <slot
1386
- name="group-by"
1387
- :group="groupedRows.grp"
1477
+ </td>
1478
+ </tr>
1479
+ </slot>
1480
+ </tbody>
1481
+ <tbody v-else-if="noResults">
1482
+ <slot name="no-results">
1483
+ <tr class="no-results">
1484
+ <td
1485
+ :colspan="fullColspan"
1486
+ class="text-center"
1388
1487
  >
1389
- <div
1390
- v-trim-whitespace
1391
- class="group-tab"
1392
- >
1393
- {{ groupedRows.ref }}
1394
- </div>
1395
- </slot>
1396
- </td>
1397
- </tr>
1398
- </slot>
1399
- <template
1400
- v-for="(row, i) in groupedRows.rows"
1401
- :key="i"
1488
+ <t :k="noDataKey" />
1489
+ </td>
1490
+ </tr>
1491
+ </slot>
1492
+ </tbody>
1493
+ <tbody
1494
+ v-for="(groupedRows) in displayRows"
1495
+ v-else
1496
+ :key="groupedRows.key"
1497
+ tabindex="-1"
1498
+ :class="{ group: groupBy }"
1402
1499
  >
1403
1500
  <slot
1404
- name="main-row"
1405
- :row="row.row"
1501
+ v-if="groupBy"
1502
+ name="group-row"
1503
+ :group="groupedRows"
1504
+ :fullColspan="fullColspan"
1505
+ >
1506
+ <tr class="group-row">
1507
+ <td :colspan="fullColspan">
1508
+ <slot
1509
+ name="group-by"
1510
+ :group="groupedRows.grp"
1511
+ >
1512
+ <div
1513
+ v-trim-whitespace
1514
+ class="group-tab"
1515
+ >
1516
+ {{ groupedRows.ref }}
1517
+ </div>
1518
+ </slot>
1519
+ </td>
1520
+ </tr>
1521
+ </slot>
1522
+ <template
1523
+ v-for="(row, i) in groupedRows.rows"
1524
+ :key="i"
1406
1525
  >
1407
1526
  <slot
1408
- :name="'main-row:' + (row.row.mainRowKey || i)"
1409
- :full-colspan="fullColspan"
1527
+ name="main-row"
1528
+ :row="row.row"
1410
1529
  >
1411
- <!-- The data-cant-run-bulk-action-of-interest attribute is being used instead of :class because
1412
- because our selection.js invokes toggleClass and :class clobbers what was added by toggleClass if
1413
- the value of :class changes. -->
1414
- <tr
1415
- class="main-row"
1416
- :data-testid="componentTestid + '-' + i + '-row'"
1417
- :class="{ 'has-sub-row': row.showSubRow}"
1418
- :data-node-id="row.key"
1419
- :data-cant-run-bulk-action-of-interest="actionOfInterest && !row.canRunBulkActionOfInterest"
1530
+ <slot
1531
+ :name="'main-row:' + (row.row.mainRowKey || i)"
1532
+ :full-colspan="fullColspan"
1420
1533
  >
1421
- <td
1422
- v-if="tableActions"
1423
- class="row-check"
1424
- align="middle"
1425
- >
1426
- {{ row.mainRowKey }}
1427
- <Checkbox
1428
- class="selection-checkbox"
1429
- :data-node-id="row.key"
1430
- :data-testid="componentTestid + '-' + i + '-checkbox'"
1431
- :value="selectedRows.includes(row.row)"
1432
- :alternate-label="t('sortableTable.genericRowCheckbox', { item: row && row.row ? row.row.id : '' })"
1433
- />
1434
- </td>
1435
- <td
1436
- v-if="subExpandColumn"
1437
- class="row-expand"
1438
- align="middle"
1534
+ <!-- The data-cant-run-bulk-action-of-interest attribute is being used instead of :class because
1535
+ because our selection.js invokes toggleClass and :class clobbers what was added by toggleClass if
1536
+ the value of :class changes. -->
1537
+ <tr
1538
+ class="main-row"
1539
+ :data-testid="componentTestid + '-' + i + '-row'"
1540
+ :class="{ 'has-sub-row': row.showSubRow}"
1541
+ :data-node-id="row.key"
1542
+ :data-cant-run-bulk-action-of-interest="actionOfInterest && !row.canRunBulkActionOfInterest"
1439
1543
  >
1440
- <i
1441
- data-title="Toggle Expand"
1442
- :class="{
1443
- icon: true,
1444
- 'icon-chevron-right': !expanded[row.row[keyField]],
1445
- 'icon-chevron-down': !!expanded[row.row[keyField]]
1446
- }"
1447
- @click.stop="toggleExpand(row.row)"
1448
- />
1449
- </td>
1450
- <template
1451
- v-for="(col, j) in row.columns"
1452
- :key="j"
1453
- >
1454
- <slot
1455
- :name="'col:' + col.col.name"
1456
- :row="row.row"
1457
- :col="col.col"
1458
- :dt="dt"
1459
- :expanded="expanded"
1460
- :rowKey="row.key"
1544
+ <td
1545
+ v-if="tableActions"
1546
+ class="row-check"
1547
+ align="middle"
1548
+ >
1549
+ {{ row.mainRowKey }}
1550
+ <Checkbox
1551
+ class="selection-checkbox"
1552
+ :data-node-id="row.key"
1553
+ :data-testid="componentTestid + '-' + i + '-checkbox'"
1554
+ :value="selectedRows.includes(row.row)"
1555
+ :alternate-label="t('sortableTable.genericRowCheckbox', { item: row && row.row ? row.row.id : '' })"
1556
+ />
1557
+ </td>
1558
+ <td
1559
+ v-if="subExpandColumn"
1560
+ class="row-expand"
1561
+ align="middle"
1461
1562
  >
1462
- <td
1463
- v-show="!hasAdvancedFiltering || (hasAdvancedFiltering && col.col.isColVisible)"
1464
- :key="col.col.name"
1465
- :data-title="col.col.label"
1466
- :data-testid="`sortable-cell-${ i }-${ j }`"
1467
- :align="col.col.align || 'left'"
1468
- :class="{['col-'+col.dasherize]: !!col.col.formatter, [col.col.breakpoint]: !!col.col.breakpoint, ['skip-select']: col.col.skipSelect}"
1469
- :width="col.col.width"
1563
+ <i
1564
+ data-title="Toggle Expand"
1565
+ :class="{
1566
+ icon: true,
1567
+ 'icon-chevron-right': !expanded[row.row[keyField]],
1568
+ 'icon-chevron-down': !!expanded[row.row[keyField]]
1569
+ }"
1570
+ @click.stop="toggleExpand(row.row)"
1571
+ />
1572
+ </td>
1573
+ <template
1574
+ v-for="(col, j) in row.columns"
1575
+ :key="j"
1576
+ >
1577
+ <slot
1578
+ :name="'col:' + col.col.name"
1579
+ :row="row.row"
1580
+ :col="col.col"
1581
+ :dt="dt"
1582
+ :expanded="expanded"
1583
+ :rowKey="row.key"
1470
1584
  >
1471
- <slot
1472
- :name="'cell:' + col.col.name"
1473
- :row="row.row"
1474
- :col="col.col"
1475
- :value="col.value"
1585
+ <td
1586
+ v-show="!hasAdvancedFiltering || (hasAdvancedFiltering && col.col.isColVisible)"
1587
+ :key="col.col.name"
1588
+ :data-title="col.col.label"
1589
+ :data-testid="`sortable-cell-${ i }-${ j }`"
1590
+ :align="'left'"
1591
+ :class="{['col-'+col.dasherize]: !!col.col.formatter, [col.col.breakpoint]: !!col.col.breakpoint, ['skip-select']: col.col.skipSelect}"
1592
+ :width="col.col.width"
1476
1593
  >
1477
- <component
1478
- :is="col.component"
1479
- v-if="col.component && col.needRef"
1480
- ref="column"
1481
- :value="col.value"
1594
+ <slot
1595
+ :name="'cell:' + col.col.name"
1482
1596
  :row="row.row"
1483
1597
  :col="col.col"
1484
- :get-custom-detail-link="getCustomDetailLink"
1485
- v-bind="col.col.formatterOpts"
1486
- :row-key="row.key"
1487
- />
1488
- <component
1489
- :is="col.component"
1490
- v-else-if="col.component"
1491
1598
  :value="col.value"
1492
- :row="row.row"
1493
- :col="col.col"
1494
- v-bind="col.col.formatterOpts"
1495
- :row-key="row.key"
1599
+ >
1600
+ <component
1601
+ :is="col.component"
1602
+ v-if="col.component && col.needRef"
1603
+ ref="column"
1604
+ :value="col.value"
1605
+ :row="row.row"
1606
+ :col="col.col"
1607
+ :get-custom-detail-link="getCustomDetailLink"
1608
+ v-bind="col.col.formatterOpts"
1609
+ :row-key="row.key"
1610
+ />
1611
+ <component
1612
+ :is="col.component"
1613
+ v-else-if="col.component"
1614
+ :value="col.value"
1615
+ :row="row.row"
1616
+ :col="col.col"
1617
+ v-bind="col.col.formatterOpts"
1618
+ :row-key="row.key"
1619
+ />
1620
+ <component
1621
+ :is="col.col.formatter"
1622
+ v-else-if="col.col.formatter"
1623
+ :value="col.value"
1624
+ :row="row.row"
1625
+ :col="col.col"
1626
+ v-bind="col.col.formatterOpts"
1627
+ :row-key="row.key"
1628
+ />
1629
+ <template v-else-if="col.value !== ''">
1630
+ {{ col.formatted }}
1631
+ </template>
1632
+ <template v-else-if="col.col.dashIfEmpty">
1633
+ <span class="text-muted">&mdash;</span>
1634
+ </template>
1635
+ </slot>
1636
+ </td>
1637
+ </slot>
1638
+ </template>
1639
+ <td
1640
+ v-if="rowActions"
1641
+ :align="'left'"
1642
+ style="height:60px"
1643
+ >
1644
+ <div style="display: flex;align-items: center;">
1645
+ <slot
1646
+ name="row-actions"
1647
+ :row="row.row"
1648
+ :index="i"
1649
+ >
1650
+ </slot>
1651
+ <template v-if="featureDropdownMenu">
1652
+ <ActionMenu
1653
+ :resource="row.row"
1654
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1655
+ :button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1496
1656
  />
1497
- <component
1498
- :is="col.col.formatter"
1499
- v-else-if="col.col.formatter"
1500
- :value="col.value"
1501
- :row="row.row"
1502
- :col="col.col"
1503
- v-bind="col.col.formatterOpts"
1504
- :row-key="row.key"
1657
+ </template>
1658
+ <template v-else>
1659
+ <ButtonMultiAction
1660
+ :id="`actionButton+${i}+${(row.row && row.row.name) ? row.row.name : ''}`"
1661
+ :ref="`actionButton${i}`"
1662
+ aria-haspopup="true"
1663
+ aria-expanded="false"
1664
+ :aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1665
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1666
+ :borderless="true"
1667
+ @click="handleActionButtonClick(i, $event)"
1668
+ @keyup.enter="handleActionButtonClick(i, $event)"
1669
+ @keyup.space="handleActionButtonClick(i, $event)"
1505
1670
  />
1506
- <template v-else-if="col.value !== ''">
1507
- {{ col.formatted }}
1508
- </template>
1509
- <template v-else-if="col.col.dashIfEmpty">
1510
- <span class="text-muted">&mdash;</span>
1511
- </template>
1512
- </slot>
1513
- </td>
1514
- </slot>
1515
- </template>
1671
+ </template>
1672
+ </div>
1673
+ </td>
1674
+ </tr>
1675
+ </slot>
1676
+ </slot>
1677
+ <!-- <slot
1678
+ v-if="row.showSubRow"
1679
+ name="sub-row"
1680
+ :full-colspan="fullColspan"
1681
+ :row="row.row"
1682
+ :sub-matches="subMatches"
1683
+ :keyField="keyField"
1684
+ :componentTestid="componentTestid"
1685
+ :i="i"
1686
+ :onRowMouseEnter="onRowMouseEnter"
1687
+ :onRowMouseLeave="onRowMouseLeave"
1688
+ >
1689
+ <tr
1690
+ v-if="row.row.stateDescription"
1691
+ :key="row.row[keyField] + '-description'"
1692
+ :data-testid="componentTestid + '-' + i + '-row-description'"
1693
+ class="state-description sub-row"
1694
+ @mouseenter="onRowMouseEnter"
1695
+ @mouseleave="onRowMouseLeave"
1696
+ >
1697
+ <td
1698
+ v-if="tableActions"
1699
+ class="row-check"
1700
+ align="middle"
1701
+ />
1516
1702
  <td
1517
- v-if="rowActions"
1703
+ :colspan="fullColspan - (tableActions ? 1: 0)"
1704
+ :class="{ 'text-error' : row.row.stateObj.error }"
1518
1705
  >
1519
- <slot
1520
- name="row-actions"
1521
- :row="row.row"
1522
- :index="i"
1523
- >
1524
- <template v-if="featureDropdownMenu">
1525
- <ActionMenu
1526
- :resource="row.row"
1527
- :data-testid="componentTestid + '-' + i + '-action-button'"
1528
- :button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1529
- />
1530
- </template>
1531
- <template v-else>
1532
- <ButtonMultiAction
1533
- :id="`actionButton+${i}+${(row.row && row.row.name) ? row.row.name : ''}`"
1534
- :ref="`actionButton${i}`"
1535
- aria-haspopup="true"
1536
- aria-expanded="false"
1537
- :aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1538
- :data-testid="componentTestid + '-' + i + '-action-button'"
1539
- :borderless="true"
1540
- @click="handleActionButtonClick(i, $event)"
1541
- @keyup.enter="handleActionButtonClick(i, $event)"
1542
- @keyup.space="handleActionButtonClick(i, $event)"
1543
- />
1544
- </template>
1545
- </slot>
1706
+ {{ row.row.stateDescription }}
1546
1707
  </td>
1547
1708
  </tr>
1548
- </slot>
1549
- </slot>
1550
- <slot
1551
- v-if="row.showSubRow"
1552
- name="sub-row"
1553
- :full-colspan="fullColspan"
1554
- :row="row.row"
1555
- :sub-matches="subMatches"
1556
- :keyField="keyField"
1557
- :componentTestid="componentTestid"
1558
- :i="i"
1559
- :onRowMouseEnter="onRowMouseEnter"
1560
- :onRowMouseLeave="onRowMouseLeave"
1561
- >
1562
- <tr
1563
- v-if="row.row.stateDescription"
1564
- :key="row.row[keyField] + '-description'"
1565
- :data-testid="componentTestid + '-' + i + '-row-description'"
1566
- class="state-description sub-row"
1567
- @mouseenter="onRowMouseEnter"
1568
- @mouseleave="onRowMouseLeave"
1569
- >
1570
- <td
1571
- v-if="tableActions"
1572
- class="row-check"
1573
- align="middle"
1574
- />
1575
- <td
1576
- :colspan="fullColspan - (tableActions ? 1: 0)"
1577
- :class="{ 'text-error' : row.row.stateObj.error }"
1578
- >
1579
- {{ row.row.stateDescription }}
1580
- </td>
1581
- </tr>
1582
- </slot>
1583
- </template>
1584
- </tbody>
1585
- </table>
1709
+ </slot> -->
1710
+ </template>
1711
+ </tbody>
1712
+ </table>
1713
+ </div>
1586
1714
  <div
1587
- v-if="showPaging"
1588
- class="paging"
1715
+ v-if="!noRows && !noResults"
1716
+ :class="$route.path=== '/account'? 'chebox-padding':''"
1717
+ style="display: flex;justify-content: flex-start;align-content: center;height: 62px;position: sticky;bottom: 0;background-color: var(--header-bg);padding: 15px 20px 0 30px;margin: 0 -20px 0 -20px;z-index:13"
1589
1718
  >
1590
- <button
1591
- type="button"
1592
- class="btn btn-sm role-multi-action"
1593
- data-testid="pagination-first"
1594
- :disabled="page == 1 || loading"
1595
- role="button"
1596
- :aria-label="t('sortableTable.ariaLabel.firstPageBtn')"
1597
- @click="goToPage('first')"
1598
- >
1599
- <i
1600
- class="icon icon-chevron-beginning"
1601
- :alt="t('sortableTable.alt.firstPageBtn')"
1719
+ <div style="display: flex;justify-content: center;height: 32px;">
1720
+ <Checkbox
1721
+ v-if="tableActions&&availableActions.some(item => item.action != 'download')"
1722
+ :value="isMuchSelected"
1723
+ class="check"
1724
+ data-testid="sortable-table_check_select_all"
1725
+ :disabled="noRows || noResults"
1726
+ style="display: flex;justify-content: center;align-content: center;"
1727
+ @update:value = "muchSelect"
1602
1728
  />
1603
- </button>
1604
- <button
1605
- type="button"
1606
- class="btn btn-sm role-multi-action"
1607
- data-testid="pagination-prev"
1608
- :disabled="page == 1 || loading"
1609
- role="button"
1610
- :aria-label="t('sortableTable.ariaLabel.prevPageBtn')"
1611
- @click="goToPage('prev')"
1729
+ </div>
1730
+ <div
1731
+ :class="{'titled': $slots.title && $slots.title.length}"
1732
+ class="sortable-table-header"
1733
+ style="margin-left: 10px;min-width: 55%;"
1612
1734
  >
1613
- <i
1614
- class="icon icon-chevron-left"
1615
- :alt="t('sortableTable.alt.prevPageBtn')"
1616
- />
1617
- </button>
1618
- <span>
1619
- {{ pagingDisplay }}
1620
- </span>
1621
- <button
1622
- type="button"
1623
- class="btn btn-sm role-multi-action"
1624
- data-testid="pagination-next"
1625
- :disabled="page == totalPages || loading"
1626
- role="button"
1627
- :aria-label="t('sortableTable.ariaLabel.nextPageBtn')"
1628
- @click="goToPage('next')"
1735
+ <slot name="title" />
1736
+ <div
1737
+ v-if="showHeaderRow"
1738
+ class="fixed-footer-actions"
1739
+ :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering,}"
1740
+ >
1741
+ <div
1742
+ :class="bulkActionsClass"
1743
+ class="bulk"
1744
+ >
1745
+ <slot name="header-left">
1746
+ <template v-if="tableActions">
1747
+ <button
1748
+ v-for="(act) in availableActions"
1749
+ :id="act.action"
1750
+ :key="act.action"
1751
+ v-clean-tooltip="actionTooltip"
1752
+ type="button"
1753
+ class="btn role-primary"
1754
+ :class="{[bulkActionClass]:true}"
1755
+ :disabled="!act.enabled"
1756
+ :data-testid="componentTestid + '-' + act.action"
1757
+ role="button"
1758
+ :aria-label="act.label"
1759
+ @click="applyTableAction(act, null, $event)"
1760
+ @keydown.enter.stop
1761
+ @mouseover="setBulkActionOfInterest(act)"
1762
+ @mouseleave="setBulkActionOfInterest(null)"
1763
+ >
1764
+ <!-- <i
1765
+ v-if="act.icon"
1766
+ :class="act.icon"
1767
+ style="line-height: 12px;height: 12px;font-size: 12px;"
1768
+ /> -->
1769
+ <span v-clean-html="act.label" />
1770
+ </button>
1771
+ <template v-if="featureDropdownMenu">
1772
+ <ActionDropdownShell
1773
+ :disabled="!selectedRows.length"
1774
+ :hidden-actions="hiddenActions"
1775
+ :action-tooltip="actionTooltip"
1776
+ @click="applyTableAction"
1777
+ @mouseover="setBulkActionOfInterest"
1778
+ @mouseleave="setBulkActionOfInterest"
1779
+ />
1780
+ </template>
1781
+ <template v-else>
1782
+ <ActionDropdown
1783
+ :class="bulkActionsDropdownClass"
1784
+ class="bulk-actions-dropdown"
1785
+ :disable-button="!selectedRows.length"
1786
+ size="sm"
1787
+ >
1788
+ <template #button-content>
1789
+ <button
1790
+ ref="actionDropDown"
1791
+ class="btn bg-primary mr-0"
1792
+ :disabled="!selectedRows.length"
1793
+ >
1794
+ <i class="icon icon-gear" />
1795
+ <span>{{ t('sortableTable.bulkActions.collapsed.label') }}</span>
1796
+ <i class="ml-10 icon icon-chevron-down" />
1797
+ </button>
1798
+ </template>
1799
+ <template #popover-content>
1800
+ <ul class="list-unstyled menu">
1801
+ <li
1802
+ v-for="(act, i) in hiddenActions"
1803
+ :key="i"
1804
+ v-close-popper
1805
+ v-clean-tooltip="{
1806
+ content: actionTooltip,
1807
+ placement: 'right'
1808
+ }"
1809
+ :class="{ disabled: !act.enabled }"
1810
+ @click="applyTableAction(act, null, $event)"
1811
+ @mouseover="setBulkActionOfInterest(act)"
1812
+ @mouseleave="setBulkActionOfInterest(null)"
1813
+ >
1814
+ <i
1815
+ v-if="act.icon"
1816
+ :class="act.icon"
1817
+ />
1818
+ <span v-clean-html="act.label" />
1819
+ </li>
1820
+ </ul>
1821
+ </template>
1822
+ </ActionDropdown>
1823
+ </template>
1824
+ <label
1825
+ v-if="selectedRowsText"
1826
+ :class="bulkActionAvailabilityClass"
1827
+ class="action-availability"
1828
+ >
1829
+ {{ tableActions&&availableActions.some(item => item.action != 'download') ?selectedRowsText: '' }}
1830
+ </label>
1831
+
1832
+ </template>
1833
+ </slot>
1834
+ </div>
1835
+ </div>
1836
+ </div>
1837
+
1838
+ <!-- 分页 -->
1839
+ <div
1840
+ v-if="showPaging"
1841
+ class="paging"
1629
1842
  >
1630
- <i
1631
- class="icon icon-chevron-right"
1632
- :alt="t('sortableTable.alt.nextPageBtn')"
1843
+ <div style="height: 100%; align-content: center;">
1844
+ {{ filteredRows.length }} 条
1845
+ </div>
1846
+
1847
+ <button
1848
+ type="button"
1849
+ class="btn btn-sm role-multi-action page-btn-normal"
1850
+ :disabled="page == 1"
1851
+ :style="{ color: page <= totalPages ? `var(--default-text) !important` : `var(--paimary)`,border: page <= totalPages ? `solid thin var(--border)` : `solid thin var(--paimary)`}"
1852
+ @click="goToPage('prev')"
1853
+ >
1854
+ <!-- <i class="icon icon-chevron-left" /> -->
1855
+ <
1856
+ </button>
1857
+ <button
1858
+ type="button"
1859
+ class="btn btn-sm role-multi-action page-btn-normal"
1860
+ :style="{ color: (page == 1) ? `var(--primary)`:`var(--default-text) !important`,border: (page == 1) ? `solid thin var(--primary)` : `solid thin var(--border)`}"
1861
+ @click="goToPage('first')"
1862
+ >
1863
+ <!-- <i class="icon icon-chevron-beginning" /> -->
1864
+ {{ 1 }}
1865
+ </button>
1866
+ <template v-if="totalPages > 2">
1867
+ <div style="display: flex;flex-direction: row;gap: 10px;">
1868
+ <button
1869
+ v-if="page - 2 > 1 && page <= totalPages "
1870
+ type="button"
1871
+ class="btn btn-sm role-multi-action page-btn-normal"
1872
+ :style="{ color: `var(--default-text) !important`,border: `solid thin white`}"
1873
+ >
1874
+ ...
1875
+ </button>
1876
+ <button
1877
+ v-if="page - 1 > 1 && page <= totalPages "
1878
+ type="button"
1879
+ class="btn btn-sm role-multi-action page-btn-normal"
1880
+ :style="{ color: `var(--default-text) !important`,border: `solid thin var(--border)`}"
1881
+ @click="setPage(page-1)"
1882
+ >
1883
+ {{ page-1 }}
1884
+ </button>
1885
+ <button
1886
+ v-if="page > 1 && page < totalPages"
1887
+ type="button"
1888
+ class="btn btn-sm role-multi-action page-btn-normal"
1889
+ :style="{ color: `var(--default-text)`,border: `solid thin var(--primary)`}"
1890
+ @click="setPage(page)"
1891
+ >
1892
+ {{ page }}
1893
+ </button>
1894
+ <button
1895
+ v-if="page + 1 < totalPages "
1896
+ type="button"
1897
+ class="btn btn-sm role-multi-action page-btn-normal"
1898
+ :style="{ color: `var(--default-text) !important`,border: `solid thin var(--border)`}"
1899
+ @click="setPage(page+1)"
1900
+ >
1901
+ {{ page+1 }}
1902
+ </button>
1903
+ <button
1904
+ v-if="page +2 < totalPages "
1905
+ type="button"
1906
+ class="btn btn-sm role-multi-action page-btn-normal"
1907
+ :style="{ color: `var(--default-text) !important`,border: `solid thin white`}"
1908
+ >
1909
+ ...
1910
+ </button>
1911
+ </div>
1912
+ </template>
1913
+ <!-- <button
1914
+ type="button"
1915
+ class="btn btn-sm role-multi-action"
1916
+ style="padding: 0;max-width: 32px;background-color: white !important;"
1917
+ >
1918
+ {{ page }}
1919
+ </button> -->
1920
+ <button
1921
+ v-if="totalPages > 1"
1922
+ type="button"
1923
+ class="btn btn-sm role-multi-action page-btn-normal"
1924
+ :style="{ color: (page == totalPages) ? `var(--primary)`:`var(--default-text) !important`,border: (page == totalPages) ? `solid thin var(--primary)` : `solid thin var(--border)`}"
1925
+ @click="goToPage('last')"
1926
+ >
1927
+ <!-- <i class="icon icon-chevron-end" /> -->
1928
+ {{ totalPages }}
1929
+ </button>
1930
+ <button
1931
+ type="button"
1932
+ class="btn btn-sm role-multi-action page-btn-normal"
1933
+ :disabled="page == totalPages"
1934
+ :style="{ color: page <= totalPages ? `var(--default-text) !important` : `var(--paimary)`,border: page <= totalPages ? `solid thin var(--border)` : `solid thin var(--paimary)`}"
1935
+ @click="goToPage('next')"
1936
+ >
1937
+ <!-- <i class="icon icon-chevron-right" /> -->
1938
+ >
1939
+ </button>
1940
+
1941
+ <!-- 分页页码切换 -->
1942
+ <Select
1943
+ :mode="inputPerPage"
1944
+ :searchable="false"
1945
+ :clearable="false"
1946
+ :options="perPageOptions"
1947
+ v-model:value="inputPerPage"
1948
+ class="pageSelect"
1949
+ @update:value="changePerPage"
1633
1950
  />
1634
- </button>
1635
- <button
1951
+
1952
+ <div style="height: 100%; align-content: center;">
1953
+ 跳至
1954
+ </div>
1955
+ <input
1956
+ v-model="inputPage"
1957
+ type="number"
1958
+ min="1"
1959
+ step="1"
1960
+ style="padding: 0px 10px;"
1961
+ @keyup.enter="handleToPage"
1962
+ >
1963
+ <div style="height: 100%; align-content: center;">
1964
+
1965
+ </div>
1966
+ <!-- <button
1636
1967
  type="button"
1637
1968
  class="btn btn-sm role-multi-action"
1638
- data-testid="pagination-last"
1639
- :disabled="page == totalPages || loading"
1640
- role="button"
1641
- :aria-label="t('sortableTable.ariaLabel.lastPageBtn')"
1642
- @click="goToPage('last')"
1969
+ style="padding: 0;max-width: 80px;background-color: white !important;"
1970
+ @click="setPage(inputPage)"
1643
1971
  >
1644
- <i
1645
- class="icon icon-chevron-end"
1646
- :alt="t('sortableTable.alt.lastPageBtn')"
1647
- />
1648
- </button>
1972
+
1973
+ </button> -->
1974
+ </div>
1649
1975
  </div>
1650
1976
  <button
1651
1977
  v-if="search"
@@ -1829,9 +2155,12 @@ export default {
1829
2155
  }
1830
2156
 
1831
2157
  .search-box {
1832
- height: 40px;
1833
- margin-left: 10px;
1834
- min-width: 180px;
2158
+ height: 32px;
2159
+ margin-left: 0px;
2160
+ /* min-width: 180px; */
2161
+ min-width: 280px;
2162
+ width: 280px !important;
2163
+ border: 1px solid rgb(217, 217, 217);
1835
2164
  }
1836
2165
  </style>
1837
2166
 
@@ -1857,7 +2186,8 @@ export default {
1857
2186
  border-collapse: collapse;
1858
2187
  min-width: 400px;
1859
2188
  border-radius: 5px 5px 0 0;
1860
- outline: 1px solid var(--border);
2189
+ border-bottom: 1px solid var(--border) !important;
2190
+ /* outline: 1px solid var(--border); */
1861
2191
  background: var(--sortable-table-bg);
1862
2192
  border-radius: 4px;
1863
2193
 
@@ -1904,7 +2234,7 @@ export default {
1904
2234
  }
1905
2235
 
1906
2236
  &:hover, &.sub-row-hovered {
1907
- background-color: var(--sortable-table-hover-bg);
2237
+ /* background-color: var(--sortable-table-hover-bg); */
1908
2238
  }
1909
2239
 
1910
2240
  &.state-description > td {
@@ -1919,7 +2249,7 @@ export default {
1919
2249
  }
1920
2250
 
1921
2251
  tr.row-selected {
1922
- background: var(--sortable-table-selected-bg);
2252
+ /* background: var(--sortable-table-selected-bg); */
1923
2253
  }
1924
2254
 
1925
2255
  .no-rows {
@@ -1934,12 +2264,15 @@ export default {
1934
2264
  background-color: var(--body-bg);
1935
2265
  }
1936
2266
  }
2267
+ .no-results{
2268
+ height: 60px;
2269
+ }
1937
2270
 
1938
2271
  &.group {
1939
2272
  &:before {
1940
2273
  content: "";
1941
2274
  display: block;
1942
- height: 20px;
2275
+ height: 0px;
1943
2276
  background-color: transparent;
1944
2277
  }
1945
2278
  }
@@ -2037,12 +2370,12 @@ export default {
2037
2370
  align-items: center;
2038
2371
  }
2039
2372
  }
2040
- .fixed-header-actions.button{
2373
+ .fixed-footer-actions.button{
2041
2374
  grid-template-columns: [bulk] auto [middle] min-content [search] minmax(min-content, 350px);
2042
2375
  }
2043
2376
 
2044
- .fixed-header-actions {
2045
- padding: 0 0 20px 0;
2377
+ .fixed-footer-actions {
2378
+ /* padding: 0 0 20px 0; */
2046
2379
  width: 100%;
2047
2380
  z-index: z-index('fixedTableHeader');
2048
2381
  background: transparent;
@@ -2157,13 +2490,233 @@ export default {
2157
2490
  }
2158
2491
  }
2159
2492
 
2493
+
2494
+ .fixed-header-table-actions {
2495
+ width: 100%;
2496
+ z-index: z-index('fixedTableHeader');
2497
+ background: transparent;
2498
+ display: flex;
2499
+ justify-content: space-between;
2500
+
2501
+
2502
+ .bulk {
2503
+ $gap: 10px;
2504
+
2505
+ & > BUTTON {
2506
+ display: none; // Handled dynamically
2507
+ }
2508
+
2509
+ & > BUTTON:not(:last-of-type) {
2510
+ margin-right: $gap;
2511
+ }
2512
+
2513
+ .action-availability {
2514
+ display: none; // Handled dynamically
2515
+ margin-left: $gap;
2516
+ vertical-align: middle;
2517
+ margin-top: 2px;
2518
+ }
2519
+
2520
+ .dropdown-button {
2521
+ $disabled-color: var(--disabled-text);
2522
+ $disabled-cursor: not-allowed;
2523
+ li.disabled {
2524
+ color: $disabled-color;
2525
+ cursor: $disabled-cursor;
2526
+
2527
+ &:hover {
2528
+ color: $disabled-color;
2529
+ background-color: unset;
2530
+ cursor: $disabled-cursor;
2531
+ }
2532
+ }
2533
+ }
2534
+
2535
+ .bulk-action {
2536
+ .icon {
2537
+ vertical-align: -10%;
2538
+ }
2539
+ }
2540
+ }
2541
+
2542
+ .middle {
2543
+ white-space: nowrap;
2544
+
2545
+ .icon.icon-backup.animate {
2546
+ animation-name: spin;
2547
+ animation-duration: 1000ms;
2548
+ animation-iteration-count: infinite;
2549
+ animation-timing-function: linear;
2550
+ }
2551
+
2552
+ @keyframes spin {
2553
+ from {
2554
+ transform:rotate(0deg);
2555
+ }
2556
+ to {
2557
+ transform:rotate(360deg);
2558
+ }
2559
+ }
2560
+ }
2561
+
2562
+ .search {
2563
+ text-align: right;
2564
+ justify-content: flex-end;
2565
+ }
2566
+
2567
+ .bulk-actions-dropdown {
2568
+ display: none; // Handled dynamically
2569
+
2570
+ .dropdown-button {
2571
+ background-color: var(--primary);
2572
+
2573
+ &:hover {
2574
+ background-color: var(--primary-hover-bg);
2575
+ color: var(--primary-hover-text);
2576
+ }
2577
+
2578
+ > *, .icon-chevron-down {
2579
+ color: var(--primary-text);
2580
+ }
2581
+
2582
+ .button-divider {
2583
+ border-color: var(--primary-text);
2584
+ }
2585
+
2586
+ &.disabled {
2587
+ border-color: var(--disabled-bg);
2588
+
2589
+ .icon-chevron-down {
2590
+ color: var(--disabled-text) !important;
2591
+ }
2592
+
2593
+ .button-divider {
2594
+ border-color: var(--disabled-text);
2595
+ }
2596
+ }
2597
+ }
2598
+ }
2599
+ }
2600
+
2160
2601
  .paging {
2161
- margin-top: 10px;
2602
+ //text-align: center;
2603
+ display: flex;
2604
+ justify-content: flex-end;
2605
+ gap: 0 10px;
2162
2606
  text-align: center;
2163
-
2607
+ max-height: 32px;
2608
+ background-color: transparent;
2609
+ flex: 1;
2164
2610
  SPAN {
2165
2611
  display: inline-block;
2166
- min-width: 200px;
2612
+ //min-width: 200px;
2613
+ min-width: auto;
2614
+ }
2615
+
2616
+ /* 针对Webkit浏览器(如Chrome, Safari) */
2617
+ input[type="number"]::-webkit-inner-spin-button,
2618
+ input[type="number"]::-webkit-outer-spin-button {
2619
+ -webkit-appearance: none;
2620
+ margin: 0;
2621
+ }
2622
+
2623
+ /* 针对Firefox */
2624
+ input[type="number"] {
2625
+ -moz-appearance: textfield;
2626
+ // background-color: var(--disabled-bg) !important;
2627
+ border: 1px var(--border) solid;
2628
+ border-radius: 2px;
2629
+ width: 50px;
2630
+ height: 100%;
2167
2631
  }
2168
2632
  }
2633
+
2169
2634
  </style>
2635
+ <style scoped lang="scss">
2636
+ :deep() .role-link{
2637
+ min-width: unset !important;
2638
+ width: 38px;
2639
+ min-height: 20px !important;
2640
+ height: 20px !important;
2641
+ line-height: 20px !important;
2642
+ &:hover{
2643
+ background-color: unset !important;
2644
+ }
2645
+ }
2646
+ :deep() .checkbox-outer-container-extra{
2647
+ margin-top: 0px !important;
2648
+ }
2649
+ .pageSelect {
2650
+ overflow: hidden;
2651
+ max-width: 100px;
2652
+ }
2653
+ .page-btn-normal {
2654
+ padding: 0;
2655
+ max-width: 32px;
2656
+ background-color:white !important;
2657
+ }
2658
+
2659
+ .pageSelect{
2660
+ &:deep() .vs__actions:after{
2661
+ padding-top: 10px;
2662
+ }
2663
+ }
2664
+ .sort-table-div{
2665
+ width:100%;
2666
+ white-space:nowrap;
2667
+ // overflow-x: auto;
2668
+ }
2669
+
2670
+ /* 滚动阴影左边 */
2671
+ .shadow-left td:nth-child(2)::after{
2672
+ content: "";
2673
+ position: absolute;
2674
+ top: 0;
2675
+ width: 10px;
2676
+ height: 100%;
2677
+ right: -10px;
2678
+ background: linear-gradient(to right, rgba(5, 5, 5, 0.06), transparent);
2679
+ }
2680
+ .shadow-left{
2681
+ &:deep() th:nth-child(2)::after{
2682
+ content: "";
2683
+ position: absolute;
2684
+ top: 0;
2685
+ width: 10px;
2686
+ height: 100%;
2687
+ right: -10px;
2688
+ background: linear-gradient(to right, rgba(5, 5, 5, 0.06), transparent);
2689
+ }
2690
+ }
2691
+
2692
+ /* 滚动阴影右边 */
2693
+ .shadow-right td:nth-last-child(1)::after{
2694
+ content: "";
2695
+ position: absolute;
2696
+ top: 0;
2697
+ width: 10px;
2698
+ height: 100%;
2699
+ left: -10px;
2700
+ background: linear-gradient(to left, rgba(5, 5, 5, 0.06), transparent);
2701
+ }
2702
+
2703
+ .shadow-right{
2704
+ &:deep() th:nth-last-child(1)::after {
2705
+ content: "";
2706
+ position: absolute;
2707
+ top: 0;
2708
+ width: 10px;
2709
+ height: 100%;
2710
+ left: -10px;
2711
+ background: linear-gradient(to left, rgba(5, 5, 5, 0.06), transparent);
2712
+ }
2713
+ }
2714
+
2715
+ /* 滚动阴影垂直修正 */
2716
+ .shadow-y td:nth-child(-n + 2), /* 前两列 */
2717
+ .shadow-y td:nth-last-child(1) /* 后一列 */
2718
+ {
2719
+ z-index: 3;
2720
+ }
2721
+ </style>
2722
+