Bug 33066: Restore HTML escaping
[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 import "datatables.net-buttons/js/buttons.colVis"
19 DataTable.use(DataTablesLib)
20
21 export default {
22     name: "KohaTable",
23     data() {
24         let hidden_ids, included_ids
25         ;[hidden_ids, included_ids] = _dt_visibility(
26             this.table_settings,
27             this.options
28         )
29         let buttons = _dt_buttons({
30             included_ids,
31             table_settings: this.table_settings,
32         })
33         return {
34             data: [],
35             tableColumns: this.columns,
36             allOptions: {
37                 deferRender: true,
38                 paging: true,
39                 serverSide: true,
40                 searching: true,
41                 pagingType: "full_numbers",
42                 processing: true,
43                 autoWidth: false,
44                 ajax: {
45                     url: typeof this.url === "function" ? this.url() : this.url,
46                     ..._dt_default_ajax({
47                         options: this.options,
48                         default_filters: this.default_filters,
49                     }),
50                 },
51                 buttons,
52                 search: { search: this.$route.query.q },
53                 columnDefs: [
54                     {
55                         targets: "_all",
56                         render: function (data, type, row, meta) {
57                             if (type == "display") {
58                                 return escape_str(data)
59                             }
60                             return data
61                         },
62                     },
63                 ],
64                 ...this.options,
65             },
66             hidden_ids,
67             included_ids,
68         }
69     },
70     setup() {
71         return { dataTablesDefaults }
72     },
73     methods: {
74         redraw: function (url) {
75             this.$refs.table.dt().ajax.url(url).draw()
76         },
77     },
78     beforeMount() {
79         if (this.actions.hasOwnProperty("-1")) {
80             this.tableColumns = [
81                 ...this.tableColumns,
82                 {
83                     name: "actions",
84                     title: this.$__("Actions"),
85                     searchable: false,
86                     render: (data, type, row) => {
87                         let content = []
88                         this.actions["-1"].forEach(a => {
89                             if (a == "edit") {
90                                 content.push(
91                                     '<a class="edit btn btn-default btn-xs" role="button"><i class="fa fa-pencil"></i>' +
92                                         this.$__("Edit") +
93                                         "</a>"
94                                 )
95                             } else if (a == "delete") {
96                                 content.push(
97                                     '<a class="delete btn btn-default btn-xs" role="button"><i class="fa fa-trash"></i>' +
98                                         this.$__("Delete") +
99                                         "</a>"
100                                 )
101                             }
102                         })
103                         return content.join(" ")
104                     },
105                 },
106             ]
107         }
108
109         $(
110             ".dt_button_clear_filter, .columns_controls, .export_controls, .dt_button_configure_table"
111         ).tooltip()
112
113         if (this.add_filters) {
114             this.options.orderCellsTop = true
115         }
116
117         if (this.table_settings) {
118             if (
119                 this.table_settings.hasOwnProperty("default_display_length") &&
120                 this.table_settings.default_display_length != null
121             ) {
122                 this.options.pageLength =
123                     this.table_settings.default_display_length
124             }
125             if (
126                 this.table_settings.hasOwnProperty("default_sort_order") &&
127                 this.table_settings.default_sort_order != null
128             ) {
129                 this.options.order = [
130                     [this.table_settings.default_sort_order, "asc"],
131                 ]
132             }
133         }
134     },
135     mounted() {
136         let dt = this.$refs.table.dt()
137         let table_node = dt.table().node()
138         let add_filters = this.add_filters
139         if (add_filters) {
140             _dt_add_filters(table_node, dt, this.filters_options)
141         }
142
143         dt.on("column-visibility.dt", function () {
144             _dt_on_visibility(add_filters, table_node, dt)
145         })
146             .columns(this.hidden_ids)
147             .visible(false)
148
149         if (Object.keys(this.actions).length) {
150             const self = this
151             dt.on("draw", () => {
152                 const dataSet = dt.rows().data()
153                 Object.entries(this.actions).forEach(([col_id, actions]) => {
154                     dt.column(col_id)
155                         .nodes()
156                         .to$()
157                         .each(function (idx) {
158                             const data = dataSet[idx]
159                             actions.forEach(action => {
160                                 $("." + action, this).on("click", e => {
161                                     self.$emit(action, data, dt, e)
162                                 })
163                             })
164                         })
165                 })
166             })
167         }
168     },
169     beforeUnmount() {
170         const dt = this.$refs.table.dt()
171         dt.destroy()
172     },
173     components: {
174         DataTable,
175     },
176     props: {
177         url: {
178             type: [String, Function],
179             default: "",
180         },
181         columns: {
182             type: Array,
183             default: [],
184         },
185         actions: {
186             type: Object,
187             default: {},
188         },
189         options: {
190             type: Object,
191             default: {},
192         },
193         default_filters: {
194             type: Object,
195             required: false,
196         },
197         table_settings: {
198             type: Object,
199             required: false,
200         },
201         add_filters: {
202             type: Boolean,
203             required: false,
204         },
205         filters_options: {
206             type: Object,
207             required: false,
208         },
209     },
210 }
211 </script>