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

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 (353) hide show
  1. package/assets/brand/csp/favicon.png +0 -0
  2. package/assets/brand/harvester/favicon.png +0 -0
  3. package/assets/brand/suse/favicon.png +0 -0
  4. package/assets/icons/demo.css +539 -0
  5. package/assets/icons/demo.css:Zone.Identifier +0 -0
  6. package/assets/icons/demo_index.html +1131 -0
  7. package/assets/icons/demo_index.html:Zone.Identifier +0 -0
  8. package/assets/icons/iconfont.css +219 -0
  9. package/assets/icons/iconfont.css:Zone.Identifier +0 -0
  10. package/assets/icons/iconfont.js +1 -0
  11. package/assets/icons/iconfont.js:Zone.Identifier +0 -0
  12. package/assets/icons/iconfont.json +324 -0
  13. package/assets/icons/iconfont.json:Zone.Identifier +0 -0
  14. package/assets/icons/iconfont.ttf +0 -0
  15. package/assets/icons/iconfont.ttf:Zone.Identifier +0 -0
  16. package/assets/icons/iconfont.woff +0 -0
  17. package/assets/icons/iconfont.woff2 +0 -0
  18. package/assets/icons/iconfont.woff2:Zone.Identifier +0 -0
  19. package/assets/icons/iconfont.woff:Zone.Identifier +0 -0
  20. package/assets/iconsNew/demo.css +539 -0
  21. package/assets/iconsNew/demo.css:Zone.Identifier +0 -0
  22. package/assets/iconsNew/demo_index.html +303 -0
  23. package/assets/iconsNew/demo_index.html:Zone.Identifier +0 -0
  24. package/assets/iconsNew/iconfont.css +43 -0
  25. package/assets/iconsNew/iconfont.css:Zone.Identifier +0 -0
  26. package/assets/iconsNew/iconfont.js +1 -0
  27. package/assets/iconsNew/iconfont.js:Zone.Identifier +0 -0
  28. package/assets/iconsNew/iconfont.json +44 -0
  29. package/assets/iconsNew/iconfont.json:Zone.Identifier +0 -0
  30. package/assets/iconsNew/iconfont.ttf +0 -0
  31. package/assets/iconsNew/iconfont.ttf:Zone.Identifier +0 -0
  32. package/assets/iconsNew/iconfont.woff +0 -0
  33. package/assets/iconsNew/iconfont.woff2 +0 -0
  34. package/assets/iconsNew/iconfont.woff2:Zone.Identifier +0 -0
  35. package/assets/iconsNew/iconfont.woff:Zone.Identifier +0 -0
  36. package/assets/images/API.svg +3 -0
  37. package/assets/images/action.svg +6 -0
  38. package/assets/images/login/password.svg +20 -0
  39. package/assets/images/login/user.svg +6 -0
  40. package/assets/images/login-bg.png +0 -0
  41. package/assets/images/login-left.png +0 -0
  42. package/assets/images/login-logo.svg +44 -0
  43. package/assets/images/logo.png +0 -0
  44. package/assets/images/logo.svg +47 -0
  45. package/assets/images/pl/dark/logo.png +0 -0
  46. package/assets/images/pl/half-logo.svg +2 -23
  47. package/assets/images/pl/harvester.png +0 -0
  48. package/assets/images/pl/logo.png +0 -0
  49. package/assets/images/promp-yellow.svg +5 -0
  50. package/assets/images/user.png +0 -0
  51. package/assets/styles/all.scss +83 -0
  52. package/assets/styles/app.scss +5 -0
  53. package/assets/styles/base/_basic.scss +2 -2
  54. package/assets/styles/base/_helpers.scss +1 -1
  55. package/assets/styles/base/_mixins.scss +1 -1
  56. package/assets/styles/base/_typography.scss +2 -1
  57. package/assets/styles/base/_variables.scss +14 -7
  58. package/assets/styles/fonts/_icons.scss +3 -2
  59. package/assets/styles/global/_button.scss +44 -26
  60. package/assets/styles/global/_columns.scss +3 -1
  61. package/assets/styles/global/_form.scss +46 -13
  62. package/assets/styles/global/_labeled-input.scss +54 -26
  63. package/assets/styles/global/_layout.scss +8 -3
  64. package/assets/styles/global/_select.scss +25 -17
  65. package/assets/styles/global/_table.scss +7 -1
  66. package/assets/styles/global/_tooltip.scss +60 -8
  67. package/assets/styles/themes/_dark.scss +3 -0
  68. package/assets/styles/themes/_light.scss +69 -46
  69. package/assets/styles/vendor/vue-select.scss +24 -10
  70. package/assets/translations/en-us.yaml +92 -4
  71. package/assets/translations/zh-hans.yaml +668 -206
  72. package/components/ActionDropdown.vue +2 -1
  73. package/components/ActionMenu.vue +2 -2
  74. package/components/ActionMenuShell.vue +2 -0
  75. package/components/AppModal.vue +46 -5
  76. package/components/BrandImage.vue +1 -0
  77. package/components/ButtonDropdown.vue +28 -4
  78. package/components/ButtonMultiAction.vue +1 -0
  79. package/components/ClusterIconMenu.vue +2 -2
  80. package/components/CodeMirror.vue +26 -10
  81. package/components/ConsumptionGauge.vue +24 -5
  82. package/components/ContainerResourceLimit.vue +2 -2
  83. package/components/CopyToClipboard.vue +15 -0
  84. package/components/CruResource.vue +12 -10
  85. package/components/CruResourceFooter.vue +2 -2
  86. package/components/DashboardOptions.vue +29 -17
  87. package/components/DotState.vue +84 -0
  88. package/components/Drawer/Chrome.vue +2 -2
  89. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +30 -27
  90. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +1 -1
  91. package/components/Drawer/ResourceDetailDrawer/index.vue +5 -4
  92. package/components/ExplorerMembers.vue +28 -4
  93. package/components/ExplorerProjectsNamespaces.vue +19 -5
  94. package/components/GlobalRoleBindings.vue +23 -4
  95. package/components/GrafanaDashboard.vue +4 -4
  96. package/components/GrowlManager.vue +3 -1
  97. package/components/HardwareResourceGauge.vue +39 -3
  98. package/components/IndentedPanel.vue +4 -10
  99. package/components/InfoBox.vue +3 -3
  100. package/components/InputOrDisplay.vue +28 -2
  101. package/components/LabelValue.vue +20 -1
  102. package/components/ModalWithCard.vue +12 -3
  103. package/components/PodSecurityAdmission.vue +2 -2
  104. package/components/PromptModal.vue +1 -1
  105. package/components/PromptRemove.vue +53 -12
  106. package/components/RelatedResources.vue +3 -0
  107. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +1 -3
  108. package/components/Resource/Detail/Metadata/KeyValue.vue +8 -4
  109. package/components/Resource/Detail/Metadata/index.vue +3 -1
  110. package/components/Resource/Detail/TitleBar/Title.vue +4 -3
  111. package/components/Resource/Detail/TitleBar/Top.vue +2 -0
  112. package/components/Resource/Detail/TitleBar/composables.ts +16 -1
  113. package/components/Resource/Detail/TitleBar/index.vue +125 -27
  114. package/components/ResourceDetail/Masthead/index.vue +1 -1
  115. package/components/ResourceDetail/Masthead/latest.vue +1 -1
  116. package/components/ResourceDetail/Masthead/legacy.vue +183 -39
  117. package/components/ResourceDetail/legacy.vue +47 -29
  118. package/components/ResourceList/Masthead.vue +222 -54
  119. package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
  120. package/components/ResourceTable.vue +40 -2
  121. package/components/SideNav.vue +74 -20
  122. package/components/SingleClusterInfo.vue +2 -1
  123. package/components/SortableTable/THead.vue +79 -4
  124. package/components/SortableTable/index.vue +1053 -464
  125. package/components/SortableTable/paging.js +26 -16
  126. package/components/SortableTable/selection.js +2 -2
  127. package/components/Tabbed/Tab.vue +3 -3
  128. package/components/Tabbed/index.vue +53 -30
  129. package/components/YamlEditor.vue +0 -1
  130. package/components/auth/Principal.vue +51 -19
  131. package/components/auth/RoleDetailEdit.vue +69 -14
  132. package/components/auth/SelectPrincipal.vue +1 -0
  133. package/components/breadcrumb/index.vue +119 -0
  134. package/components/form/ArrayList.vue +177 -152
  135. package/components/form/ArrayListGrouped.vue +13 -3
  136. package/components/form/ArrayListSelect.vue +1 -1
  137. package/components/form/BannerSettings.vue +64 -59
  138. package/components/form/ChangePassword.vue +5 -5
  139. package/components/form/ClusterAppearance.vue +4 -3
  140. package/components/form/ColorInput.vue +32 -8
  141. package/components/form/Command.vue +4 -5
  142. package/components/form/Conditions.vue +15 -1
  143. package/components/form/Footer.vue +12 -8
  144. package/components/form/HealthCheck.vue +0 -2
  145. package/components/form/HookOption.vue +87 -58
  146. package/components/form/InputWithSelect.vue +8 -4
  147. package/components/form/KeyValue.vue +66 -8
  148. package/components/form/LabeledSelect.vue +216 -242
  149. package/components/form/Labels.vue +4 -4
  150. package/components/form/MatchExpressions.vue +28 -11
  151. package/components/form/Members/ClusterMembershipEditor.vue +1 -1
  152. package/components/form/Members/ClusterPermissionsEditor.vue +61 -43
  153. package/components/form/Members/MembershipEditor.vue +4 -4
  154. package/components/form/Members/ProjectMembershipEditor.vue +1 -1
  155. package/components/form/NameNsDescription.vue +62 -22
  156. package/components/form/Networking.vue +6 -9
  157. package/components/form/NodeAffinity.vue +29 -28
  158. package/components/form/Password.vue +16 -7
  159. package/components/form/PodAffinity.vue +24 -25
  160. package/components/form/Probe.vue +15 -11
  161. package/components/form/ProjectMemberEditor.vue +66 -48
  162. package/components/form/ResourceQuota/Namespace.vue +4 -4
  163. package/components/form/ResourceQuota/NamespaceRow.vue +26 -23
  164. package/components/form/ResourceQuota/Project.vue +4 -4
  165. package/components/form/ResourceQuota/ProjectRow.vue +38 -35
  166. package/components/form/ResourceSelector.vue +1 -1
  167. package/components/form/SecretSelector.vue +24 -23
  168. package/components/form/Security.vue +1 -3
  169. package/components/form/Select.vue +12 -3
  170. package/components/form/ServiceNameSelect.vue +2 -5
  171. package/components/form/ServicePorts.vue +149 -75
  172. package/components/form/SimpleSecretSelector.vue +29 -9
  173. package/components/form/Taints.vue +2 -1
  174. package/components/form/Tolerations.vue +13 -9
  175. package/components/form/UnitInput.vue +8 -3
  176. package/components/form/ValueFromResource.vue +110 -96
  177. package/components/form/WorkloadPorts.vue +143 -123
  178. package/components/formatter/BadgeStateFormatter.vue +8 -5
  179. package/components/formatter/LiveDate.vue +3 -3
  180. package/components/formatter/WorkloadHealthScale.vue +4 -3
  181. package/components/nav/Favorite.vue +5 -1
  182. package/components/nav/Group.vue +139 -99
  183. package/components/nav/Header.vue +138 -164
  184. package/components/nav/HeaderPageActionMenu.vue +1 -0
  185. package/components/nav/NamespaceFilter.vue +34 -36
  186. package/components/nav/TopLevelMenu.vue +62 -25
  187. package/components/nav/Type.vue +73 -43
  188. package/composables/useClickOutside.ts +1 -1
  189. package/config/menuRouteMap.js +10 -0
  190. package/config/private-label.js +14 -11
  191. package/config/product/auth.js +17 -7
  192. package/config/product/explorer.js +32 -10
  193. package/config/product/manager.js +28 -17
  194. package/config/product/settings.js +19 -9
  195. package/config/product/uiplugins.js +13 -10
  196. package/config/router/navigation-guards/index.js +61 -3
  197. package/config/settings.ts +28 -0
  198. package/config/table-headers.js +3 -2
  199. package/detail/node.vue +28 -23
  200. package/dialog/AddCustomBadgeDialog.vue +17 -9
  201. package/dialog/ForceMachineRemoveDialog.vue +2 -2
  202. package/dialog/RollbackWorkloadDialog.vue +1 -1
  203. package/dialog/ScalePoolDownDialog.vue +2 -2
  204. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +1 -1
  205. package/edit/autoscaling.horizontalpodautoscaler/hpa-scaling-rule.vue +9 -6
  206. package/edit/autoscaling.horizontalpodautoscaler/index.vue +3 -1
  207. package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +2 -2
  208. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +7 -5
  209. package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +5 -3
  210. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +2 -2
  211. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  212. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +1 -1
  213. package/edit/autoscaling.horizontalpodautoscaler/resource-metric.vue +2 -2
  214. package/edit/configmap.vue +4 -0
  215. package/edit/logging-flow/index.vue +1 -2
  216. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +3 -3
  217. package/edit/logging.banzaicloud.io.output/providers/azurestorage.vue +19 -19
  218. package/edit/logging.banzaicloud.io.output/providers/cloudwatch.vue +23 -23
  219. package/edit/logging.banzaicloud.io.output/providers/datadog.vue +19 -19
  220. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +14 -14
  221. package/edit/logging.banzaicloud.io.output/providers/forward.vue +12 -12
  222. package/edit/logging.banzaicloud.io.output/providers/gcs.vue +23 -23
  223. package/edit/logging.banzaicloud.io.output/providers/gelf.vue +6 -6
  224. package/edit/logging.banzaicloud.io.output/providers/kafka.vue +10 -10
  225. package/edit/logging.banzaicloud.io.output/providers/kinesisStream.vue +8 -8
  226. package/edit/logging.banzaicloud.io.output/providers/logdna.vue +17 -17
  227. package/edit/logging.banzaicloud.io.output/providers/logz.vue +7 -7
  228. package/edit/logging.banzaicloud.io.output/providers/loki.vue +12 -12
  229. package/edit/logging.banzaicloud.io.output/providers/newrelic.vue +3 -3
  230. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +14 -14
  231. package/edit/logging.banzaicloud.io.output/providers/redis.vue +6 -6
  232. package/edit/logging.banzaicloud.io.output/providers/s3.vue +23 -23
  233. package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +13 -13
  234. package/edit/logging.banzaicloud.io.output/providers/sumologic.vue +2 -2
  235. package/edit/logging.banzaicloud.io.output/providers/syslog.vue +54 -54
  236. package/edit/management.cattle.io.user.vue +17 -4
  237. package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +19 -19
  238. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +50 -26
  239. package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +36 -12
  240. package/edit/monitoring.coreos.com.alertmanagerconfig/types/dingding.vue +32 -0
  241. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +6 -6
  242. package/edit/monitoring.coreos.com.alertmanagerconfig/types/message.vue +52 -0
  243. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +10 -10
  244. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +4 -4
  245. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +4 -4
  246. package/edit/monitoring.coreos.com.alertmanagerconfig/types/snmp.vue +45 -0
  247. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +1 -1
  248. package/edit/monitoring.coreos.com.alertmanagerconfig/types/work.vue +31 -0
  249. package/edit/monitoring.coreos.com.receiver/types/email.vue +6 -6
  250. package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +10 -10
  251. package/edit/monitoring.coreos.com.receiver/types/pagerduty.vue +5 -5
  252. package/edit/monitoring.coreos.com.receiver/types/slack.vue +4 -4
  253. package/edit/namespace.vue +1 -2
  254. package/edit/networking.k8s.io.ingress/Certificate.vue +14 -5
  255. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  256. package/edit/networking.k8s.io.ingress/Rule.vue +5 -11
  257. package/edit/networking.k8s.io.ingress/RulePath.vue +105 -96
  258. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +3 -3
  259. package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +4 -2
  260. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -11
  261. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  262. package/edit/persistentvolume/index.vue +3 -1
  263. package/edit/persistentvolumeclaim.vue +2 -0
  264. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -1
  265. package/edit/secret/index.vue +2 -2
  266. package/edit/service.vue +4 -1
  267. package/edit/storage.k8s.io.storageclass/index.vue +10 -8
  268. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +34 -27
  269. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +15 -13
  270. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +41 -39
  271. package/edit/token.vue +31 -12
  272. package/edit/workload/Job.vue +31 -34
  273. package/edit/workload/Upgrading.vue +5 -5
  274. package/edit/workload/index.vue +22 -18
  275. package/edit/workload/storage/Mount.vue +1 -0
  276. package/edit/workload/storage/awsElasticBlockStore.vue +9 -7
  277. package/edit/workload/storage/azureDisk.vue +14 -10
  278. package/edit/workload/storage/azureFile.vue +9 -7
  279. package/edit/workload/storage/csi/index.vue +6 -9
  280. package/edit/workload/storage/emptyDir.vue +7 -5
  281. package/edit/workload/storage/gcePersistentDisk.vue +9 -7
  282. package/edit/workload/storage/hostPath.vue +7 -5
  283. package/edit/workload/storage/nfs.vue +8 -6
  284. package/edit/workload/storage/persistentVolumeClaim/index.vue +12 -10
  285. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +20 -15
  286. package/edit/workload/storage/secret.vue +9 -6
  287. package/edit/workload/storage/vsphereVolume.vue +11 -7
  288. package/initialize/app-extended.js +7 -1
  289. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +8 -6
  290. package/list/management.cattle.io.setting.vue +22 -13
  291. package/list/management.cattle.io.user.vue +7 -3
  292. package/list/namespace.vue +3 -0
  293. package/list/provisioning.cattle.io.cluster.vue +6 -7
  294. package/mixins/brand.js +17 -0
  295. package/mixins/create-edit-view/impl.js +10 -0
  296. package/models/provisioning.cattle.io.cluster.js +19 -18
  297. package/models/workload.js +2 -2
  298. package/package.json +1 -1
  299. package/pages/account/index.vue +93 -58
  300. package/pages/account/pri.vue +229 -0
  301. package/pages/auth/login.vue +216 -51
  302. package/pages/auth/setup.vue +175 -33
  303. package/pages/c/_cluster/_product/namespaces.vue +5 -5
  304. package/pages/c/_cluster/auth/roles/index.vue +83 -8
  305. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -1
  306. package/pages/c/_cluster/explorer/index.vue +2 -1
  307. package/pages/c/_cluster/explorer/tools/index.vue +6 -6
  308. package/pages/c/_cluster/monitoring/monitor/index.vue +2 -2
  309. package/pages/c/_cluster/settings/banners.vue +174 -102
  310. package/pages/c/_cluster/settings/brand.vue +350 -302
  311. package/pages/c/_cluster/settings/performance.vue +61 -38
  312. package/pages/home.vue +119 -37
  313. package/pages/prefs.vue +27 -25
  314. package/pkg/tsconfig.json +9 -9
  315. package/pkg/vue.config.js +1 -1
  316. package/plugins/dashboard-store/actions.js +1 -1
  317. package/plugins/dashboard-store/resource-class.js +28 -27
  318. package/promptRemove/mixin/roleDeletionCheck.js +2 -2
  319. package/public/index.html +4 -4
  320. package/rancher-components/BadgeState/BadgeState.vue +38 -55
  321. package/rancher-components/Banner/Banner.vue +25 -9
  322. package/rancher-components/Card/Card.vue +7 -8
  323. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -0
  324. package/rancher-components/Form/LabeledInput/LabeledInput.vue +42 -3
  325. package/rancher-components/Form/Radio/RadioButton.vue +35 -11
  326. package/rancher-components/Form/Radio/RadioGroup.vue +22 -6
  327. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +3 -3
  328. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -0
  329. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +41 -4
  330. package/rancher-components/RcDropdown/RcDropdown.vue +35 -7
  331. package/rancher-components/RcDropdown/RcDropdownItem.vue +2 -2
  332. package/rancher-components/RcDropdown/RcDropdownMenu.vue +12 -6
  333. package/rancher-components/RcDropdown/types.ts +1 -0
  334. package/rancher-components/StringList/StringList.vue +1 -1
  335. package/scripts/build-pkg.sh +18 -23
  336. package/scripts/publish-shell.sh +1 -1
  337. package/static/favicon.ico +0 -0
  338. package/static/favicon.png +0 -0
  339. package/static/loading-indicator.html +3 -3
  340. package/store/i18n.js +6 -2
  341. package/store/modal.ts +3 -3
  342. package/store/prefs.js +11 -4
  343. package/store/type-map.js +30 -2
  344. package/types/shell/index.d.ts +86 -97
  345. package/utils/error.js +109 -8
  346. package/utils/errorTranslate.json +1740 -0
  347. package/utils/errorTranslateNew.json +39 -0
  348. package/utils/roleFiltering.js +33 -0
  349. package/utils/router.js +21 -0
  350. package/utils/select.js +26 -3
  351. package/utils/string.js +8 -5
  352. package/utils/title.ts +1 -1
  353. package/vue.config.js +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,
@@ -577,6 +654,14 @@ export default {
577
654
  namespaces() {
578
655
  return this.$store.getters['activeNamespaceCache'];
579
656
  },
657
+
658
+ // 正确的总数显示
659
+ totalCount() {
660
+ if (this.externalPaginationEnabled && this.externalPaginationResult) {
661
+ return this.externalPaginationResult.total || this.externalPaginationResult.count || 0;
662
+ }
663
+ return this.rows ? this.rows.length : 0;
664
+ },
580
665
 
581
666
  initalLoad() {
582
667
  return !!(!this.isLoading && !this._didinit && this.rows?.length);
@@ -788,11 +873,123 @@ export default {
788
873
  },
789
874
 
790
875
  methods: {
876
+ // getTableList () {
877
+ // const q = this.eventualSearchQuery;
878
+
879
+ // this.searchQuery = q;
880
+
881
+ // if (!this.hasAdvancedFiltering && this.useQueryParamsForSimpleFiltering) {
882
+ // const route = {
883
+ // name: this.$route.name,
884
+ // params: { ...this.$route.params },
885
+ // query: { ...this.$route.query, q }
886
+ // };
887
+
888
+ // if (!q && this.$route.query?.q) {
889
+ // route.query = {};
890
+ // }
891
+
892
+ // this.$router.replace(route);
893
+ // }
894
+ // },
895
+ // 设置当前页码
896
+ setPage(pageNum) {
897
+ if (pageNum >= 1 && pageNum <= this.totalPages) {
898
+ this.page = pageNum;
899
+ this.inputPage = ''; // 清空输入框
900
+ this.debouncedPaginationChanged();
901
+ }
902
+ },
903
+ onTableScroll(table, e) {
904
+ // 记录最后滚动的距离
905
+ let lastScrollTop = 0;
906
+ let lastScrollLeft = 0;
907
+
908
+ // 监听容器滚动
909
+ table.addEventListener('scroll', (e) => {
910
+ // 如果当前垂直滚动距离不等于上次
911
+ if (e.target.scrollTop !== lastScrollTop) {
912
+ // 更新最后距离
913
+ lastScrollTop = e.target.scrollTop;
914
+
915
+ // 移除左右阴影样式
916
+ table.classList.remove('shadow-left');
917
+ table.classList.remove('shadow-right');
918
+
919
+ // 如果滚动到顶部,移除顶部阴影样式
920
+ // if (lastScrollTop === 0) {
921
+ // table.classList.remove('shadow-top');
922
+ // }
923
+ // // 否则添加顶部阴影样式
924
+ // else {
925
+ // table.classList.add('shadow-top');
926
+ // }
927
+
928
+ // 如果滚动到底部,移除底部阴影样式
929
+ // if (lastScrollTop + table.clientHeight === table.scrollHeight) {
930
+ // table.classList.remove('shadow-bottom');
931
+ // }
932
+ // // 否则添加底部阴影样式
933
+ // else {
934
+ // table.classList.add('shadow-bottom');
935
+ // }
936
+
937
+ // 阴影效果修正
938
+ table.classList.remove('shadow-x');
939
+ table.classList.add('shadow-y');
940
+ }
941
+
942
+ // 如果当前水平滚动距离不等于上次
943
+ else if (e.target.scrollLeft !== lastScrollLeft) {
944
+ // 更新最后距离
945
+ lastScrollLeft = e.target.scrollLeft;
946
+
947
+ // 移除上下阴影样式
948
+ // table.classList.remove('shadow-top');
949
+ // table.classList.remove('shadow-bottom');
950
+
951
+ // 如果滚动到左边,移除左边阴影样式
952
+ if (lastScrollLeft === 0) {
953
+ table.classList.remove('shadow-left');
954
+ }
955
+ // 否则添加左边阴影样式
956
+ else {
957
+ table.classList.add('shadow-left');
958
+ }
959
+
960
+ // 如果滚动到右边,移除右边阴影样式
961
+ if (lastScrollLeft + table.clientWidth === table.scrollWidth) {
962
+ table.classList.remove('shadow-right');
963
+ }
964
+ // 否则添加右边阴影样式
965
+ else {
966
+ table.classList.add('shadow-right');
967
+ }
968
+
969
+ // 阴影效果修正
970
+ table.classList.remove('shadow-y');
971
+ table.classList.add('shadow-x');
972
+ }
973
+ });
974
+ },
975
+ changePerPage(value) {
976
+ this.inputPerPage = value;
977
+ this.setgetPerPage(value);
978
+ },
979
+ handleToPage() {
980
+ this.setPage(parseInt(this.inputPage, 10));
981
+ },
791
982
  refreshTableData() {
792
983
  this.$store.dispatch('resource-fetch/doManualRefresh');
793
984
  },
794
985
  get,
795
986
  dasherize,
987
+ muchSelect(value) {
988
+ console.log(value);
989
+
990
+ this.isMuchSelected = !this.isMuchSelected;
991
+ this.onToggleAll(value);
992
+ },
796
993
 
797
994
  onScroll() {
798
995
  if (this.hasLiveColumns || this.hasDelayedColumns) {
@@ -893,12 +1090,22 @@ export default {
893
1090
  if ( col.labelKey ) {
894
1091
  return this.t(col.labelKey, undefined, true);
895
1092
  } else if ( col.label ) {
896
- return col.label;
1093
+ // 判断 label 是否为中文
1094
+ if (this.isChinese(col.label)) {
1095
+ return col.label;
1096
+ } else {
1097
+ return this.t(`tableHeaders.${col.label.replace(/\s+/g, '').toLowerCase()}`, undefined, true);
1098
+ }
897
1099
  }
898
1100
 
899
1101
  return ucFirst(col.name);
900
1102
  },
901
1103
 
1104
+ // 判断字符串是否包含中文
1105
+ isChinese(str) {
1106
+ return /[\u4e00-\u9fa5]/.test(str);
1107
+ },
1108
+
902
1109
  valueFor(row, col, isLabel) {
903
1110
  if (typeof col.value === 'function') {
904
1111
  return col.value(row);
@@ -1076,120 +1283,32 @@ export default {
1076
1283
  ref="container"
1077
1284
  :data-testid="componentTestid + '-list-container'"
1078
1285
  >
1286
+ <!-- 主标题和过滤器区域 -->
1079
1287
  <div
1080
- :class="{'titled': $slots.title && $slots.title.length}"
1288
+ :class="{'titled': $slots.title && $slots.title.length, 'mb-40': isFilterLabel }"
1081
1289
  class="sortable-table-header"
1082
1290
  >
1083
1291
  <slot name="title" />
1292
+
1293
+ <!-- 顶部功能行区域 -->
1084
1294
  <div
1085
1295
  v-if="showHeaderRow"
1086
- class="fixed-header-actions"
1087
- :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering}"
1296
+ class="fixed-header-table-actions mb-20"
1297
+ :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering, }"
1298
+ style="display: flex;"
1088
1299
  >
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
1300
 
1301
+ <!-- 搜索栏、右插槽、刷新按钮、高级筛选等区域 -->
1188
1302
  <div
1189
1303
  v-if="search || hasAdvancedFiltering || isTooManyItemsToAutoUpdate || $slots['header-right']"
1190
1304
  class="search row"
1191
1305
  data-testid="search-box-filter-row"
1306
+ style="max-height: 32px;"
1192
1307
  >
1308
+
1309
+ <slot name="search-main-button" />
1310
+
1311
+ <!-- 已应用的高级筛选 -->
1193
1312
  <ul
1194
1313
  v-if="hasAdvancedFiltering"
1195
1314
  class="advanced-filters-applied"
@@ -1206,15 +1325,9 @@ export default {
1206
1325
  <div class="bg" />
1207
1326
  </li>
1208
1327
  </ul>
1209
- <slot name="watch-controls" />
1328
+
1210
1329
  <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
- />
1330
+
1218
1331
  <div
1219
1332
  v-if="hasAdvancedFiltering"
1220
1333
  ref="advanced-filter-group"
@@ -1270,6 +1383,8 @@ export default {
1270
1383
  </div>
1271
1384
  </div>
1272
1385
  </div>
1386
+
1387
+ <!-- 搜索描述文本(隐藏) -->
1273
1388
  <p
1274
1389
  v-else-if="search"
1275
1390
  id="describe-filter-sortable-table"
@@ -1277,375 +1392,615 @@ export default {
1277
1392
  >
1278
1393
  {{ t('sortableTable.filteringDescription') }}
1279
1394
  </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
1395
  <slot name="header-button" />
1396
+
1397
+ <div style="display: flex;">
1398
+ <!-- 搜索输入框 -->
1399
+ <input
1400
+ v-if="search"
1401
+ ref="searchQuery"
1402
+ v-model="eventualSearchQuery"
1403
+ type="search"
1404
+ class="input-sm search-box"
1405
+ :aria-label="t('sortableTable.searchLabel')"
1406
+ aria-describedby="describe-filter-sortable-table"
1407
+ :placeholder="t('sortableTable.search')+searchPlaceholder"
1408
+ >
1409
+ <!-- <button v-if="search" @click="getTableList(eventualSearchQuery)" calss="search-btn role-secondary">
1410
+ 检索
1411
+ </button> -->
1412
+
1413
+ <!-- 手动刷新按钮 -->
1414
+ <AsyncButton
1415
+ v-if="isTooManyItemsToAutoUpdate"
1416
+ mode="manual-refresh"
1417
+ :size="manualRefreshButtonSize"
1418
+ :current-phase="refreshButtonPhase"
1419
+ @click="debouncedRefreshTableData"
1420
+ />
1421
+
1422
+ </div>
1423
+
1291
1424
  </div>
1425
+
1426
+ <div style="display: flex;">
1427
+ <slot name="header-button-left" />
1428
+
1429
+ <!-- 中间区域插槽 -->
1430
+ <div
1431
+ v-if="!hasAdvancedFiltering && $slots['header-middle']"
1432
+ class="middle"
1433
+ style="margin-left: 10px;"
1434
+ >
1435
+ <slot name="header-middle" />
1436
+ </div>
1437
+ </div>
1292
1438
  </div>
1293
1439
  </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
1440
 
1328
- <!-- Don't display anything if we're loading and the delay has yet to pass -->
1329
- <div v-if="isLoading && !loadingDelay" />
1441
+ <div v-if="$slots['banner']">
1442
+ <slot name="banner"></slot>
1443
+ </div>
1444
+
1445
+ <div class="sort-table-div">
1446
+ <table
1447
+ ref="table"
1448
+ class="sortable-table"
1449
+ :class="classObject"
1450
+ width="100%"
1451
+ role="table"
1452
+ >
1453
+ <THead
1454
+ v-if="showHeaders"
1455
+ :label-for="labelFor"
1456
+ :columns="columns"
1457
+ :group="group"
1458
+ :group-options="advGroupOptions"
1459
+ :has-advanced-filtering="hasAdvancedFiltering"
1460
+ :adv-filter-hide-labels-as-cols="advFilterHideLabelsAsCols"
1461
+ :table-actions="tableActions"
1462
+ :table-cols-options="columnOptions"
1463
+ :row-actions="rowActions"
1464
+ :sub-expand-column="subExpandColumn"
1465
+ :row-actions-width="rowActionsWidth"
1466
+ :how-much-selected="howMuchSelected"
1467
+ :sort-by="sortBy"
1468
+ :default-sort-by="_defaultSortBy"
1469
+ :descending="descending"
1470
+ :no-rows="noRows"
1471
+ :loading="isLoading && !loadingDelay"
1472
+ :no-results="noResults"
1473
+ @on-toggle-all="onToggleAll"
1474
+ @on-sort-change="changeSort"
1475
+ @col-visibility-change="changeColVisibility"
1476
+ @group-value-change="(val) => $emit('group-value-change', val)"
1477
+ @update-cols-options="updateColsOptions"
1478
+ />
1330
1479
 
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" />
1480
+ <!-- Don't display anything if we're loading and the delay has yet to pass -->
1481
+ <div v-if="isLoading && !loadingDelay" />
1482
+
1483
+ <tbody v-else-if="isLoading && !altLoading">
1484
+ <slot name="loading">
1485
+ <tr>
1486
+ <td :colspan="fullColspan">
1487
+ <div class="data-loading">
1488
+ <i class="icon-spin icon icon-spinner" />
1489
+ <t
1490
+ k="generic.loading"
1491
+ :raw="true"
1492
+ />
1493
+ </div>
1494
+ </td>
1495
+ </tr>
1496
+ </slot>
1497
+ </tbody>
1498
+ <tbody v-else-if="noRows">
1499
+ <slot name="no-rows">
1500
+ <tr class="no-rows">
1501
+ <td :colspan="fullColspan">
1337
1502
  <t
1338
- k="generic.loading"
1339
- :raw="true"
1503
+ v-if="showNoRows"
1504
+ :k="noRowsKey"
1340
1505
  />
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"
1506
+ </td>
1507
+ </tr>
1508
+ </slot>
1509
+ </tbody>
1510
+ <tbody v-else-if="noResults">
1511
+ <slot name="no-results">
1512
+ <tr class="no-results">
1513
+ <td
1514
+ :colspan="fullColspan"
1515
+ class="text-center"
1388
1516
  >
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"
1517
+ <t :k="noDataKey" />
1518
+ </td>
1519
+ </tr>
1520
+ </slot>
1521
+ </tbody>
1522
+ <tbody
1523
+ v-for="(groupedRows) in displayRows"
1524
+ v-else
1525
+ :key="groupedRows.key"
1526
+ tabindex="-1"
1527
+ :class="{ group: groupBy }"
1402
1528
  >
1403
1529
  <slot
1404
- name="main-row"
1405
- :row="row.row"
1530
+ v-if="groupBy"
1531
+ name="group-row"
1532
+ :group="groupedRows"
1533
+ :fullColspan="fullColspan"
1534
+ >
1535
+ <tr class="group-row">
1536
+ <td :colspan="fullColspan">
1537
+ <slot
1538
+ name="group-by"
1539
+ :group="groupedRows.grp"
1540
+ >
1541
+ <div
1542
+ v-trim-whitespace
1543
+ class="group-tab"
1544
+ >
1545
+ {{ groupedRows.ref }}
1546
+ </div>
1547
+ </slot>
1548
+ </td>
1549
+ </tr>
1550
+ </slot>
1551
+ <template
1552
+ v-for="(row, i) in groupedRows.rows"
1553
+ :key="i"
1406
1554
  >
1407
1555
  <slot
1408
- :name="'main-row:' + (row.row.mainRowKey || i)"
1409
- :full-colspan="fullColspan"
1556
+ name="main-row"
1557
+ :row="row.row"
1410
1558
  >
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"
1559
+ <slot
1560
+ :name="'main-row:' + (row.row.mainRowKey || i)"
1561
+ :full-colspan="fullColspan"
1420
1562
  >
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"
1439
- >
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"
1563
+ <!-- The data-cant-run-bulk-action-of-interest attribute is being used instead of :class because
1564
+ because our selection.js invokes toggleClass and :class clobbers what was added by toggleClass if
1565
+ the value of :class changes. -->
1566
+ <tr
1567
+ class="main-row"
1568
+ :data-testid="componentTestid + '-' + i + '-row'"
1569
+ :class="{ 'has-sub-row': row.showSubRow}"
1570
+ :data-node-id="row.key"
1571
+ :data-cant-run-bulk-action-of-interest="actionOfInterest && !row.canRunBulkActionOfInterest"
1453
1572
  >
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"
1573
+ <td
1574
+ v-if="tableActions"
1575
+ class="row-check"
1576
+ align="middle"
1461
1577
  >
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"
1578
+ {{ row.mainRowKey }}
1579
+ <Checkbox
1580
+ class="selection-checkbox"
1581
+ :data-node-id="row.key"
1582
+ :data-testid="componentTestid + '-' + i + '-checkbox'"
1583
+ :value="selectedRows.includes(row.row)"
1584
+ :alternate-label="t('sortableTable.genericRowCheckbox', { item: row && row.row ? row.row.id : '' })"
1585
+ />
1586
+ </td>
1587
+ <td
1588
+ v-if="subExpandColumn"
1589
+ class="row-expand"
1590
+ align="middle"
1591
+ >
1592
+ <i
1593
+ data-title="Toggle Expand"
1594
+ :class="{
1595
+ icon: true,
1596
+ 'icon-chevron-right': !expanded[row.row[keyField]],
1597
+ 'icon-chevron-down': !!expanded[row.row[keyField]]
1598
+ }"
1599
+ @click.stop="toggleExpand(row.row)"
1600
+ />
1601
+ </td>
1602
+ <template
1603
+ v-for="(col, j) in row.columns"
1604
+ :key="j"
1605
+ >
1606
+ <slot
1607
+ :name="'col:' + col.col.name"
1608
+ :row="row.row"
1609
+ :col="col.col"
1610
+ :dt="dt"
1611
+ :expanded="expanded"
1612
+ :rowKey="row.key"
1470
1613
  >
1471
- <slot
1472
- :name="'cell:' + col.col.name"
1473
- :row="row.row"
1474
- :col="col.col"
1475
- :value="col.value"
1614
+ <td
1615
+ v-show="!hasAdvancedFiltering || (hasAdvancedFiltering && col.col.isColVisible)"
1616
+ :key="col.col.name"
1617
+ :data-title="col.col.label"
1618
+ :data-testid="`sortable-cell-${ i }-${ j }`"
1619
+ :align="'left'"
1620
+ :class="{['col-'+col.dasherize]: !!col.col.formatter, [col.col.breakpoint]: !!col.col.breakpoint, ['skip-select']: col.col.skipSelect}"
1621
+ :width="col.col.width"
1476
1622
  >
1477
- <component
1478
- :is="col.component"
1479
- v-if="col.component && col.needRef"
1480
- ref="column"
1481
- :value="col.value"
1623
+ <slot
1624
+ :name="'cell:' + col.col.name"
1482
1625
  :row="row.row"
1483
1626
  :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
1627
  :value="col.value"
1492
- :row="row.row"
1493
- :col="col.col"
1494
- v-bind="col.col.formatterOpts"
1495
- :row-key="row.key"
1628
+ >
1629
+ <component
1630
+ :is="col.component"
1631
+ v-if="col.component && col.needRef"
1632
+ ref="column"
1633
+ :value="col.value"
1634
+ :row="row.row"
1635
+ :col="col.col"
1636
+ :get-custom-detail-link="getCustomDetailLink"
1637
+ v-bind="col.col.formatterOpts"
1638
+ :row-key="row.key"
1639
+ />
1640
+ <component
1641
+ :is="col.component"
1642
+ v-else-if="col.component"
1643
+ :value="col.value"
1644
+ :row="row.row"
1645
+ :col="col.col"
1646
+ v-bind="col.col.formatterOpts"
1647
+ :row-key="row.key"
1648
+ />
1649
+ <component
1650
+ :is="col.col.formatter"
1651
+ v-else-if="col.col.formatter"
1652
+ :value="col.value"
1653
+ :row="row.row"
1654
+ :col="col.col"
1655
+ v-bind="col.col.formatterOpts"
1656
+ :row-key="row.key"
1657
+ />
1658
+ <template v-else-if="col.value !== ''">
1659
+ {{ col.formatted }}
1660
+ </template>
1661
+ <template v-else-if="col.col.dashIfEmpty">
1662
+ <span class="text-muted">&mdash;</span>
1663
+ </template>
1664
+ </slot>
1665
+ </td>
1666
+ </slot>
1667
+ </template>
1668
+ <td
1669
+ v-if="rowActions"
1670
+ :align="'left'"
1671
+ style="height:60px"
1672
+ >
1673
+ <div style="display: flex;align-items: center;">
1674
+ <slot
1675
+ name="row-actions"
1676
+ :row="row.row"
1677
+ :index="i"
1678
+ >
1679
+ </slot>
1680
+ <template v-if="featureDropdownMenu">
1681
+ <ActionMenu
1682
+ :resource="row.row"
1683
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1684
+ :button-aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1496
1685
  />
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"
1686
+ </template>
1687
+ <template v-else>
1688
+ <ButtonMultiAction
1689
+ :id="`actionButton+${i}+${(row.row && row.row.name) ? row.row.name : ''}`"
1690
+ :ref="`actionButton${i}`"
1691
+ aria-haspopup="true"
1692
+ aria-expanded="false"
1693
+ :aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1694
+ :data-testid="componentTestid + '-' + i + '-action-button'"
1695
+ :borderless="true"
1696
+ @click="handleActionButtonClick(i, $event)"
1697
+ @keyup.enter="handleActionButtonClick(i, $event)"
1698
+ @keyup.space="handleActionButtonClick(i, $event)"
1505
1699
  />
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>
1700
+ </template>
1701
+ </div>
1702
+ </td>
1703
+ </tr>
1704
+ </slot>
1705
+ </slot>
1706
+ <!-- <slot
1707
+ v-if="row.showSubRow"
1708
+ name="sub-row"
1709
+ :full-colspan="fullColspan"
1710
+ :row="row.row"
1711
+ :sub-matches="subMatches"
1712
+ :keyField="keyField"
1713
+ :componentTestid="componentTestid"
1714
+ :i="i"
1715
+ :onRowMouseEnter="onRowMouseEnter"
1716
+ :onRowMouseLeave="onRowMouseLeave"
1717
+ >
1718
+ <tr
1719
+ v-if="row.row.stateDescription"
1720
+ :key="row.row[keyField] + '-description'"
1721
+ :data-testid="componentTestid + '-' + i + '-row-description'"
1722
+ class="state-description sub-row"
1723
+ @mouseenter="onRowMouseEnter"
1724
+ @mouseleave="onRowMouseLeave"
1725
+ >
1726
+ <td
1727
+ v-if="tableActions"
1728
+ class="row-check"
1729
+ align="middle"
1730
+ />
1516
1731
  <td
1517
- v-if="rowActions"
1732
+ :colspan="fullColspan - (tableActions ? 1: 0)"
1733
+ :class="{ 'text-error' : row.row.stateObj.error }"
1518
1734
  >
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>
1735
+ {{ row.row.stateDescription }}
1546
1736
  </td>
1547
1737
  </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>
1738
+ </slot> -->
1739
+ </template>
1740
+ </tbody>
1741
+ </table>
1742
+ </div>
1586
1743
  <div
1587
- v-if="showPaging"
1588
- class="paging"
1744
+ v-if="!noRows && !noResults"
1745
+ :class="$route.path=== '/account'? 'chebox-padding':''"
1746
+ 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
1747
  >
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')"
1748
+ <div style="display: flex;justify-content: center;height: 32px;">
1749
+ <Checkbox
1750
+ v-if="tableActions&&availableActions.some(item => item.action != 'download')"
1751
+ :value="isMuchSelected"
1752
+ class="check"
1753
+ data-testid="sortable-table_check_select_all"
1754
+ :disabled="noRows || noResults"
1755
+ style="display: flex;justify-content: center;align-content: center;"
1756
+ @update:value = "muchSelect"
1602
1757
  />
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')"
1758
+ </div>
1759
+ <div
1760
+ :class="{'titled': $slots.title && $slots.title.length}"
1761
+ class="sortable-table-header"
1762
+ style="margin-left: 10px;min-width: 55%;"
1612
1763
  >
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')"
1764
+ <slot name="title" />
1765
+ <div
1766
+ v-if="showHeaderRow"
1767
+ class="fixed-footer-actions"
1768
+ :class="{button: !!$slots['header-button'], 'advanced-filtering': hasAdvancedFiltering,}"
1769
+ >
1770
+ <div
1771
+ :class="bulkActionsClass"
1772
+ class="bulk"
1773
+ >
1774
+ <slot name="header-left">
1775
+ <template v-if="tableActions">
1776
+ <button
1777
+ v-for="(act) in availableActions"
1778
+ :id="act.action"
1779
+ :key="act.action"
1780
+ v-clean-tooltip="actionTooltip"
1781
+ type="button"
1782
+ class="btn role-primary"
1783
+ :class="{[bulkActionClass]:true}"
1784
+ :disabled="!act.enabled"
1785
+ :data-testid="componentTestid + '-' + act.action"
1786
+ role="button"
1787
+ :aria-label="act.label"
1788
+ @click="applyTableAction(act, null, $event)"
1789
+ @keydown.enter.stop
1790
+ @mouseover="setBulkActionOfInterest(act)"
1791
+ @mouseleave="setBulkActionOfInterest(null)"
1792
+ >
1793
+ <!-- <i
1794
+ v-if="act.icon"
1795
+ :class="act.icon"
1796
+ style="line-height: 12px;height: 12px;font-size: 12px;"
1797
+ /> -->
1798
+ <span v-clean-html="act.label" />
1799
+ </button>
1800
+ <template v-if="featureDropdownMenu">
1801
+ <ActionDropdownShell
1802
+ :disabled="!selectedRows.length"
1803
+ :hidden-actions="hiddenActions"
1804
+ :action-tooltip="actionTooltip"
1805
+ @click="applyTableAction"
1806
+ @mouseover="setBulkActionOfInterest"
1807
+ @mouseleave="setBulkActionOfInterest"
1808
+ />
1809
+ </template>
1810
+ <template v-else>
1811
+ <ActionDropdown
1812
+ :class="bulkActionsDropdownClass"
1813
+ class="bulk-actions-dropdown"
1814
+ :disable-button="!selectedRows.length"
1815
+ size="sm"
1816
+ >
1817
+ <template #button-content>
1818
+ <button
1819
+ ref="actionDropDown"
1820
+ class="btn bg-primary mr-0"
1821
+ :disabled="!selectedRows.length"
1822
+ >
1823
+ <i class="icon icon-gear" />
1824
+ <span>{{ t('sortableTable.bulkActions.collapsed.label') }}</span>
1825
+ <i class="ml-10 icon icon-chevron-down" />
1826
+ </button>
1827
+ </template>
1828
+ <template #popover-content>
1829
+ <ul class="list-unstyled menu">
1830
+ <li
1831
+ v-for="(act, i) in hiddenActions"
1832
+ :key="i"
1833
+ v-close-popper
1834
+ v-clean-tooltip="{
1835
+ content: actionTooltip,
1836
+ placement: 'right'
1837
+ }"
1838
+ :class="{ disabled: !act.enabled }"
1839
+ @click="applyTableAction(act, null, $event)"
1840
+ @mouseover="setBulkActionOfInterest(act)"
1841
+ @mouseleave="setBulkActionOfInterest(null)"
1842
+ >
1843
+ <i
1844
+ v-if="act.icon"
1845
+ :class="act.icon"
1846
+ />
1847
+ <span v-clean-html="act.label" />
1848
+ </li>
1849
+ </ul>
1850
+ </template>
1851
+ </ActionDropdown>
1852
+ </template>
1853
+ <label
1854
+ v-if="selectedRowsText"
1855
+ :class="bulkActionAvailabilityClass"
1856
+ class="action-availability"
1857
+ >
1858
+ {{ tableActions&&availableActions.some(item => item.action != 'download') ?selectedRowsText: '' }}
1859
+ </label>
1860
+
1861
+ </template>
1862
+ </slot>
1863
+ </div>
1864
+ </div>
1865
+ </div>
1866
+
1867
+ <!-- 分页 -->
1868
+ <div
1869
+ v-if="showPaging"
1870
+ class="paging"
1629
1871
  >
1630
- <i
1631
- class="icon icon-chevron-right"
1632
- :alt="t('sortableTable.alt.nextPageBtn')"
1872
+ <div style="height: 100%; align-content: center;">
1873
+ {{ totalCount ? totalCount : 0 }} 条
1874
+ </div>
1875
+
1876
+ <button
1877
+ type="button"
1878
+ class="btn btn-sm role-multi-action page-btn-normal"
1879
+ :disabled="page == 1"
1880
+ :style="{ color: page <= totalPages ? `var(--default-text) !important` : `var(--paimary)`,border: page <= totalPages ? `solid thin var(--border)` : `solid thin var(--paimary)`}"
1881
+ @click="goToPage('prev')"
1882
+ >
1883
+ <!-- <i class="icon icon-chevron-left" /> -->
1884
+ <
1885
+ </button>
1886
+ <button
1887
+ type="button"
1888
+ class="btn btn-sm role-multi-action page-btn-normal"
1889
+ :style="{ color: (page == 1) ? `var(--primary)`:`var(--default-text) !important`,border: (page == 1) ? `solid thin var(--primary)` : `solid thin var(--border)`}"
1890
+ @click="goToPage('first')"
1891
+ >
1892
+ <!-- <i class="icon icon-chevron-beginning" /> -->
1893
+ {{ 1 }}
1894
+ </button>
1895
+ <template v-if="totalPages > 2">
1896
+ <div style="display: flex;flex-direction: row;gap: 10px;">
1897
+ <button
1898
+ v-if="page - 2 > 1 && page <= totalPages "
1899
+ type="button"
1900
+ class="btn btn-sm role-multi-action page-btn-normal"
1901
+ :style="{ color: `var(--default-text) !important`,border: `solid thin white`}"
1902
+ >
1903
+ ...
1904
+ </button>
1905
+ <button
1906
+ v-if="page - 1 > 1 && page <= totalPages "
1907
+ type="button"
1908
+ class="btn btn-sm role-multi-action page-btn-normal"
1909
+ :style="{ color: `var(--default-text) !important`,border: `solid thin var(--border)`}"
1910
+ @click="setPage(page-1)"
1911
+ >
1912
+ {{ page-1 }}
1913
+ </button>
1914
+ <button
1915
+ v-if="page > 1 && page < totalPages"
1916
+ type="button"
1917
+ class="btn btn-sm role-multi-action page-btn-normal"
1918
+ :style="{ color: `var(--default-text)`,border: `solid thin var(--primary)`}"
1919
+ @click="setPage(page)"
1920
+ >
1921
+ {{ page }}
1922
+ </button>
1923
+ <button
1924
+ v-if="page + 1 < totalPages "
1925
+ type="button"
1926
+ class="btn btn-sm role-multi-action page-btn-normal"
1927
+ :style="{ color: `var(--default-text) !important`,border: `solid thin var(--border)`}"
1928
+ @click="setPage(page+1)"
1929
+ >
1930
+ {{ page+1 }}
1931
+ </button>
1932
+ <button
1933
+ v-if="page +2 < totalPages "
1934
+ type="button"
1935
+ class="btn btn-sm role-multi-action page-btn-normal"
1936
+ :style="{ color: `var(--default-text) !important`,border: `solid thin white`}"
1937
+ >
1938
+ ...
1939
+ </button>
1940
+ </div>
1941
+ </template>
1942
+ <!-- <button
1943
+ type="button"
1944
+ class="btn btn-sm role-multi-action"
1945
+ style="padding: 0;max-width: 32px;background-color: white !important;"
1946
+ >
1947
+ {{ page }}
1948
+ </button> -->
1949
+ <button
1950
+ v-if="totalPages > 1"
1951
+ type="button"
1952
+ class="btn btn-sm role-multi-action page-btn-normal"
1953
+ :style="{ color: (page == totalPages) ? `var(--primary)`:`var(--default-text) !important`,border: (page == totalPages) ? `solid thin var(--primary)` : `solid thin var(--border)`}"
1954
+ @click="goToPage('last')"
1955
+ >
1956
+ <!-- <i class="icon icon-chevron-end" /> -->
1957
+ {{ totalPages }}
1958
+ </button>
1959
+ <button
1960
+ type="button"
1961
+ class="btn btn-sm role-multi-action page-btn-normal"
1962
+ :disabled="page == totalPages"
1963
+ :style="{ color: page <= totalPages ? `var(--default-text) !important` : `var(--paimary)`,border: page <= totalPages ? `solid thin var(--border)` : `solid thin var(--paimary)`}"
1964
+ @click="goToPage('next')"
1965
+ >
1966
+ <!-- <i class="icon icon-chevron-right" /> -->
1967
+ >
1968
+ </button>
1969
+
1970
+ <!-- 分页页码切换 -->
1971
+ <Select
1972
+ :mode="inputPerPage"
1973
+ :searchable="false"
1974
+ :clearable="false"
1975
+ :options="perPageOptions"
1976
+ v-model:value="inputPerPage"
1977
+ class="pageSelect"
1978
+ @update:value="changePerPage"
1633
1979
  />
1634
- </button>
1635
- <button
1980
+
1981
+ <div style="height: 100%; align-content: center;">
1982
+ 跳至
1983
+ </div>
1984
+ <input
1985
+ v-model="inputPage"
1986
+ type="number"
1987
+ min="1"
1988
+ step="1"
1989
+ style="padding: 0px 10px;"
1990
+ @keyup.enter="handleToPage"
1991
+ >
1992
+ <div style="height: 100%; align-content: center;">
1993
+
1994
+ </div>
1995
+ <!-- <button
1636
1996
  type="button"
1637
1997
  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')"
1998
+ style="padding: 0;max-width: 80px;background-color: white !important;"
1999
+ @click="setPage(inputPage)"
1643
2000
  >
1644
- <i
1645
- class="icon icon-chevron-end"
1646
- :alt="t('sortableTable.alt.lastPageBtn')"
1647
- />
1648
- </button>
2001
+
2002
+ </button> -->
2003
+ </div>
1649
2004
  </div>
1650
2005
  <button
1651
2006
  v-if="search"
@@ -1829,9 +2184,12 @@ export default {
1829
2184
  }
1830
2185
 
1831
2186
  .search-box {
1832
- height: 40px;
1833
- margin-left: 10px;
1834
- min-width: 180px;
2187
+ height: 32px;
2188
+ margin-left: 0px;
2189
+ /* min-width: 180px; */
2190
+ min-width: 280px;
2191
+ width: 280px !important;
2192
+ border: 1px solid rgb(217, 217, 217);
1835
2193
  }
1836
2194
  </style>
1837
2195
 
@@ -1857,7 +2215,8 @@ export default {
1857
2215
  border-collapse: collapse;
1858
2216
  min-width: 400px;
1859
2217
  border-radius: 5px 5px 0 0;
1860
- outline: 1px solid var(--border);
2218
+ border-bottom: 1px solid var(--border) !important;
2219
+ /* outline: 1px solid var(--border); */
1861
2220
  background: var(--sortable-table-bg);
1862
2221
  border-radius: 4px;
1863
2222
 
@@ -1871,6 +2230,9 @@ export default {
1871
2230
  td {
1872
2231
  padding: 8px 5px;
1873
2232
  border: 0;
2233
+ white-space: normal;
2234
+ word-break: break-all;
2235
+ overflow-wrap: break-word;
1874
2236
 
1875
2237
  &:first-child {
1876
2238
  padding-left: 10px;
@@ -1887,8 +2249,9 @@ export default {
1887
2249
 
1888
2250
  tbody {
1889
2251
  tr {
1890
- border-bottom: 1px solid var(--sortable-table-top-divider);
2252
+ border-bottom: 1px solid var(--sortable-table-top-divider) !important;
1891
2253
  background-color: var(--sortable-table-row-bg);
2254
+ height: 60px;
1892
2255
 
1893
2256
  &.main-row.has-sub-row {
1894
2257
  border-bottom: 0;
@@ -1904,7 +2267,7 @@ export default {
1904
2267
  }
1905
2268
 
1906
2269
  &:hover, &.sub-row-hovered {
1907
- background-color: var(--sortable-table-hover-bg);
2270
+ /* background-color: var(--sortable-table-hover-bg); */
1908
2271
  }
1909
2272
 
1910
2273
  &.state-description > td {
@@ -1919,7 +2282,7 @@ export default {
1919
2282
  }
1920
2283
 
1921
2284
  tr.row-selected {
1922
- background: var(--sortable-table-selected-bg);
2285
+ /* background: var(--sortable-table-selected-bg); */
1923
2286
  }
1924
2287
 
1925
2288
  .no-rows {
@@ -1934,12 +2297,15 @@ export default {
1934
2297
  background-color: var(--body-bg);
1935
2298
  }
1936
2299
  }
2300
+ .no-results{
2301
+ height: 60px;
2302
+ }
1937
2303
 
1938
2304
  &.group {
1939
2305
  &:before {
1940
2306
  content: "";
1941
2307
  display: block;
1942
- height: 20px;
2308
+ height: 0px;
1943
2309
  background-color: transparent;
1944
2310
  }
1945
2311
  }
@@ -1949,6 +2315,7 @@ export default {
1949
2315
 
1950
2316
  &:first-child {
1951
2317
  border-bottom: 2px solid var(--sortable-table-row-bg);
2318
+ height: 40px;
1952
2319
  }
1953
2320
 
1954
2321
  &:not(:first-child) {
@@ -2037,12 +2404,12 @@ export default {
2037
2404
  align-items: center;
2038
2405
  }
2039
2406
  }
2040
- .fixed-header-actions.button{
2407
+ .fixed-footer-actions.button{
2041
2408
  grid-template-columns: [bulk] auto [middle] min-content [search] minmax(min-content, 350px);
2042
2409
  }
2043
2410
 
2044
- .fixed-header-actions {
2045
- padding: 0 0 20px 0;
2411
+ .fixed-footer-actions {
2412
+ /* padding: 0 0 20px 0; */
2046
2413
  width: 100%;
2047
2414
  z-index: z-index('fixedTableHeader');
2048
2415
  background: transparent;
@@ -2157,13 +2524,235 @@ export default {
2157
2524
  }
2158
2525
  }
2159
2526
 
2527
+
2528
+ .fixed-header-table-actions {
2529
+ width: 100%;
2530
+ z-index: z-index('fixedTableHeader');
2531
+ background: transparent;
2532
+ display: flex;
2533
+ justify-content: space-between;
2534
+
2535
+
2536
+ .bulk {
2537
+ $gap: 10px;
2538
+
2539
+ & > BUTTON {
2540
+ display: none; // Handled dynamically
2541
+ }
2542
+
2543
+ & > BUTTON:not(:last-of-type) {
2544
+ margin-right: $gap;
2545
+ }
2546
+
2547
+ .action-availability {
2548
+ display: none; // Handled dynamically
2549
+ margin-left: $gap;
2550
+ vertical-align: middle;
2551
+ margin-top: 2px;
2552
+ }
2553
+
2554
+ .dropdown-button {
2555
+ $disabled-color: var(--disabled-text);
2556
+ $disabled-cursor: not-allowed;
2557
+ li.disabled {
2558
+ color: $disabled-color;
2559
+ cursor: $disabled-cursor;
2560
+
2561
+ &:hover {
2562
+ color: $disabled-color;
2563
+ background-color: unset;
2564
+ cursor: $disabled-cursor;
2565
+ }
2566
+ }
2567
+ }
2568
+
2569
+ .bulk-action {
2570
+ .icon {
2571
+ vertical-align: -10%;
2572
+ }
2573
+ }
2574
+ }
2575
+
2576
+ .middle {
2577
+ white-space: nowrap;
2578
+
2579
+ .icon.icon-backup.animate {
2580
+ animation-name: spin;
2581
+ animation-duration: 1000ms;
2582
+ animation-iteration-count: infinite;
2583
+ animation-timing-function: linear;
2584
+ }
2585
+
2586
+ @keyframes spin {
2587
+ from {
2588
+ transform:rotate(0deg);
2589
+ }
2590
+ to {
2591
+ transform:rotate(360deg);
2592
+ }
2593
+ }
2594
+ }
2595
+
2596
+ .search {
2597
+ text-align: right;
2598
+ justify-content: flex-end;
2599
+ }
2600
+
2601
+ .bulk-actions-dropdown {
2602
+ display: none; // Handled dynamically
2603
+
2604
+ .dropdown-button {
2605
+ background-color: var(--primary);
2606
+
2607
+ &:hover {
2608
+ background-color: var(--primary-hover-bg);
2609
+ color: var(--primary-hover-text);
2610
+ }
2611
+
2612
+ > *, .icon-chevron-down {
2613
+ color: var(--primary-text);
2614
+ }
2615
+
2616
+ .button-divider {
2617
+ border-color: var(--primary-text);
2618
+ }
2619
+
2620
+ &.disabled {
2621
+ border-color: var(--disabled-bg);
2622
+
2623
+ .icon-chevron-down {
2624
+ color: var(--disabled-text) !important;
2625
+ }
2626
+
2627
+ .button-divider {
2628
+ border-color: var(--disabled-text);
2629
+ }
2630
+ }
2631
+ }
2632
+ }
2633
+ }
2634
+
2160
2635
  .paging {
2161
- margin-top: 10px;
2636
+ //text-align: center;
2637
+ display: flex;
2638
+ justify-content: flex-end;
2639
+ gap: 0 10px;
2162
2640
  text-align: center;
2163
-
2641
+ max-height: 32px;
2642
+ background-color: transparent;
2643
+ flex: 1;
2164
2644
  SPAN {
2165
2645
  display: inline-block;
2166
- min-width: 200px;
2646
+ //min-width: 200px;
2647
+ min-width: auto;
2648
+ }
2649
+
2650
+ /* 针对Webkit浏览器(如Chrome, Safari) */
2651
+ input[type="number"]::-webkit-inner-spin-button,
2652
+ input[type="number"]::-webkit-outer-spin-button {
2653
+ -webkit-appearance: none;
2654
+ margin: 0;
2655
+ }
2656
+
2657
+ /* 针对Firefox */
2658
+ input[type="number"] {
2659
+ -moz-appearance: textfield;
2660
+ // background-color: var(--disabled-bg) !important;
2661
+ border: 1px var(--border) solid;
2662
+ border-radius: 2px;
2663
+ width: 50px;
2664
+ height: 100%;
2167
2665
  }
2168
2666
  }
2667
+
2169
2668
  </style>
2669
+ <style scoped lang="scss">
2670
+ :deep() .role-link{
2671
+ min-width: unset !important;
2672
+ width: 38px;
2673
+ min-height: 20px !important;
2674
+ height: 20px !important;
2675
+ line-height: 20px !important;
2676
+ &:hover{
2677
+ background-color: unset !important;
2678
+ }
2679
+ }
2680
+ :deep() .checkbox-outer-container-extra{
2681
+ margin-top: 0px !important;
2682
+ }
2683
+ .pageSelect {
2684
+ overflow: hidden;
2685
+ max-width: 100px;
2686
+ }
2687
+ .page-btn-normal {
2688
+ padding: 0;
2689
+ max-width: 32px;
2690
+ background-color:white !important;
2691
+ }
2692
+
2693
+ .pageSelect{
2694
+ &:deep() .vs__actions:after{
2695
+ // padding-top: 10px;
2696
+ display: flex;
2697
+ align-items: center;
2698
+ }
2699
+ }
2700
+ .sort-table-div{
2701
+ width:100%;
2702
+ white-space:nowrap;
2703
+ // overflow-x: auto;
2704
+ }
2705
+
2706
+ /* 滚动阴影左边 */
2707
+ .shadow-left td:nth-child(2)::after{
2708
+ content: "";
2709
+ position: absolute;
2710
+ top: 0;
2711
+ width: 10px;
2712
+ height: 100%;
2713
+ right: -10px;
2714
+ background: linear-gradient(to right, rgba(5, 5, 5, 0.06), transparent);
2715
+ }
2716
+ .shadow-left{
2717
+ &:deep() th:nth-child(2)::after{
2718
+ content: "";
2719
+ position: absolute;
2720
+ top: 0;
2721
+ width: 10px;
2722
+ height: 100%;
2723
+ right: -10px;
2724
+ background: linear-gradient(to right, rgba(5, 5, 5, 0.06), transparent);
2725
+ }
2726
+ }
2727
+
2728
+ /* 滚动阴影右边 */
2729
+ .shadow-right td:nth-last-child(1)::after{
2730
+ content: "";
2731
+ position: absolute;
2732
+ top: 0;
2733
+ width: 10px;
2734
+ height: 100%;
2735
+ left: -10px;
2736
+ background: linear-gradient(to left, rgba(5, 5, 5, 0.06), transparent);
2737
+ }
2738
+
2739
+ .shadow-right{
2740
+ &:deep() th:nth-last-child(1)::after {
2741
+ content: "";
2742
+ position: absolute;
2743
+ top: 0;
2744
+ width: 10px;
2745
+ height: 100%;
2746
+ left: -10px;
2747
+ background: linear-gradient(to left, rgba(5, 5, 5, 0.06), transparent);
2748
+ }
2749
+ }
2750
+
2751
+ /* 滚动阴影垂直修正 */
2752
+ .shadow-y td:nth-child(-n + 2), /* 前两列 */
2753
+ .shadow-y td:nth-last-child(1) /* 后一列 */
2754
+ {
2755
+ z-index: 3;
2756
+ }
2757
+ </style>
2758
+