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

(-)a/koha-tmpl/intranet-tmpl/prog/css/staff-global.css (+15 lines)
Lines 3052-3057 fieldset.rows + fieldset.action { Link Here
3052
    margin: 1em;
3052
    margin: 1em;
3053
}
3053
}
3054
3054
3055
#interlibraryloans #column-toggle,
3056
#interlibraryloans #reset-toggle {
3057
    margin: 15px 0;
3058
    line-height: 1.5em;
3059
    font-weight: 700;
3060
}
3061
3055
#ill-view-panel {
3062
#ill-view-panel {
3056
    margin-top: 15px;
3063
    margin-top: 15px;
3057
}
3064
}
Lines 3072-3074 fieldset.rows + fieldset.action { Link Here
3072
#ill-view-panel #requestattributes .label {
3079
#ill-view-panel #requestattributes .label {
3073
    width: auto;
3080
    width: auto;
3074
}
3081
}
3082
3083
table#ill-requests {
3084
    width: 100% !important;
3085
}
3086
3087
table#ill-requests th {
3088
    text-transform: capitalize;
3089
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt (-126 / +324 lines)
Lines 10-130 Link Here
10
<script type="text/javascript">
10
<script type="text/javascript">
11
    //<![CDATA[
11
    //<![CDATA[
12
    $(document).ready(function() {
12
    $(document).ready(function() {
13
        var myTable = $("#ill-requests").DataTable($.extend(true, {}, dataTablesDefaults, {
13
14
            "aoColumnDefs": [  // Last column shouldn't be sortable or searchable
14
        // Illview Datatable setup
15
                { "aTargets": [ -1 ], "bSortable": false, "bSearchable": false },
15
16
            ],
16
        // Fields we don't want to display
17
            "aaSorting": [[ 8, "desc" ]], // Default sort, updated descending
17
        var ignore = [
18
            "processing": true, // Display a message when manipulating
18
            'accessurl',
19
            "language": {
19
            'backend',
20
                "loadingRecords": "Please wait - loading requests...",
20
            'completed',
21
                "zeroRecords": "No requests were found"
21
            'branch',
22
            },
22
            'capabilities',
23
            "iDisplayLength": 10, // 10 results per page
23
            'cost',
24
            "sPaginationType": "full_numbers", // Pagination display
24
            'medium',
25
            "sAjaxDataProp": "", // Data is in the root object of the response
25
            'notesopac',
26
            "deferRender": true, // Improve performance on big datasets
26
            'notesstaff',
27
            "ajax": {
27
            'placed',
28
                url: "/api/v1/illrequests?embed=metadata,patron,capabilities,branch",
28
            'replied'
29
                cache: true
29
        ];
30
            },
30
31
            "columns": [
31
        // Fields we need to expand (flatten)
32
                {
32
        var expand = [
33
                    data: 'orderid',
33
            'metadata',
34
                    className: 'orderid'
34
            'patron'
35
                },
35
        ];
36
                {
36
37
                    render: function(data, type, row) {
37
        // Expanded fields
38
                        return (
38
        // This is auto populated
39
                            row.metadata.hasOwnProperty('Author') &&
39
        var expanded = {};
40
                            row.metadata.Author.length > 0
40
41
                        ) ? row.metadata.Author : 'N/A';
41
        // The core fields that should be displayed first
42
                    },
42
        var core = [
43
                    className: 'title'
43
            'metadata_Author',
44
                },
44
            'metadata_Title',
45
                {
45
            'borrowernumber',
46
                    render: function(data, type, row) {
46
            'biblio_id',
47
                        return (
47
            'branchcode',
48
                            row.metadata.hasOwnProperty('Title') &&
48
            'status',
49
                            row.metadata.Title.length > 0
49
            'updated',
50
                        ) ? row.metadata.Title : 'N/A';
50
            'illrequest_id',
51
                    },
51
            'action'
52
                    className: 'title'
52
        ];
53
                },
53
54
                {
54
        // Extra fields that we need to tack on to the end
55
                    render: function(data, type, row) {
55
        var extra = [ 'action' ];
56
                        return '<a title="View borrower details" ' +
56
57
                        'href="/cgi-bin/koha/members/moremember.pl?' +
57
        // Remove any fields we're ignoring
58
                        'borrowernumber='+row.borrowernumber+'">' +
58
        var removeIgnore = function(dataObj) {
59
                        row.patron.firstname + ' ' + row.patron.surname +
59
            dataObj.forEach(function(thisRow) {
60
                        '</a>';
60
                ignore.forEach(function(thisIgnore) {
61
                    },
61
                    if (thisRow.hasOwnProperty(thisIgnore)) {
62
                    className: 'borrower_name'
62
                        delete thisRow[thisIgnore];
63
                },
63
                    }
64
                {
64
                });
65
                    data: 'borrowernumber',
65
            });
66
                    className: 'borrowernumber'
66
        };
67
                },
67
68
                {
68
        // Expand any fields we're expanding
69
                    data: 'biblio_id',
69
        var expandExpand = function(row) {
70
                    className: 'biblio_id'
70
            expand.forEach(function(thisExpand) {
71
                },
71
                if (row.hasOwnProperty(thisExpand)) {
72
                {
72
                    if (!expanded.hasOwnProperty(thisExpand)) {
73
                    data: 'branch.branchname',
73
                        expanded[thisExpand] = [];
74
                    className: 'branch_name'
75
                },
76
                {
77
                    render: function(data, type, row) {
78
                        return row.capabilities[row.status].name;
79
                    },
80
                    className: 'status'
81
                },
82
                {
83
                    data: 'updated',
84
                    className: 'updated'
85
                },
86
                {
87
                    data: 'medium',
88
                    className: 'medium'
89
                },
90
                {
91
                    data: 'cost',
92
                    className: 'cost'
93
                },
94
                {
95
                    render: function(data, type, row) {
96
                        return row.id_prefix + row.illrequest_id;
97
                    },
98
                    className: 'request_id'
99
                },
100
                {
101
                    data: null,
102
                    render: function(data, type, row) {
103
                        return '<a class="btn btn-default btn-sm" ' +
104
                        'href="/cgi-bin/koha/ill/ill-requests.pl?' +
105
                        'method=illview&amp;illrequest_id=' +
106
                        row.illrequest_id +
107
                        '">Manage request</a>' +
108
                        '</div>'
109
                    }
74
                    }
75
                    var expandObj = row[thisExpand];
76
                    Object.keys(expandObj).forEach(
77
                        function(thisExpandCol) {
78
                            var expColName = thisExpand + '_' + thisExpandCol;
79
                            // Keep a list of fields that have been expanded
80
                            // so we can create toggle links for them
81
                            if (expanded[thisExpand].indexOf(expColName) == -1) {
82
                                expanded[thisExpand].push(expColName);
83
                            }
84
                            expandObj[expColName] =
85
                                expandObj[thisExpandCol];
86
                            delete expandObj[thisExpandCol];
87
                        }
88
                    );
89
                    $.extend(true, row, expandObj);
90
                    delete row[thisExpand];
110
                }
91
                }
111
            ]
92
            });
112
        }));
93
        };
113
        var filters = $('#ill-requests').data();
94
114
        if (typeof filters !== 'undefined') {
95
        // Build a de-duped list of all column names
115
            var filterNames = Object.keys(filters).filter(
96
        var allCols = {};
116
                function(thisData) {
97
        core.map(function(thisCore) {
117
                    return thisData.match(/^filter/);
98
            allCols[thisCore] = 1;
99
        });
100
        var unionColumns = function(row) {
101
            Object.keys(row).forEach(function(col) {
102
                if (ignore.indexOf(col) == -1) {
103
                    allCols[col] = 1;
118
                }
104
                }
119
            );
120
            filterNames.forEach(function(thisFilter) {
121
                var filterClass = "." + toColumnName(thisFilter);
122
                var regex = '^'+filters[thisFilter]+'$';
123
                myTable.columns(filterClass).search(regex, true, false);
124
            });
105
            });
125
            myTable.draw();
106
        };
107
108
        // Some rows may not have fields that other rows have,
109
        // so make sure all rows have the same fields
110
        var fillMissing = function(row) {
111
            Object.keys(allCols).forEach(function(thisCol) {
112
                row[thisCol] = (!row.hasOwnProperty(thisCol)) ?
113
                    null :
114
                    row[thisCol];
115
            });
126
        }
116
        }
127
117
118
        // Strip the expand prefix if it exists, we do this for display
119
        var stripPrefix = function(value) {
120
            expand.forEach(function(thisExpand) {
121
                var regex = new RegExp(thisExpand + '_', 'g');
122
                value = value.replace(regex, '');
123
            });
124
            return value;
125
        };
126
127
        // Our 'render' function for borrowerlink
128
        var createBorrowerLink = function(data, type, row) {
129
            return '<a title="View borrower details" ' +
130
                'href="/cgi-bin/koha/members/moremember.pl?' +
131
                'borrowernumber='+row.patron_borrowernumber+'">' +
132
                row.patron_firstname + ' ' + row.patron_surname +
133
                '</a>';
134
        };
135
136
        // Render function for request ID
137
        var createRequestId = function(data, type, row) {
138
            return row.id_prefix + row.illrequest_id;
139
        };
140
141
        // Render function for request status
142
        var createStatus = function(data, type, row, meta) {
143
            var origData = meta.settings.oInit.originalData;
144
            if (origData.length > 0) {
145
                return meta.settings.oInit.originalData[0].capabilities[
146
                    row.status
147
                ].name;
148
            } else {
149
                return '';
150
            }
151
        };
152
153
        // Render function for creating a row's action link
154
        var createActionLink = function(data, type, row) {
155
            return '<a class="btn btn-default btn-sm" ' +
156
                'href="/cgi-bin/koha/ill/ill-requests.pl?' +
157
                'method=illview&amp;illrequest_id=' +
158
                row.illrequest_id +
159
                '">Manage request</a>' +
160
                '</div>'
161
        };
162
163
        // Columns that require special treatment
164
        var specialCols = {
165
            action: {
166
                name: '',
167
                func: createActionLink
168
            },
169
            borrowernumber: {
170
                name: 'Borrower',
171
                func: createBorrowerLink
172
            },
173
            illrequest_id: {
174
                name: 'Request number',
175
                func: createRequestId
176
            },
177
            status: {
178
                name: 'Status',
179
                func: createStatus
180
            },
181
            biblio_id: {
182
                name: 'Biblio number'
183
            },
184
            branchcode: {
185
                name: 'Branch code'
186
            }
187
        };
188
189
        // Helper for handling prefilter column names
128
        function toColumnName(myVal) {
190
        function toColumnName(myVal) {
129
            return myVal
191
            return myVal
130
                .replace(/^filter/, '')
192
                .replace(/^filter/, '')
Lines 132-141 Link Here
132
                .replace(/^_/,'').toLowerCase();
194
                .replace(/^_/,'').toLowerCase();
133
        };
195
        };
134
196
197
        // Toggle request attributes in Illview
135
        $('#toggle_requestattributes').click(function() {
198
        $('#toggle_requestattributes').click(function() {
136
            $('#requestattributes').toggleClass('content_hidden');
199
            $('#requestattributes').toggleClass('content_hidden');
137
        });
200
        });
138
201
202
        // Filter partner list
139
        $('#partner_filter').keyup(function() {
203
        $('#partner_filter').keyup(function() {
140
            var needle = $('#partner_filter').val();
204
            var needle = $('#partner_filter').val();
141
            $('#partners > option').each(function() {
205
            $('#partners > option').each(function() {
Lines 152-157 Link Here
152
            });
216
            });
153
        });
217
        });
154
218
219
        // Get our data from the API and process it prior to passing
220
        // it to datatables
221
        var ajax = $.ajax(
222
            '/api/v1/illrequests?embed=metadata,patron,capabilities,branch'
223
            ).done(function() {
224
                var data = JSON.parse(ajax.responseText);
225
                // Make a copy, we'll be removing columns next and need
226
                // to be able to refer to data that has been removed
227
                var dataCopy = $.extend(true, [], data);
228
                // Remove all columns we're not interested in
229
                removeIgnore(dataCopy);
230
                // Expand columns that need it and create an array
231
                // of all column names
232
                $.each(dataCopy, function(k, row) {
233
                    expandExpand(row);
234
                    unionColumns(row);
235
                });
236
                // Append any extra columns we need to tag on
237
                if (extra.length > 0) {
238
                    extra.forEach(function(thisExtra) {
239
                        allCols[thisExtra] = 1;
240
                    });
241
                };
242
                // Different requests will have different columns,
243
                // make sure they all have the same
244
                $.each(dataCopy, function(k, row) {
245
                    fillMissing(row);
246
                });
247
248
                // Assemble an array of column definitions for passing
249
                // to datatables
250
                var colData = [];
251
                Object.keys(allCols).forEach(function(thisCol) {
252
                    // We may have defined a pretty name for this column
253
                    var colName = (
254
                        specialCols.hasOwnProperty(thisCol) &&
255
                        specialCols[thisCol].hasOwnProperty('name')
256
                    ) ?
257
                        specialCols[thisCol].name :
258
                        thisCol;
259
                    // Create the table header for this column
260
                    var str = '<th>' + stripPrefix(colName) + '</th>';
261
                    $(str).appendTo('#illview-header');
262
                    // Create the base column object
263
                    var colObj = {
264
                        name: thisCol,
265
                        className: thisCol
266
                    };
267
                    // We may need to process the data going in this
268
                    // column, so do it if necessary
269
                    if (
270
                        specialCols.hasOwnProperty(thisCol) &&
271
                        specialCols[thisCol].hasOwnProperty('func')
272
                    ) {
273
                        colObj.render = specialCols[thisCol].func;
274
                    } else {
275
                        colObj.data = thisCol
276
                    }
277
                    colData.push(colObj);
278
                });
279
280
                // Create the toggle links for all metadata fields
281
                var links = [];
282
                expanded.metadata.forEach(function(thisExpanded) {
283
                    if (core.indexOf(thisExpanded) == -1) {
284
                        links.push(
285
                            '<a href="#" class="toggle-vis" data-column="' +
286
                            thisExpanded + '">' + stripPrefix(thisExpanded) +
287
                            '</a>'
288
                        );
289
                    }
290
                });
291
                $('#column-toggle').append(links.join(' | '));
292
293
                // Initialise the datatable
294
                var myTable = $('#ill-requests').DataTable($.extend(true, {}, dataTablesDefaults, {
295
                    aoColumnDefs: [  // Last column shouldn't be sortable or searchable
296
                        {
297
                            aTargets: [ 'action' ],
298
                            bSortable: false,
299
                            bSearchable: false
300
                        },
301
                    ],
302
                    aaSorting: [[ 6, 'desc' ]], // Default sort, updated descending
303
                    processing: true, // Display a message when manipulating
304
                    language: {
305
                        loadingRecords: "Please wait - loading requests...",
306
                        zeroRecords: "No requests were found"
307
                    },
308
                    iDisplayLength: 10, // 10 results per page
309
                    sPaginationType: "full_numbers", // Pagination display
310
                    deferRender: true, // Improve performance on big datasets
311
                    data: dataCopy,
312
                    columns: colData,
313
                    originalData: data // Enable render functions to access
314
                                       // our original data
315
                }));
316
317
                // Reset columns to default
318
                var resetColumns = function() {
319
                    Object.keys(allCols).forEach(function(thisCol) {
320
                        myTable.column(thisCol + ':name').visible(core.indexOf(thisCol) != -1);
321
                    });
322
                    myTable.columns.adjust().draw(false);
323
                };
324
325
                // Handle the click event on a toggle link
326
                $('a.toggle-vis').on('click', function(e) {
327
                    e.preventDefault();
328
                    var column = myTable.column(
329
                        $(this).data('column') + ':name'
330
                    );
331
                    column.visible(!column.visible());
332
                });
333
334
                // Reset column toggling
335
                $('#reset-toggle').click(function() {
336
                    resetColumns();
337
                });
338
339
                // Handle a prefilter request and do the prefiltering
340
                var filters = $('#ill-requests').data();
341
                if (typeof filters !== 'undefined') {
342
                    var filterNames = Object.keys(filters).filter(
343
                        function(thisData) {
344
                            return thisData.match(/^filter/);
345
                        }
346
                    );
347
                    filterNames.forEach(function(thisFilter) {
348
                        var filterName = toColumnName(thisFilter) + ':name';
349
                        var regex = '^'+filters[thisFilter]+'$';
350
                        console.log(regex);
351
                        myTable.columns(filterName).search(regex, true, false);
352
                    });
353
                    myTable.draw();
354
                }
355
356
                // Initialise column hiding
357
                resetColumns();
358
359
            }
360
        );
361
155
    });
362
    });
156
    //]]>
363
    //]]>
157
</script>
364
</script>
Lines 442-470 Link Here
442
                    <h1>View ILL requests</h1>
649
                    <h1>View ILL requests</h1>
443
                    <div id="results">
650
                    <div id="results">
444
                        <h3>Details for all requests</h3>
651
                        <h3>Details for all requests</h3>
652
653
                        <div id="column-toggle">
654
                            Toggle additional columns:
655
                        </div>
656
                        <div id="reset-toggle"><a href="#">Reset toggled columns</a></div>
657
445
                        <table
658
                        <table
446
                            [% FOREACH filter IN prefilters %]
659
                            [% FOREACH filter IN prefilters %]
447
                            data-filter-[% filter.name %]="[% filter.value %]"
660
                            data-filter-[% filter.name %]="[% filter.value %]"
448
                            [% END %]
661
                            [% END %]
449
                            id="ill-requests">
662
                            id="ill-requests">
450
                            <thead>
663
                            <thead>
451
                                <tr>
664
                                <tr id="illview-header"></tr>
452
                                    <th id="orderid">Order ID:</th>
453
                                    <th id="author">Author:</th>
454
                                    <th id="title">Title:</th>
455
                                    <th id="borrower_name">Borrower:</th>
456
                                    <th id="borrowernumber">Borrower number:</th>
457
                                    <th id="biblio_id">Biblio number:</th>
458
                                    <th id="branchcode">Branch:</th>
459
                                    <th id="status">Status:</th>
460
                                    <th id="updated">Last updated:</th>
461
                                    <th id="medium">Request type:</th>
462
                                    <th id="cost">Cost:</th>
463
                                    <th id="req_id">Request number:</th>
464
                                    <th id="link">Manage request:</th>
465
                                </tr>
466
                            </thead>
665
                            </thead>
467
                            <tbody>
666
                            <tbody id="illview-body">
468
                            </tbody>
667
                            </tbody>
469
                        </table>
668
                        </table>
470
                    </div>
669
                    </div>
471
- 

Return to bug 7317