2 <div v-if="!initialized">{{ $__("Loading") }}</div>
3 <div v-else id="agreements_list">
4 <Toolbar v-if="before_route_entered" />
5 <fieldset v-if="agreement_count > 0" class="filters">
6 <label for="expired_filter">{{ $__("Filter by expired") }}:</label>
10 v-model="filters.by_expired"
11 @keyup.enter="filter_table"
15 id="max_expiration_date_filter"
16 v-model="filters.max_expiration_date"
20 <label for="by_mine_filter">{{ $__("Show mine only") }}:</label>
24 v-model="filters.by_mine"
25 @keyup.enter="filter_table"
32 :value="$__('Filter')"
35 <div v-if="agreement_count > 0" class="page-section">
36 <table :id="table_id"></table>
38 <div v-else class="dialog message">
39 {{ $__("There are no agreements defined") }}
45 import flatPickr from "vue-flatpickr-component"
46 import Toolbar from "./AgreementsToolbar.vue"
47 import { inject, createVNode, render } from "vue"
48 import { APIClient } from "../../fetch/api-client.js"
49 import { storeToRefs } from "pinia"
50 import { useDataTable, build_url } from "../../composables/datatables"
54 const vendorStore = inject("vendorStore")
55 const { vendors } = storeToRefs(vendorStore)
57 const AVStore = inject("AVStore")
58 const { get_lib_from_av, map_av_dt_filter } = AVStore
60 const { setConfirmationDialog, setMessage } = inject("mainStore")
62 const table_id = "agreement_list"
63 useDataTable(table_id)
71 setConfirmationDialog,
77 fp_config: flatpickr_defaults,
81 by_expired: this.$route.query.by_expired || false,
83 this.$route.query.max_expiration_date || "",
84 by_mine: this.$route.query.by_mine || false,
86 before_route_entered: false,
87 building_table: false,
90 beforeRouteEnter(to, from, next) {
92 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)
93 if (!vm.building_table) {
94 vm.building_table = true
95 vm.getAgreementCount().then(() => vm.build_datatable())
101 let url = "/api/v1/erm/agreements"
102 if (this.filters.by_expired)
104 "?max_expiration_date=" + this.filters.max_expiration_date
109 async getAgreementCount() {
110 const client = APIClient.erm
111 await client.agreements.count().then(
113 this.agreement_count = count
114 this.initialized = true
119 show_agreement: function (agreement_id) {
120 this.$router.push("/cgi-bin/koha/erm/agreements/" + agreement_id)
122 edit_agreement: function (agreement_id) {
124 "/cgi-bin/koha/erm/agreements/edit/" + agreement_id
127 delete_agreement: function (agreement_id, agreement_name) {
128 this.setConfirmationDialog(
131 "Are you sure you want to remove this agreement?"
133 message: agreement_name,
134 accept_label: this.$__("Yes, delete"),
135 cancel_label: this.$__("No, do not delete"),
138 const client = APIClient.erm
139 client.agreements.delete(agreement_id).then(
142 this.$__("Agreement %s deleted").format(
154 select_agreement: function (agreement_id) {
155 this.$emit("select-agreement", agreement_id)
158 refresh_table: function () {
159 $("#" + this.table_id)
161 .ajax.url(this.datatable_url)
164 filter_table: async function () {
165 if (this.before_route_entered) {
166 let new_route = build_url(
167 "/cgi-bin/koha/erm/agreements",
170 this.$router.push(new_route)
172 if (this.filters.by_expired) {
173 if (!this.filters.max_expiration_date)
174 this.filters.max_expiration_date = new Date()
180 table_url: function () {},
181 build_datatable: function () {
182 let show_agreement = this.show_agreement
183 let edit_agreement = this.edit_agreement
184 let delete_agreement = this.delete_agreement
185 let select_agreement = this.select_agreement
186 let get_lib_from_av = this.get_lib_from_av
187 let map_av_dt_filter = this.map_av_dt_filter
188 let datatable_url = this.datatable_url
189 let default_search = this.$route.query.q
190 let actions = this.before_route_entered ? "edit_delete" : "select"
191 let filters = this.filters
192 let table_id = this.table_id
193 let logged_in_user = this.logged_in_user
195 window["vendors"] = this.vendors.map(e => {
197 e["_str"] = e["name"]
200 let vendors_map = this.vendors.reduce((map, e) => {
205 "av_agreement_statuses",
206 "av_agreement_closure_reasons",
207 "av_agreement_renewal_priorities",
209 avs.forEach(function (av_cat) {
210 window[av_cat] = map_av_dt_filter(av_cat)
213 window["av_agreement_is_perpetual"] = [
214 { _id: 0, _str: _("No") },
215 { _id: 1, _str: _("Yes") },
218 let additional_filters = {
219 "user_roles.user_id": function () {
220 return filters.by_mine ? logged_in_user.borrowernumber : ""
223 const table = $("#" + table_id).kohaTable(
228 embed: ["user_roles"],
231 search: { search: default_search },
235 render: function (data, type, row, meta) {
236 if (type == "display") {
237 return escape_str(data)
246 data: "me.agreement_id:me.name",
249 render: function (data, type, row, meta) {
250 // Rendering done in drawCallback
259 render: function (data, type, row, meta) {
260 return row.vendor_id != undefined
262 vendors_map[row.vendor_id].name
268 title: __("Description"),
278 render: function (data, type, row, meta) {
281 "av_agreement_statuses",
288 title: __("Closure reason"),
289 data: "closure_reason",
292 render: function (data, type, row, meta) {
295 "av_agreement_closure_reasons",
302 title: __("Is perpetual"),
303 data: "is_perpetual",
306 render: function (data, type, row, meta) {
308 row.is_perpetual ? _("Yes") : _("No")
313 title: __("Renewal priority"),
314 data: "renewal_priority",
317 render: function (data, type, row, meta) {
320 "av_agreement_renewal_priorities",
327 title: __("Actions"),
328 data: function (row, type, val, meta) {
329 return '<div class="actions"></div>'
331 className: "actions noExport",
336 drawCallback: function (settings) {
337 var api = new $.fn.dataTable.Api(settings)
339 if (actions == "edit_delete") {
341 $(this).find("td .actions"),
342 function (index, e) {
343 let tr = $(this).parent().parent()
344 let agreement_id = api
347 let agreement_name = api.row(tr).data().name
348 let editButton = createVNode(
351 class: "btn btn-default btn-xs",
354 edit_agreement(agreement_id)
359 class: "fa fa-pencil",
360 "aria-hidden": "true",
366 let deleteButton = createVNode(
369 class: "btn btn-default btn-xs",
380 class: "fa fa-trash",
381 "aria-hidden": "true",
387 let n = createVNode("span", {}, [
397 $(this).find("td .actions"),
398 function (index, e) {
399 let tr = $(this).parent().parent()
400 let agreement_id = api
403 let selectButton = createVNode(
406 class: "btn btn-default btn-xs",
409 select_agreement(agreement_id)
414 class: "fa fa-check",
415 "aria-hidden": "true",
421 let n = createVNode("span", {}, [
430 $(this).find("tbody tr td:first-child"),
431 function (index, e) {
432 let tr = $(this).parent()
433 let row = api.row(tr).data()
434 if (!row) return // Happen if the table is empty
440 show_agreement(row.agreement_id)
443 `${row.name} (#${row.agreement_id})`
449 preDrawCallback: function (settings) {
453 .attr("data-filter", "vendors")
457 .attr("data-filter", "av_agreement_statuses")
461 .attr("data-filter", "av_agreement_closure_reasons")
465 .attr("data-filter", "av_agreement_is_perpetual")
471 "av_agreement_renewal_priorities"
475 agreement_table_settings,
482 if (!this.building_table) {
483 this.building_table = true
484 this.getAgreementCount().then(() => this.build_datatable())
487 components: { flatPickr, Toolbar },
488 name: "AgreementsList",
489 emits: ["select-agreement", "close"],
497 .filters > label[for="by_mine_filter"],
498 .filters > input[type="checkbox"],
499 .filters > input[type="button"] {