Bug 32939: Uniformize api calls
[koha-ffzg.git] / koha-tmpl / intranet-tmpl / prog / js / vue / components / ERM / AgreementsList.vue
1 <template>
2     <div v-if="!initialized">{{ $__("Loading") }}</div>
3     <div v-else-if="agreements" id="agreements_list">
4         <Toolbar v-if="before_route_entered" />
5         <fieldset v-if="agreements.length" class="filters">
6             <label for="expired_filter">{{ $__("Filter by expired") }}:</label>
7             <input
8                 type="checkbox"
9                 id="expired_filter"
10                 v-model="filters.by_expired"
11                 @keyup.enter="filter_table"
12             />
13             {{ $__("on") }}
14             <flat-pickr
15                 id="max_expiration_date_filter"
16                 v-model="filters.max_expiration_date"
17                 :config="fp_config"
18             />
19
20             <input
21                 @click="filter_table"
22                 id="filter_table"
23                 type="button"
24                 :value="$__('Filter')"
25             />
26         </fieldset>
27         <div v-if="agreements.length" class="page-section">
28             <table :id="table_id"></table>
29         </div>
30         <div v-else-if="initialized" class="dialog message">
31             {{ $__("There are no agreements defined") }}
32         </div>
33     </div>
34 </template>
35
36 <script>
37 import flatPickr from "vue-flatpickr-component"
38 import Toolbar from "./AgreementsToolbar.vue"
39 import { inject, createVNode, render } from "vue"
40 import { APIClient } from "../../fetch/api-client.js"
41 import { storeToRefs } from "pinia"
42 import { useDataTable, build_url } from "../../composables/datatables"
43
44 export default {
45     setup() {
46         const vendorStore = inject("vendorStore")
47         const { vendors } = storeToRefs(vendorStore)
48
49         const AVStore = inject("AVStore")
50         const { get_lib_from_av, map_av_dt_filter } = AVStore
51
52         const table_id = "agreement_list"
53         useDataTable(table_id)
54
55         return {
56             vendors,
57             get_lib_from_av,
58             map_av_dt_filter,
59             table_id,
60         }
61     },
62     data: function () {
63         return {
64             fp_config: flatpickr_defaults,
65             agreements: [],
66             initialized: false,
67             filters: {
68                 by_expired: this.$route.query.by_expired || false,
69                 max_expiration_date:
70                     this.$route.query.max_expiration_date || "",
71             },
72             before_route_entered: false,
73             building_table: false,
74         }
75     },
76     beforeRouteEnter(to, from, next) {
77         next(vm => {
78             vm.before_route_entered = true // FIXME This is ugly, but we need to distinguish when it's used as main component or child component (from EHoldingsEBSCOPAckagesShow for instance)
79             if (!vm.building_table) {
80                 vm.building_table = true
81                 vm.getAgreements().then(() => vm.build_datatable())
82             }
83         })
84     },
85     computed: {
86         datatable_url() {
87             let url = "/api/v1/erm/agreements"
88             if (this.filters.by_expired)
89                 url +=
90                     "?max_expiration_date=" + this.filters.max_expiration_date
91             return url
92         },
93     },
94     methods: {
95         async getAgreements() {
96             const client = APIClient.erm
97             await client.agreements.getAll().then(
98                 data => {
99                     this.agreements = data
100                     this.initialized = true
101                 },
102                 error => {}
103             )
104         },
105         show_agreement: function (agreement_id) {
106             this.$router.push("/cgi-bin/koha/erm/agreements/" + agreement_id)
107         },
108         edit_agreement: function (agreement_id) {
109             this.$router.push(
110                 "/cgi-bin/koha/erm/agreements/edit/" + agreement_id
111             )
112         },
113         delete_agreement: function (agreement_id) {
114             this.$router.push(
115                 "/cgi-bin/koha/erm/agreements/delete/" + agreement_id
116             )
117         },
118         select_agreement: function (agreement_id) {
119             this.$emit("select-agreement", agreement_id)
120             this.$emit("close")
121         },
122         filter_table: async function () {
123             if (this.before_route_entered) {
124                 let new_route = build_url(
125                     "/cgi-bin/koha/erm/agreements",
126                     this.filters
127                 )
128                 this.$router.push(new_route)
129             }
130             if (this.filters.by_expired) {
131                 if (!this.filters.max_expiration_date)
132                     this.filters.max_expiration_date = new Date()
133                         .toISOString()
134                         .substring(0, 10)
135             }
136             $("#" + this.table_id)
137                 .DataTable()
138                 .ajax.url(this.datatable_url)
139                 .draw()
140         },
141         table_url: function () {},
142         build_datatable: function () {
143             let show_agreement = this.show_agreement
144             let edit_agreement = this.edit_agreement
145             let delete_agreement = this.delete_agreement
146             let select_agreement = this.select_agreement
147             let get_lib_from_av = this.get_lib_from_av
148             let map_av_dt_filter = this.map_av_dt_filter
149             let datatable_url = this.datatable_url
150             let default_search = this.$route.query.q
151             let actions = this.before_route_entered ? "edit_delete" : "select"
152             let table_id = this.table_id
153
154             window["vendors"] = this.vendors.map(e => {
155                 e["_id"] = e["id"]
156                 e["_str"] = e["name"]
157                 return e
158             })
159             let vendors_map = this.vendors.reduce((map, e) => {
160                 map[e.id] = e
161                 return map
162             }, {})
163             let avs = [
164                 "av_agreement_statuses",
165                 "av_agreement_closure_reasons",
166                 "av_agreement_renewal_priorities",
167             ]
168             avs.forEach(function (av_cat) {
169                 window[av_cat] = map_av_dt_filter(av_cat)
170             })
171
172             window["av_agreement_is_perpetual"] = [
173                 { _id: 0, _str: _("No") },
174                 { _id: 1, _str: _("Yes") },
175             ]
176
177             const table = $("#" + table_id).kohaTable(
178                 {
179                     ajax: {
180                         url: datatable_url,
181                     },
182                     order: [[0, "asc"]],
183                     autoWidth: false,
184                     search: { search: default_search },
185                     columnDefs: [
186                         {
187                             targets: [0, 2],
188                             render: function (data, type, row, meta) {
189                                 if (type == "display") {
190                                     return escape_str(data)
191                                 }
192                                 return data
193                             },
194                         },
195                     ],
196                     columns: [
197                         {
198                             title: __("Name"),
199                             data: "me.agreement_id:me.name",
200                             searchable: true,
201                             orderable: true,
202                             render: function (data, type, row, meta) {
203                                 // Rendering done in drawCallback
204                                 return ""
205                             },
206                         },
207                         {
208                             title: __("Vendor"),
209                             data: "vendor_id",
210                             searchable: true,
211                             orderable: true,
212                             render: function (data, type, row, meta) {
213                                 return row.vendor_id != undefined
214                                     ? escape_str(
215                                           vendors_map[row.vendor_id].name
216                                       )
217                                     : ""
218                             },
219                         },
220                         {
221                             title: __("Description"),
222                             data: "description",
223                             searchable: true,
224                             orderable: true,
225                         },
226                         {
227                             title: __("Status"),
228                             data: "status",
229                             searchable: true,
230                             orderable: true,
231                             render: function (data, type, row, meta) {
232                                 return escape_str(
233                                     get_lib_from_av(
234                                         "av_agreement_statuses",
235                                         row.status
236                                     )
237                                 )
238                             },
239                         },
240                         {
241                             title: __("Closure reason"),
242                             data: "closure_reason",
243                             searchable: true,
244                             orderable: true,
245                             render: function (data, type, row, meta) {
246                                 return escape_str(
247                                     get_lib_from_av(
248                                         "av_agreement_closure_reasons",
249                                         row.closure_reason
250                                     )
251                                 )
252                             },
253                         },
254                         {
255                             title: __("Is perpetual"),
256                             data: "is_perpetual",
257                             searchable: true,
258                             orderable: true,
259                             render: function (data, type, row, meta) {
260                                 return escape_str(
261                                     row.is_perpetual ? _("Yes") : _("No")
262                                 )
263                             },
264                         },
265                         {
266                             title: __("Renewal priority"),
267                             data: "renewal_priority",
268                             searchable: true,
269                             orderable: true,
270                             render: function (data, type, row, meta) {
271                                 return escape_str(
272                                     get_lib_from_av(
273                                         "av_agreement_renewal_priorities",
274                                         row.renewal_priority
275                                     )
276                                 )
277                             },
278                         },
279                         {
280                             title: __("Actions"),
281                             data: function (row, type, val, meta) {
282                                 return '<div class="actions"></div>'
283                             },
284                             className: "actions noExport",
285                             searchable: false,
286                             orderable: false,
287                         },
288                     ],
289                     drawCallback: function (settings) {
290                         var api = new $.fn.dataTable.Api(settings)
291
292                         if (actions == "edit_delete") {
293                             $.each(
294                                 $(this).find("td .actions"),
295                                 function (index, e) {
296                                     let tr = $(this).parent().parent()
297                                     let agreement_id = api
298                                         .row(tr)
299                                         .data().agreement_id
300                                     let editButton = createVNode(
301                                         "a",
302                                         {
303                                             class: "btn btn-default btn-xs",
304                                             role: "button",
305                                             onClick: () => {
306                                                 edit_agreement(agreement_id)
307                                             },
308                                         },
309                                         [
310                                             createVNode("i", {
311                                                 class: "fa fa-pencil",
312                                                 "aria-hidden": "true",
313                                             }),
314                                             __("Edit"),
315                                         ]
316                                     )
317
318                                     let deleteButton = createVNode(
319                                         "a",
320                                         {
321                                             class: "btn btn-default btn-xs",
322                                             role: "button",
323                                             onClick: () => {
324                                                 delete_agreement(agreement_id)
325                                             },
326                                         },
327                                         [
328                                             createVNode("i", {
329                                                 class: "fa fa-trash",
330                                                 "aria-hidden": "true",
331                                             }),
332                                             __("Delete"),
333                                         ]
334                                     )
335
336                                     let n = createVNode("span", {}, [
337                                         editButton,
338                                         " ",
339                                         deleteButton,
340                                     ])
341                                     render(n, e)
342                                 }
343                             )
344                         } else {
345                             $.each(
346                                 $(this).find("td .actions"),
347                                 function (index, e) {
348                                     let tr = $(this).parent().parent()
349                                     let agreement_id = api
350                                         .row(tr)
351                                         .data().agreement_id
352                                     let selectButton = createVNode(
353                                         "a",
354                                         {
355                                             class: "btn btn-default btn-xs",
356                                             role: "button",
357                                             onClick: () => {
358                                                 select_agreement(agreement_id)
359                                             },
360                                         },
361                                         [
362                                             createVNode("i", {
363                                                 class: "fa fa-check",
364                                                 "aria-hidden": "true",
365                                             }),
366                                             __("Select"),
367                                         ]
368                                     )
369
370                                     let n = createVNode("span", {}, [
371                                         selectButton,
372                                     ])
373                                     render(n, e)
374                                 }
375                             )
376                         }
377
378                         $.each(
379                             $(this).find("tbody tr td:first-child"),
380                             function (index, e) {
381                                 let tr = $(this).parent()
382                                 let row = api.row(tr).data()
383                                 if (!row) return // Happen if the table is empty
384                                 let n = createVNode(
385                                     "a",
386                                     {
387                                         role: "button",
388                                         onClick: () => {
389                                             show_agreement(row.agreement_id)
390                                         },
391                                     },
392                                     `${row.name} (#${row.agreement_id})`
393                                 )
394                                 render(n, e)
395                             }
396                         )
397                     },
398                     preDrawCallback: function (settings) {
399                         $("#" + table_id)
400                             .find("thead th")
401                             .eq(1)
402                             .attr("data-filter", "vendors")
403                         $("#" + table_id)
404                             .find("thead th")
405                             .eq(3)
406                             .attr("data-filter", "av_agreement_statuses")
407                         $("#" + table_id)
408                             .find("thead th")
409                             .eq(4)
410                             .attr("data-filter", "av_agreement_closure_reasons")
411                         $("#" + table_id)
412                             .find("thead th")
413                             .eq(5)
414                             .attr("data-filter", "av_agreement_is_perpetual")
415                         $("#" + table_id)
416                             .find("thead th")
417                             .eq(6)
418                             .attr(
419                                 "data-filter",
420                                 "av_agreement_renewal_priorities"
421                             )
422                     },
423                 },
424                 agreement_table_settings,
425                 1
426             )
427         },
428     },
429     mounted() {
430         if (!this.building_table) {
431             this.building_table = true
432             this.getAgreements().then(() => this.build_datatable())
433         }
434     },
435     components: { flatPickr, Toolbar },
436     name: "AgreementsList",
437     emits: ["select-agreement", "close"],
438 }
439 </script>
440
441 <style scoped>
442 #agreement_list {
443     display: table;
444 }
445 .filters > input[type="checkbox"],
446 .filters > input[type="button"] {
447     margin-left: 1rem;
448 }
449 </style>