ModulesTable.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <script setup lang="tsx">
  2. import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
  3. import type { TableColumnType } from 'ant-design-vue'
  4. import type { FilterResetProps } from 'ant-design-vue/es/table/interface'
  5. import { useGlobalStore } from '@/pinia'
  6. import { SearchOutlined } from '@ant-design/icons-vue'
  7. import { Button as AButton, Input as AInput } from 'ant-design-vue'
  8. const globalStore = useGlobalStore()
  9. const { modules } = storeToRefs(globalStore)
  10. const searchText = ref('')
  11. const searchInput = ref<HTMLInputElement>()
  12. function handleSearch(selectedKeys: string[], confirm: () => void) {
  13. confirm()
  14. searchText.value = selectedKeys[0]
  15. }
  16. function handleReset(clearFilters?: (param?: FilterResetProps) => void) {
  17. clearFilters?.({ confirm: true })
  18. searchText.value = ''
  19. }
  20. // Modules columns
  21. const modulesColumns: TableColumnType[] = [
  22. {
  23. title: $gettext('Module'),
  24. dataIndex: 'name',
  25. width: '800px',
  26. filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
  27. <div style="padding: 8px">
  28. <AInput
  29. ref={searchInput}
  30. value={selectedKeys[0]}
  31. placeholder={$gettext('Search module name')}
  32. style="width: 188px; margin-bottom: 8px; display: block;"
  33. onInput={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
  34. onPressEnter={() => handleSearch(selectedKeys as string[], confirm)}
  35. class="mb-2"
  36. />
  37. <div class="flex justify-between">
  38. <AButton
  39. type="primary"
  40. onClick={() => handleSearch(selectedKeys as string[], confirm)}
  41. size="small"
  42. class="mr-2"
  43. >
  44. {$gettext('Search')}
  45. </AButton>
  46. <AButton
  47. onClick={() => handleReset(clearFilters)}
  48. size="small"
  49. >
  50. {$gettext('Reset')}
  51. </AButton>
  52. </div>
  53. </div>
  54. ),
  55. filterIcon: filtered => (
  56. <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />
  57. ),
  58. onFilter: (value, record) =>
  59. record.name && record.name.toString().toLowerCase().includes((value as string).toLowerCase()),
  60. onFilterDropdownVisibleChange: visible => {
  61. if (visible) {
  62. setTimeout(() => {
  63. if (searchInput.value) {
  64. searchInput.value.focus()
  65. }
  66. }, 100)
  67. }
  68. },
  69. customRender: (args: CustomRender) => {
  70. return (
  71. <div>
  72. <div>{args.record.name}</div>
  73. <div class="text-sm text-gray-500">{args.record.params}</div>
  74. </div>
  75. )
  76. },
  77. },
  78. {
  79. title: $gettext('Type'),
  80. dataIndex: 'dynamic',
  81. width: '100px',
  82. filters: [
  83. { text: $gettext('Dynamic'), value: true },
  84. { text: $gettext('Static'), value: false },
  85. ],
  86. onFilter: (value, record) => record.dynamic === value,
  87. customRender: ({ record }) => {
  88. return <span>{record.dynamic ? $gettext('Dynamic') : $gettext('Static')}</span>
  89. },
  90. },
  91. {
  92. title: $gettext('Status'),
  93. dataIndex: 'loaded',
  94. width: '100px',
  95. filters: [
  96. { text: $gettext('Loaded'), value: true },
  97. { text: $gettext('Not Loaded'), value: false },
  98. ],
  99. onFilter: (value, record) => record.loaded === value,
  100. customRender: ({ record }) => {
  101. return <span>{record.loaded ? $gettext('Loaded') : $gettext('Not Loaded')}</span>
  102. },
  103. },
  104. ]
  105. </script>
  106. <template>
  107. <div class="overflow-x-auto">
  108. <ATable
  109. :columns="modulesColumns"
  110. :data-source="modules"
  111. :pagination="false"
  112. size="middle"
  113. :scroll="{ x: '100%' }"
  114. />
  115. </div>
  116. </template>