Bug 30708: Display AV descriptions instead of codes
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / vue / components / Preservation / TrainsShow.vue
1 <template>
2     <transition name="modal">
3         <div v-if="show_modal" class="modal">
4             <h2>{{ $__("Copy item to the following train") }}</h2>
5             <form @submit="copyItem($event)">
6                 <div class="page-section">
7                     <fieldset class="rows">
8                         <ol>
9                             <li>
10                                 <label class="required" for="train_list"
11                                     >{{ $__("Select a train") }}:</label
12                                 >
13                                 <v-select
14                                     v-model="train_id_selected_for_copy"
15                                     label="name"
16                                     :options="train_list"
17                                     :reduce="t => t.train_id"
18                                 >
19                                     <template #search="{ attributes, events }">
20                                         <input
21                                             :required="
22                                                 !train_id_selected_for_copy
23                                             "
24                                             class="vs__search"
25                                             v-bind="attributes"
26                                             v-on="events"
27                                         />
28                                     </template>
29                                 </v-select>
30                                 <span class="required">{{
31                                     $__("Required")
32                                 }}</span>
33                             </li>
34                         </ol>
35                     </fieldset>
36                     <fieldset class="action">
37                         <input type="submit" value="Copy" />
38                         <input
39                             type="button"
40                             @click="show_modal = false"
41                             :value="$__('Close')"
42                         />
43                     </fieldset>
44                 </div>
45             </form>
46         </div>
47     </transition>
48     <div v-if="!initialized">{{ $__("Loading") }}</div>
49     <div v-else id="trains_show">
50         <div id="toolbar" class="btn-toolbar">
51             <router-link
52                 v-if="train.closed_on == null"
53                 :to="`/cgi-bin/koha/preservation/trains/${train.train_id}/items/add`"
54                 class="btn btn-default"
55                 ><font-awesome-icon icon="plus" />
56                 {{ $__("Add items") }}</router-link
57             >
58             <span
59                 v-else
60                 class="btn btn-default"
61                 disabled="disabled"
62                 :title="$__('Cannot add items to a closed train')"
63             >
64                 <font-awesome-icon icon="plus" /> {{ $__("Add items") }}
65             </span>
66             <router-link
67                 :to="`/cgi-bin/koha/preservation/trains/edit/${train.train_id}`"
68                 class="btn btn-default"
69                 ><font-awesome-icon icon="pencil" />
70                 {{ $__("Edit") }}</router-link
71             >
72             <a @click="deleteTrain(train)" class="btn btn-default"
73                 ><font-awesome-icon icon="trash" /> {{ $__("Delete") }}</a
74             >
75             <a
76                 v-if="!train.closed_on"
77                 class="btn btn-default"
78                 @click="closeTrain"
79                 ><font-awesome-icon icon="remove" /> {{ $__("Close") }}</a
80             >
81             <a
82                 v-else-if="!train.sent_on"
83                 class="btn btn-default"
84                 @click="sendTrain"
85                 ><font-awesome-icon icon="paper-plane" /> {{ $__("Send") }}</a
86             >
87             <a
88                 v-else-if="!train.received_on"
89                 class="btn btn-default"
90                 @click="receiveTrain"
91                 ><font-awesome-icon icon="inbox" /> {{ $__("Receive") }}</a
92             >
93         </div>
94         <h2>
95             {{ $__("Train #%s").format(train.train_id) }}
96         </h2>
97         <div>
98             <fieldset class="rows">
99                 <ol>
100                     <li>
101                         <label>{{ $__("Name") }}:</label>
102                         <span>
103                             {{ train.name }}
104                         </span>
105                     </li>
106                     <li>
107                         <label>{{ $__("Description") }}:</label>
108                         <span>
109                             {{ train.description }}
110                         </span>
111                     </li>
112                     <li v-if="train.closed_on">
113                         <label>{{ $__("Closed on") }}:</label>
114                         <span>
115                             {{ format_date(train.closed_on) }}
116                         </span>
117                     </li>
118                     <li v-if="train.sent_on">
119                         <label>{{ $__("Sent on") }}:</label>
120                         <span>
121                             {{ format_date(train.sent_on) }}
122                         </span>
123                     </li>
124                     <li v-if="train.received_on">
125                         <label>{{ $__("Received on") }}:</label>
126                         <span>
127                             {{ format_date(train.received_on) }}
128                         </span>
129                     </li>
130                     <li>
131                         <label
132                             >{{
133                                 $__("Status for item added to this train")
134                             }}:</label
135                         >
136                         <span>{{
137                             get_lib_from_av("av_notforloan", train.not_for_loan)
138                         }}</span>
139                     </li>
140                     <li>
141                         <label>{{ $__("Default processing") }}:</label>
142                         <span>
143                             {{ train.default_processing.name }}
144                         </span>
145                     </li>
146                 </ol>
147             </fieldset>
148             <fieldset v-if="train.items.length" class="rows">
149                 <legend>{{ $__("Items") }}</legend>
150                 <table v-if="item_table.display" :id="table_id"></table>
151                 <ol v-else>
152                     <li
153                         :id="`item_${counter}`"
154                         class="rows"
155                         v-for="(item, counter) in train.items"
156                         v-bind:key="counter"
157                     >
158                         <label
159                             >{{ item.user_train_item_id }}
160                             <span class="action_links">
161                                 <router-link
162                                     :to="`/cgi-bin/koha/preservation/trains/${train.train_id}/items/edit/${item.train_item_id}`"
163                                     :title="$__('Edit')"
164                                     ><i class="fa fa-pencil"></i></router-link
165                             ></span>
166                         </label>
167                         <div class="attributes_values">
168                             <span
169                                 :id="`attribute_${counter_attribute}`"
170                                 class="attribute_value"
171                                 v-for="(
172                                     attribute, counter_attribute
173                                 ) in item.attributes"
174                                 v-bind:key="counter_attribute"
175                             >
176                                 {{ attribute.processing_attribute.name }}={{
177                                     attribute._strings.value.str
178                                 }}
179                             </span>
180                         </div>
181                     </li>
182                 </ol>
183             </fieldset>
184             <fieldset class="action">
185                 <router-link
186                     to="/cgi-bin/koha/preservation/trains"
187                     role="button"
188                     class="cancel"
189                     >{{ $__("Close") }}</router-link
190                 >
191             </fieldset>
192         </div>
193     </div>
194 </template>
195
196 <script>
197 import { inject, createVNode, render } from "vue"
198 import { APIClient } from "../../fetch/api-client"
199 import { useDataTable } from "../../composables/datatables"
200
201 export default {
202     setup() {
203         const format_date = $date
204
205         const AVStore = inject("AVStore")
206         const { get_lib_from_av } = AVStore
207
208         const { setConfirmationDialog, setMessage, setWarning } =
209             inject("mainStore")
210
211         const table_id = "item_list"
212         useDataTable(table_id)
213
214         return {
215             format_date,
216             get_lib_from_av,
217             table_id,
218             setConfirmationDialog,
219             setMessage,
220             setWarning,
221         }
222     },
223     data() {
224         return {
225             train: {
226                 train_id: null,
227                 name: "",
228                 description: "",
229             },
230             initialized: false,
231             show_modal: false,
232             item_table: {
233                 display: false,
234                 data: [],
235                 columns: [],
236             },
237             train_list: [],
238             train_id_selected_for_copy: null,
239             train_item_id_to_copy: null,
240             av_options: {},
241         }
242     },
243     beforeRouteEnter(to, from, next) {
244         next(vm => {
245             vm.getTrain(to.params.train_id).then(() => vm.build_datatable())
246             vm.getTrainList()
247         })
248     },
249     methods: {
250         async getTrain(train_id) {
251             const client = APIClient.preservation
252             await client.trains.get(train_id).then(
253                 train => {
254                     this.train = train
255                     let display_table = this.train.items.every(
256                         item =>
257                             item.processing_id ==
258                             this.train.default_processing_id
259                     )
260                     if (display_table) {
261                         this.item_table.data = []
262                         this.train.items.forEach(item => {
263                             let item_row = {}
264                             this.train.default_processing.attributes.forEach(
265                                 attribute => {
266                                     item_row[
267                                         attribute.processing_attribute_id
268                                     ] = item.attributes
269                                         .filter(
270                                             a =>
271                                                 a.processing_attribute_id ==
272                                                 attribute.processing_attribute_id
273                                         )
274                                         .map(a => a._strings.value.str)
275                                 }
276                             )
277                             item_row.item = item
278                             this.item_table.data.push(item_row)
279                         })
280                         this.item_table.columns = []
281                         this.item_table.columns.push({
282                             name: "",
283                             title: this.$__("ID"),
284                             data: "item.user_train_item_id",
285                         })
286                         train.default_processing.attributes.forEach(a =>
287                             this.item_table.columns.push({
288                                 name: a.name,
289                                 title: a.name,
290                                 data: a.processing_attribute_id,
291                                 render: (data, type, row) => {
292                                     return data.join("<br/>")
293                                 },
294                             })
295                         )
296                         this.item_table.columns.push({
297                             name: "actions",
298                             className: "actions noExport",
299                             title: this.$__("Actions"),
300                             searchable: false,
301                             orderable: false,
302                             render: (data, type, row) => {
303                                 return ""
304                             },
305                         })
306                     }
307                     this.initialized = true
308                     this.item_table.display = display_table
309                 },
310                 error => {}
311             )
312         },
313         getTrainList: function () {
314             const client = APIClient.preservation
315             let q = { "me.closed_on": null }
316             client.trains.getAll(q).then(
317                 trains => (this.train_list = trains),
318                 error => {}
319             )
320         },
321         deleteTrain: function (train) {
322             this.setConfirmationDialog(
323                 {
324                     title: this.$__(
325                         "Are you sure you want to remove this train?"
326                     ),
327                     message: train.name,
328                     accept_label: this.$__("Yes, delete"),
329                     cancel_label: this.$__("No, do not delete"),
330                 },
331                 () => {
332                     const client = APIClient.preservation
333                     client.trains.delete(train.train_id).then(
334                         success => {
335                             this.setMessage(
336                                 this.$__("Train %s deleted").format(train.name),
337                                 true
338                             )
339                         },
340                         error => {}
341                     )
342                 }
343             )
344         },
345         async updateTrainDate(attribute) {
346             let train = JSON.parse(JSON.stringify(this.train))
347             let train_id = train.train_id
348             delete train.train_id
349             delete train.items
350             delete train.default_processing
351             train[attribute] = new Date()
352             const client = APIClient.preservation
353             if (train_id) {
354                 return client.trains
355                     .update(train, train_id)
356                     .then(() => this.getTrain(this.train.train_id))
357             } else {
358                 return client.trains
359                     .create(train)
360                     .then(() => this.getTrain(this.train.train_id))
361             }
362         },
363         closeTrain() {
364             this.updateTrainDate("closed_on")
365         },
366         sendTrain() {
367             this.updateTrainDate("sent_on")
368         },
369         receiveTrain() {
370             this.updateTrainDate("received_on").then(
371                 success => {
372                     // Rebuild the table to show the "copy" button
373                     $("#" + this.table_id)
374                         .DataTable()
375                         .destroy()
376                     this.build_datatable()
377                 },
378                 error => {}
379             )
380         },
381         editItem(train_item_id) {
382             this.$router.push(
383                 `/cgi-bin/koha/preservation/trains/${this.train.train_id}/items/edit/${train_item_id}`
384             )
385         },
386         removeItem(train_item_id) {
387             this.setConfirmationDialog(
388                 {
389                     title: this.$__(
390                         "Are you sure you want to remove this item?"
391                     ),
392                     accept_label: this.$__("Yes, remove"),
393                     cancel_label: this.$__("No, do not remove"),
394                 },
395                 () => {
396                     const client = APIClient.preservation
397                     client.train_items
398                         .delete(this.train.train_id, train_item_id)
399                         .then(
400                             success => {
401                                 this.setMessage(this.$__("Item removed"), true)
402                                 this.getTrain(this.train.train_id).then(() => {
403                                     $("#" + this.table_id)
404                                         .DataTable()
405                                         .destroy()
406                                     this.build_datatable()
407                                 })
408                             },
409                             error => {}
410                         )
411                 }
412             )
413         },
414         selectTrainForCopy(train_item_id) {
415             this.show_modal = true
416             this.train_item_id_to_copy = train_item_id
417         },
418         copyItem(event) {
419             event.preventDefault()
420             const client = APIClient.preservation
421             client.train_items
422                 .copy(
423                     this.train_id_selected_for_copy,
424                     this.train.train_id,
425                     this.train_item_id_to_copy
426                 )
427                 .then(
428                     success => {
429                         this.setMessage(this.$__("Item copied successfully."))
430                         this.show_modal = false
431                     },
432                     error => {
433                         this.setWarning(
434                             this.$__(
435                                 "Item cannot be copied to a train, it is already in a non-received train."
436                             )
437                         )
438                     }
439                 )
440         },
441         build_datatable: function () {
442             let table_id = this.table_id
443             let item_table = this.item_table
444             let removeItem = this.removeItem
445             let editItem = this.editItem
446             let selectTrainForCopy = this.selectTrainForCopy
447             let train = this.train
448
449             let table = KohaTable(table_id, {
450                 data: item_table.data,
451                 ordering: false,
452                 autoWidth: false,
453                 columns: item_table.columns,
454                 drawCallback: function (settings) {
455                     var api = new $.fn.dataTable.Api(settings)
456                     $.each($(this).find("td.actions"), function (index, e) {
457                         let tr = $(this).parent()
458                         let train_item_id = api.row(tr).data()
459                             .item.train_item_id
460
461                         let editButton = createVNode(
462                             "a",
463                             {
464                                 class: "btn btn-default btn-xs",
465                                 role: "button",
466                                 onClick: () => {
467                                     editItem(train_item_id)
468                                 },
469                             },
470                             [
471                                 createVNode("i", {
472                                     class: "fa fa-pencil",
473                                     "aria-hidden": "true",
474                                 }),
475                                 __("Edit"),
476                             ]
477                         )
478
479                         let removeButton = createVNode(
480                             "a",
481                             {
482                                 class: "btn btn-default btn-xs",
483                                 role: "button",
484                                 onClick: () => {
485                                     removeItem(train_item_id)
486                                 },
487                             },
488                             [
489                                 createVNode("i", {
490                                     class: "fa fa-trash",
491                                     "aria-hidden": "true",
492                                 }),
493                                 __("Remove"),
494                             ]
495                         )
496                         let buttons = [editButton, "", removeButton]
497
498                         if (train.received_on !== null) {
499                             buttons.push("")
500                             buttons.push(
501                                 createVNode(
502                                     "a",
503                                     {
504                                         class: "btn btn-default btn-xs",
505                                         role: "button",
506                                         onClick: () => {
507                                             selectTrainForCopy(train_item_id)
508                                         },
509                                     },
510                                     [
511                                         createVNode("i", {
512                                             class: "fa fa-copy",
513                                             "aria-hidden": "true",
514                                         }),
515                                         __("Copy"),
516                                     ]
517                                 )
518                             )
519                         }
520
521                         let n = createVNode("span", {}, buttons)
522                         render(n, e)
523                     })
524                 },
525             })
526         },
527     },
528     name: "TrainsShow",
529 }
530 </script>
531 <style scoped>
532 .action_links a {
533     padding-left: 0.2em;
534     font-size: 11px;
535 }
536 .attributes_values {
537     float: left;
538 }
539 .attribute_value {
540     display: block;
541 }
542 .modal {
543     position: fixed;
544     z-index: 9998;
545     top: 0;
546     left: 0;
547     width: 35%;
548     height: 30%;
549     background-color: rgba(0, 0, 0, 0.5);
550     display: table;
551     transition: opacity 0.3s ease;
552     margin: auto;
553     padding: 20px 30px;
554     background-color: #fff;
555     border-radius: 2px;
556     box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
557     transition: all 0.3s ease;
558 }
559 </style>