StreamList.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <script setup lang="tsx">
  2. import type { EnvGroup } from '@/api/env_group'
  3. import type { Stream } from '@/api/stream'
  4. import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
  5. import type { Column, JSXElements } from '@/components/StdDesign/types'
  6. import env_group from '@/api/env_group'
  7. import stream from '@/api/stream'
  8. import EnvGroupTabs from '@/components/EnvGroupTabs/EnvGroupTabs.vue'
  9. import StdBatchEdit from '@/components/StdDesign/StdDataDisplay/StdBatchEdit.vue'
  10. import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
  11. import { actualValueRender, datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
  12. import { input, selector } from '@/components/StdDesign/StdDataEntry'
  13. import InspectConfig from '@/views/config/InspectConfig.vue'
  14. import envGroupColumns from '@/views/environments/group/columns'
  15. import StreamDuplicate from '@/views/stream/components/StreamDuplicate.vue'
  16. import { Badge, message } from 'ant-design-vue'
  17. const columns: Column[] = [{
  18. title: () => $gettext('Name'),
  19. dataIndex: 'name',
  20. sorter: true,
  21. pithy: true,
  22. edit: {
  23. type: input,
  24. },
  25. search: true,
  26. }, {
  27. title: () => $gettext('Environment Group'),
  28. dataIndex: 'env_group_id',
  29. customRender: actualValueRender('env_group.name'),
  30. edit: {
  31. type: selector,
  32. selector: {
  33. api: env_group,
  34. columns: envGroupColumns,
  35. recordValueIndex: 'name',
  36. selectionType: 'radio',
  37. },
  38. },
  39. sorter: true,
  40. pithy: true,
  41. batch: true,
  42. width: 150,
  43. }, {
  44. title: () => $gettext('Status'),
  45. dataIndex: 'enabled',
  46. customRender: (args: CustomRender) => {
  47. const template: JSXElements = []
  48. const { text } = args
  49. if (text === true || text > 0) {
  50. template.push(<Badge status="success" />)
  51. template.push($gettext('Enabled'))
  52. }
  53. else {
  54. template.push(<Badge status="warning" />)
  55. template.push($gettext('Disabled'))
  56. }
  57. return h('div', template)
  58. },
  59. sorter: true,
  60. pithy: true,
  61. width: 200,
  62. }, {
  63. title: () => $gettext('Updated at'),
  64. dataIndex: 'modified_at',
  65. customRender: datetime,
  66. sorter: true,
  67. pithy: true,
  68. width: 200,
  69. }, {
  70. title: () => $gettext('Action'),
  71. dataIndex: 'action',
  72. width: 250,
  73. fixed: 'right',
  74. }]
  75. const table = ref()
  76. const inspect_config = ref()
  77. function enable(name: string) {
  78. stream.enable(name).then(() => {
  79. message.success($gettext('Enabled successfully'))
  80. table.value?.get_list()
  81. inspect_config.value?.test()
  82. }).catch(r => {
  83. message.error($gettext('Failed to enable %{msg}', { msg: r.message ?? '' }), 10)
  84. })
  85. }
  86. function disable(name: string) {
  87. stream.disable(name).then(() => {
  88. message.success($gettext('Disabled successfully'))
  89. table.value?.get_list()
  90. inspect_config.value?.test()
  91. }).catch(r => {
  92. message.error($gettext('Failed to disable %{msg}', { msg: r.message ?? '' }))
  93. })
  94. }
  95. function destroy(stream_name: string) {
  96. stream.destroy(stream_name).then(() => {
  97. table.value.get_list()
  98. message.success($gettext('Delete stream: %{stream_name}', { stream_name }))
  99. inspect_config.value?.test()
  100. })
  101. }
  102. const showDuplicator = ref(false)
  103. const target = ref('')
  104. function handle_click_duplicate(name: string) {
  105. showDuplicator.value = true
  106. target.value = name
  107. }
  108. const route = useRoute()
  109. const envGroupId = ref(Number.parseInt(route.query.env_group_id as string) || 0)
  110. const envGroups = ref([]) as Ref<EnvGroup[]>
  111. onMounted(async () => {
  112. while (true) {
  113. try {
  114. const { data, pagination } = await env_group.get_list()
  115. if (!data || !pagination)
  116. return
  117. envGroups.value.push(...data)
  118. if (data.length < pagination?.per_page) {
  119. return
  120. }
  121. }
  122. catch {
  123. return
  124. }
  125. }
  126. })
  127. watch(route, () => {
  128. inspect_config.value?.test()
  129. })
  130. const showAddStream = ref(false)
  131. const name = ref('')
  132. function add() {
  133. showAddStream.value = true
  134. name.value = ''
  135. }
  136. function handleAddStream() {
  137. stream.save(name.value, { name: name.value, content: 'server\t{\n\n}' }).then(() => {
  138. showAddStream.value = false
  139. table.value?.get_list()
  140. message.success($gettext('Added successfully'))
  141. })
  142. }
  143. const stdBatchEditRef = useTemplateRef('stdBatchEditRef')
  144. async function handleClickBatchEdit(batchColumns: Column[], selectedRowKeys: string[], selectedRows: Stream[]) {
  145. stdBatchEditRef.value?.showModal(batchColumns, selectedRowKeys, selectedRows)
  146. }
  147. function handleBatchUpdated() {
  148. table.value?.get_list()
  149. table.value?.resetSelection()
  150. }
  151. </script>
  152. <template>
  153. <ACard :title="$gettext('Manage Streams')">
  154. <template #extra>
  155. <a @click="add">{{ $gettext('Add') }}</a>
  156. </template>
  157. <InspectConfig ref="inspect_config" />
  158. <EnvGroupTabs v-model:active-key="envGroupId" :env-groups="envGroups" />
  159. <StdTable
  160. ref="table"
  161. :api="stream"
  162. :columns="columns"
  163. row-key="name"
  164. disable-delete
  165. disable-view
  166. :scroll-x="800"
  167. :get-params="{
  168. env_group_id: envGroupId,
  169. }"
  170. @click-edit="r => $router.push({
  171. path: `/streams/${r}`,
  172. })"
  173. @click-batch-modify="handleClickBatchEdit"
  174. >
  175. <template #actions="{ record }">
  176. <AButton
  177. v-if="record.enabled"
  178. type="link"
  179. size="small"
  180. @click="disable(record.name)"
  181. >
  182. {{ $gettext('Disable') }}
  183. </AButton>
  184. <AButton
  185. v-else
  186. type="link"
  187. size="small"
  188. @click="enable(record.name)"
  189. >
  190. {{ $gettext('Enable') }}
  191. </AButton>
  192. <AButton
  193. type="link"
  194. size="small"
  195. @click="handle_click_duplicate(record.name)"
  196. >
  197. {{ $gettext('Duplicate') }}
  198. </AButton>
  199. <APopconfirm
  200. :cancel-text="$gettext('No')"
  201. :ok-text="$gettext('OK')"
  202. :title="$gettext('Are you sure you want to delete?')"
  203. :disabled="record.enabled"
  204. @confirm="destroy(record.name)"
  205. >
  206. <AButton
  207. type="link"
  208. size="small"
  209. :disabled="record.enabled"
  210. >
  211. {{ $gettext('Delete') }}
  212. </AButton>
  213. </APopconfirm>
  214. </template>
  215. </StdTable>
  216. <AModal
  217. v-model:open="showAddStream"
  218. :title="$gettext('Add Stream')"
  219. :mask="false"
  220. @ok="handleAddStream"
  221. >
  222. <AForm layout="vertical">
  223. <AFormItem :label="$gettext('Name')">
  224. <AInput v-model:value="name" />
  225. </AFormItem>
  226. </AForm>
  227. </AModal>
  228. <StreamDuplicate
  229. v-model:visible="showDuplicator"
  230. :name="target"
  231. @duplicated="() => table.get_list()"
  232. />
  233. <StdBatchEdit
  234. ref="stdBatchEditRef"
  235. :api="stream"
  236. :columns="columns"
  237. @save="handleBatchUpdated"
  238. />
  239. </ACard>
  240. </template>
  241. <style scoped>
  242. </style>