1
0

StdCurd.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <script setup lang="ts">
  2. import gettext from '@/gettext'
  3. import StdTable from './StdTable.vue'
  4. import StdDataEntry from '@/components/StdDataEntry'
  5. import {provide, reactive, ref} from 'vue'
  6. import {message} from 'ant-design-vue'
  7. const {$gettext} = gettext
  8. const props = defineProps({
  9. api: Object,
  10. columns: Array,
  11. title: String,
  12. data_key: {
  13. type: String,
  14. default: 'data'
  15. },
  16. disable_search: {
  17. type: Boolean,
  18. default: false
  19. },
  20. disable_add: {
  21. type: Boolean,
  22. default: false
  23. },
  24. soft_delete: {
  25. type: Boolean,
  26. default: false
  27. },
  28. edit_text: String,
  29. deletable: {
  30. type: Boolean,
  31. default: true
  32. },
  33. get_params: {
  34. type: Object,
  35. default() {
  36. return {}
  37. }
  38. },
  39. editable: {
  40. type: Boolean,
  41. default: true
  42. },
  43. beforeSave: {
  44. type: Function,
  45. default: null
  46. },
  47. exportCsv: {
  48. type: Boolean,
  49. default: false
  50. },
  51. modalWidth: {
  52. type: Number,
  53. default: 600
  54. },
  55. useSortable: Boolean
  56. })
  57. const visible = ref(false)
  58. const update = ref(0)
  59. const data: any = reactive({id: null})
  60. provide('data', data)
  61. const error: any = reactive({})
  62. const selected = ref([])
  63. function onSelect(keys: any) {
  64. selected.value = keys
  65. }
  66. function editableColumns() {
  67. return props.columns!.filter((c: any) => {
  68. return c.edit
  69. })
  70. }
  71. function add() {
  72. Object.keys(data).forEach(v => {
  73. delete data[v]
  74. })
  75. clear_error()
  76. visible.value = true
  77. }
  78. defineExpose({
  79. add,
  80. data
  81. })
  82. const table = ref(null)
  83. interface Table {
  84. get_list(): void
  85. }
  86. function clear_error() {
  87. Object.keys(error).forEach(v => {
  88. delete error[v]
  89. })
  90. }
  91. const ok = async () => {
  92. clear_error()
  93. await props?.beforeSave?.(data)
  94. props.api!.save(data.id, data).then((r: any) => {
  95. message.success($gettext('Save Successfully'))
  96. Object.assign(data, r)
  97. const t: Table | null = table.value
  98. t!.get_list()
  99. }).catch((e: any) => {
  100. message.error($gettext(e?.message ?? 'Server error'), 5)
  101. Object.assign(error, e.errors)
  102. })
  103. }
  104. function cancel() {
  105. visible.value = false
  106. clear_error()
  107. }
  108. function edit(id: any) {
  109. props.api!.get(id).then(async (r: any) => {
  110. Object.keys(data).forEach(k => {
  111. delete data[k]
  112. })
  113. data.id = null
  114. Object.assign(data, r)
  115. visible.value = true
  116. }).catch((e: any) => {
  117. message.error($gettext(e?.message ?? 'Server error'), 5)
  118. })
  119. }
  120. const selectedRowKeys = ref([])
  121. </script>
  122. <template>
  123. <div class="std-curd">
  124. <a-card :title="title||$gettext('Table')">
  125. <template v-if="!disable_add" #extra>
  126. <a @click="add" v-translate>Add</a>
  127. </template>
  128. <std-table
  129. ref="table"
  130. v-model:selected-row-keys="selectedRowKeys"
  131. v-bind="props"
  132. @clickEdit="edit"
  133. @selected="onSelect"
  134. :key="update"
  135. >
  136. <template v-slot:actions="slotProps">
  137. <slot name="actions" :actions="slotProps.record"/>
  138. </template>
  139. </std-table>
  140. </a-card>
  141. <a-modal
  142. class="std-curd-edit-modal"
  143. :mask="false"
  144. :title="edit_text?edit_text:(data.id ? $gettext('Modify') : $gettext('Add'))"
  145. :visible="visible"
  146. :cancel-text="$gettext('Cancel')"
  147. :ok-text="$gettext('OK')"
  148. @cancel="cancel"
  149. @ok="ok"
  150. :width="modalWidth"
  151. destroyOnClose
  152. >
  153. <div class="before-edit" v-if="$slots.beforeEdit">
  154. <slot name="beforeEdit" :data="data"/>
  155. </div>
  156. <std-data-entry
  157. ref="std_data_entry"
  158. :data-list="editableColumns()"
  159. :data-source="data"
  160. :error="error"
  161. />
  162. <slot name="edit" :data="data"/>
  163. </a-modal>
  164. </div>
  165. </template>
  166. <style lang="less" scoped>
  167. .before-edit:last-child {
  168. margin-bottom: 10px;
  169. }
  170. </style>