View | Details | Raw Unified | Return to bug 41249
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/ill-batch-modal-strings.inc (+1 lines)
Lines 14-19 Link Here
14
    var ill_populate_waiting = _("Retrieving...");
14
    var ill_populate_waiting = _("Retrieving...");
15
    var ill_populate_failed = _("Failed to retrieve");
15
    var ill_populate_failed = _("Failed to retrieve");
16
    var ill_button_remove = _("Remove");
16
    var ill_button_remove = _("Remove");
17
    var ill_batch_request_creating = _("Creating...");
17
    var ill_batch_create_api_fail = _("Unable to create batch request");
18
    var ill_batch_create_api_fail = _("Unable to create batch request");
18
    var ill_batch_update_api_fail = _("Unable to update batch request");
19
    var ill_batch_update_api_fail = _("Unable to update batch request");
19
    var ill_batch_item_remove = _("Are you sure you want to remove this item from the batch?");
20
    var ill_batch_item_remove = _("Are you sure you want to remove this item from the batch?");
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/ill-batch-modal.inc (+3 lines)
Lines 71-76 Link Here
71
                                [% IF Koha.Preference('ILLCheckAvailability') %]
71
                                [% IF Koha.Preference('ILLCheckAvailability') %]
72
                                    <th scope="col">Availability</th>
72
                                    <th scope="col">Availability</th>
73
                                [% END %]
73
                                [% END %]
74
                                [% IF Koha.Preference('AutoILLBackendPriority') %]
75
                                    <th scope="col">Auto backend</th>
76
                                [% END %]
74
                                <th scope="col"></th>
77
                                <th scope="col"></th>
75
                            </tr>
78
                            </tr>
76
                        </thead>
79
                        </thead>
(-)a/koha-tmpl/intranet-tmpl/prog/js/ill-batch-modal.js (-7 / +179 lines)
Lines 10-15 Link Here
10
    // Delay between API requests
10
    // Delay between API requests
11
    var debounceDelay = 1000;
11
    var debounceDelay = 1000;
12
12
13
    // Global var to determine if requests are being created
14
    var creatingRequests = false;
15
13
    // Elements we work frequently with
16
    // Elements we work frequently with
14
    var textarea = document.getElementById("identifiers_input");
17
    var textarea = document.getElementById("identifiers_input");
15
    var nameInput = document.getElementById("name");
18
    var nameInput = document.getElementById("name");
Lines 233-248 Link Here
233
        createRequestsButton.setAttribute("disabled", true);
236
        createRequestsButton.setAttribute("disabled", true);
234
        createRequestsButton.setAttribute("aria-disabled", true);
237
        createRequestsButton.setAttribute("aria-disabled", true);
235
        setFinishButton();
238
        setFinishButton();
236
        var toCheck = tableContent.data;
239
        const toCheck = tableContent.data;
237
        toCheck.forEach(function (row) {
240
        const promises = [];
241
242
        creatingRequests = true;
243
        toCheck.forEach(function (row, i) {
238
            if (
244
            if (
239
                !row.requestId &&
245
                !row.requestId &&
240
                Object.keys(row.metadata).length > 0 &&
246
                Object.keys(row.metadata).length > 0 &&
241
                !submissionSent[row.value]
247
                !submissionSent[row.value]
242
            ) {
248
            ) {
243
                submissionSent[row.value] = 1;
249
                submissionSent[row.value] = 1;
244
                makeLocalSubmission(row.value, row.metadata);
250
                promises.push(makeLocalSubmission(row.value, row.metadata, i));
251
            }
252
        });
253
        Promise.all(promises).then(() => {
254
            creatingRequests = false;
255
        });
256
    }
257
258
    async function populateAutoILL(row) {
259
        let metadata = row.metadata;
260
        metadata.branchcode = batch.data.library_id;
261
        metadata.cardnumber = batch.data.cardnumber;
262
        var prepped = encodeURIComponent(
263
            base64EncodeUnicode(JSON.stringify(metadata))
264
        );
265
266
        const withTimeout = (promise, backendName) =>
267
            Promise.race([
268
                promise,
269
                new Promise(resolve =>
270
                    setTimeout(
271
                        () =>
272
                            resolve({
273
                                name: backendName,
274
                                error: "Verification timed out",
275
                            }),
276
                        10000
277
                    )
278
                ),
279
            ]);
280
281
        const fetchPromises = have_batch_auto_backends.map(backend =>
282
            withTimeout(
283
                fetch(backend.endpoint + prepped)
284
                    .then(res => res.json())
285
                    .then(responseData => ({
286
                        name: backend.name,
287
                        success: responseData.success,
288
                        warning: responseData.warning,
289
                        error: responseData.error
290
                            ? responseData.error
291
                            : responseData.errors
292
                              ? responseData.errors
293
                                    .map(error => error.message)
294
                                    .join(", ")
295
                              : undefined,
296
                    })),
297
                backend.name
298
            )
299
        );
300
301
        return Promise.all(fetchPromises).then(results => {
302
            const firstSuccessIndex = results.findIndex(
303
                item => item.success === "" || !!item.success
304
            );
305
            results = results.map((item, i) => ({
306
                ...item,
307
                suggested: i === firstSuccessIndex ? 1 : 0,
308
            }));
309
            if (!results.some(item => item.suggested === 1)) {
310
                results.push({ name: "Standard", success: "", suggested: 1 });
311
            } else {
312
                results.push({ name: "Standard", success: "", suggested: 0 });
245
            }
313
            }
314
            return results;
246
        });
315
        });
247
    }
316
    }
248
317
Lines 296-302 Link Here
296
365
297
    // Create a local submission and update our local state
366
    // Create a local submission and update our local state
298
    // upon success
367
    // upon success
299
    function makeLocalSubmission(identifier, metadata) {
368
    function makeLocalSubmission(identifier, metadata, i) {
369
        const checked_backend = document.querySelector(
370
            `input[name="auto_backend_${i}"]:checked`
371
        );
372
        let selected_backend = checked_backend ? checked_backend.value : null;
373
300
        // Prepare extended_attributes in array format for POST
374
        // Prepare extended_attributes in array format for POST
301
        var extended_attributes = [];
375
        var extended_attributes = [];
302
        for (const [key, value] of Object.entries(metadata)) {
376
        for (const [key, value] of Object.entries(metadata)) {
Lines 305-316 Link Here
305
379
306
        var payload = {
380
        var payload = {
307
            ill_batch_id: batchId,
381
            ill_batch_id: batchId,
308
            ill_backend_id: batch.data.backend,
382
            ill_backend_id: selected_backend
383
                ? selected_backend
384
                : batch.data.backend,
309
            patron_id: batch.data.patron.patron_id,
385
            patron_id: batch.data.patron.patron_id,
310
            library_id: batch.data.library_id,
386
            library_id: batch.data.library_id,
311
            extended_attributes: extended_attributes,
387
            extended_attributes: extended_attributes,
312
        };
388
        };
313
        window
389
        return window
314
            .doCreateSubmission(payload)
390
            .doCreateSubmission(payload)
315
            .then(function (response) {
391
            .then(function (response) {
316
                return response.json();
392
                return response.json();
Lines 319-324 Link Here
319
                tableContent.data = tableContent.data.map(function (row) {
395
                tableContent.data = tableContent.data.map(function (row) {
320
                    if (row.value === identifier) {
396
                    if (row.value === identifier) {
321
                        row.requestId = data.ill_request_id;
397
                        row.requestId = data.ill_request_id;
398
                        row.ill_backend_id = data.ill_backend_id;
322
                        row.requestStatus = data.status;
399
                        row.requestStatus = data.status;
323
                    }
400
                    }
324
                    return row;
401
                    return row;
Lines 719-724 Link Here
719
                row.metadata = {};
796
                row.metadata = {};
720
                row.failed = {};
797
                row.failed = {};
721
                row.availability_hits = {};
798
                row.availability_hits = {};
799
                row.auto_backends = {};
722
                row.requestId = null;
800
                row.requestId = null;
723
                deduped.push(row);
801
                deduped.push(row);
724
            }
802
            }
Lines 781-786 Link Here
781
                    //do nothing
859
                    //do nothing
782
                }
860
                }
783
            }
861
            }
862
            if (have_batch_auto_backends.length) {
863
                try {
864
                    var request_auto_backends = await populateAutoILL(row);
865
                    row.auto_backends = request_auto_backends || {};
866
                } catch (e) {
867
                    //do nothing
868
                }
869
            }
784
870
785
            newData[i] = row;
871
            newData[i] = row;
786
            tableContent.data = newData;
872
            tableContent.data = newData;
Lines 1004-1009 Link Here
1004
        return data.requestStatus || "-";
1090
        return data.requestStatus || "-";
1005
    }
1091
    }
1006
1092
1093
    function createRequestAutoBackend(data, row_index) {
1094
        if (creatingRequests && !data.ill_backend_id) {
1095
            return ill_batch_request_creating;
1096
        }
1097
1098
        if (data.failed.length > 0) {
1099
            return data.failed;
1100
        }
1101
1102
        if (Object.keys(data.auto_backends).length === 0) {
1103
            return ill_populate_waiting;
1104
        }
1105
1106
        if (data.ill_backend_id) {
1107
            return "<strong>" + data.ill_backend_id + "</strong>";
1108
        }
1109
1110
        let html = data.auto_backends
1111
            .map((item, i) => {
1112
                const checked = item.suggested ? "checked" : "";
1113
                const disabled =
1114
                    data.ill_backend_id ||
1115
                    item.success === "" ||
1116
                    !!item.success ||
1117
                    item.warning === "" ||
1118
                    !!item.warning
1119
                        ? ""
1120
                        : "disabled";
1121
                const color =
1122
                    item.success === "" || !!item.success
1123
                        ? "green"
1124
                        : item.warning === "" || !!item.warning
1125
                          ? "#8a6804"
1126
                          : "red";
1127
                const statusIcon =
1128
                    item.success === "" || !!item.success
1129
                        ? '<i class="fa-solid fa-check"></i> '
1130
                        : item.error === "" || !!item.error
1131
                          ? '<i class="fa-solid fa-xmark"></i> '
1132
                          : item.warning === "" || !!item.warning
1133
                            ? '<i class="fa-solid fa-exclamation-circle"></i> '
1134
                            : "";
1135
                return `
1136
                <label style="color: ${color};">
1137
                    <input type="radio" name="auto_backend_${row_index}" value="${item.name}" ${checked} ${disabled}>
1138
                    <span class="d-inline-block text-center align-middle" style="width:1em;">
1139
                        ${statusIcon}
1140
                    </span>
1141
                     ${item.name}
1142
                </label>
1143
                ${
1144
                    item.success || item.warning || item.error
1145
                        ? `
1146
                <a href="#" data-bs-toggle="tooltip" style="color: ${color};"
1147
                title="${item.success || item.warning || item.error}">
1148
                <i class="fa-solid fa-circle-exclamation"></i>
1149
                </a>`
1150
                        : ""
1151
                }
1152
                <br>
1153
            `;
1154
            })
1155
            .join("");
1156
1157
        return html.trim();
1158
    }
1159
1007
    function createRequestAvailability(x, y, data) {
1160
    function createRequestAvailability(x, y, data) {
1008
        // If the fetch failed
1161
        // If the fetch failed
1009
        if (data.failed.length > 0) {
1162
        if (data.failed.length > 0) {
Lines 1035-1040 Link Here
1035
1188
1036
    function buildTable(identifiers) {
1189
    function buildTable(identifiers) {
1037
        table = $("#identifier-table").kohaTable({
1190
        table = $("#identifier-table").kohaTable({
1191
            drawCallback: function () {
1192
                const tooltipTriggerList = Array.from(
1193
                    document.querySelectorAll('[data-bs-toggle="tooltip"]')
1194
                );
1195
                tooltipTriggerList.forEach(el => new bootstrap.Tooltip(el));
1196
            },
1038
            processing: true,
1197
            processing: true,
1039
            ordering: false,
1198
            ordering: false,
1040
            paging: false,
1199
            paging: false,
Lines 1074-1079 Link Here
1074
                          },
1233
                          },
1075
                      ]
1234
                      ]
1076
                    : []),
1235
                    : []),
1236
                ...(have_batch_auto_backends.length
1237
                    ? [
1238
                          {
1239
                              data: "",
1240
                              width: "25%",
1241
                              render: function (data, type, row, meta) {
1242
                                  return createRequestAutoBackend(
1243
                                      row,
1244
                                      meta.row
1245
                                  );
1246
                              },
1247
                          },
1248
                      ]
1249
                    : []),
1077
                {
1250
                {
1078
                    width: "6.5%",
1251
                    width: "6.5%",
1079
                    render: createActions,
1252
                    render: createActions,
1080
- 

Return to bug 41249