Bug 33066: Introduce a KohaTable Vue component
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / vue / components / KohaTable.vue
1 <template>
2     <DataTable
3         :columns="tableColumns"
4         :options="{ ...dataTablesDefaults, ...allOptions }"
5         :data="data"
6         ref="table"
7     >
8         <slot></slot>
9     </DataTable>
10 </template>
11
12 <script>
13 import DataTable from "datatables.net-vue3"
14 import DataTablesLib from "datatables.net"
15 import "datatables.net-buttons"
16 import "datatables.net-buttons/js/buttons.html5"
17 import "datatables.net-buttons/js/buttons.print"
18 DataTable.use(DataTablesLib)
19
20 export default {
21     name: "KohaTable",
22     data() {
23         return {
24             data: [],
25             tableColumns: this.columns,
26             allOptions: {
27                 deferRender: true,
28                 paging: true,
29                 serverSide: true,
30                 searching: true,
31                 pagingType: "full_numbers",
32                 processing: true,
33                 ajax: {
34                     url: typeof this.url === "function" ? this.url() : this.url,
35                     ..._dt_default_ajax({ options: this.options }),
36                 },
37                 buttons: _dt_buttons({ table_settings: this.table_settings }),
38                 default_search: this.$route.query.q,
39             },
40         }
41     },
42     setup() {
43         return { dataTablesDefaults }
44     },
45     methods: {
46         redraw: function (url) {
47             this.$refs.table.dt().ajax.url(url).draw()
48         },
49     },
50     beforeMount() {
51         if (this.actions.hasOwnProperty("-1")) {
52             let actions = this.actions["-1"]
53             this.tableColumns = [
54                 ...this.tableColumns,
55                 {
56                     name: "actions",
57                     title: this.$__("Actions"),
58                     searchable: false,
59                     render: (data, type, row) => {
60                         let content = []
61                         this.actions["-1"].forEach(a => {
62                             if (a == "edit") {
63                                 content.push(
64                                     '<a class="edit btn btn-default btn-xs" role="button"><i class="fa fa-pencil"></i>' +
65                                         this.$__("Edit") +
66                                         "</a>"
67                                 )
68                             } else if (a == "delete") {
69                                 content.push(
70                                     '<a class="delete btn btn-default btn-xs" role="button"><i class="fa fa-trash"></i>' +
71                                         this.$__("Delete") +
72                                         "</a>"
73                                 )
74                             }
75                         })
76                         return content.join(" ")
77                     },
78                 },
79             ]
80         }
81     },
82     mounted() {
83         if (Object.keys(this.actions).length) {
84             const dt = this.$refs.table.dt()
85             const self = this
86             dt.on("draw", () => {
87                 const dataSet = dt.rows().data()
88                 Object.entries(this.actions).forEach(([col_id, actions]) => {
89                     dt.column(col_id)
90                         .nodes()
91                         .to$()
92                         .each(function (idx) {
93                             const data = dataSet[idx]
94                             actions.forEach(action => {
95                                 $("." + action, this).on("click", e => {
96                                     self.$emit(action, data, dt, e)
97                                 })
98                             })
99                         })
100                 })
101             })
102         }
103     },
104     beforeUnmount() {
105         const dt = this.$refs.table.dt()
106         dt.destroy()
107     },
108     components: {
109         DataTable,
110     },
111     props: {
112         url: {
113             type: [String, Function],
114             default: "",
115         },
116         columns: {
117             type: Array,
118             default: [],
119         },
120         actions: {
121             type: Object,
122             default: {},
123         },
124         options: {
125             type: Object,
126             default: {},
127         },
128         default_filters: {
129             type: Object,
130             required: false,
131         },
132         table_settings: {
133             type: Object,
134             required: false,
135         },
136         default_search: {
137             type: String,
138             required: false,
139         },
140     },
141 }
142 </script>