]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/cat/authority/list.js
Use the browse method instead of startwith for Manage Authorities, too
[working/Evergreen.git] / Open-ILS / web / js / ui / default / cat / authority / list.js
1 dojo.require('dijit.Dialog');
2 dojo.require('dijit.form.Button');
3 dojo.require('dijit.form.DropDownButton');
4 dojo.require('dijit.form.FilteringSelect');
5 dojo.require('dijit.form.Form');
6 dojo.require('dijit.form.NumberSpinner');
7 dojo.require('dijit.form.TextBox');
8 dojo.require("dijit.Menu");
9 dojo.require("dijit.MenuItem");
10 dojo.require('dojox.xml.parser');
11 dojo.require('DojoSRF');
12 dojo.require("fieldmapper.Fieldmapper");
13 dojo.require('openils.CGI');
14 dojo.require('openils.PermaCrud');
15 dojo.require('openils.XUL');
16 dojo.require('openils.widget.OrgUnitFilteringSelect');
17 dojo.requireLocalization("openils.authority", "authority");
18 var auth_strings = dojo.i18n.getLocalization("openils.authority", "authority");
19
20 var cgi = new openils.CGI();
21
22 /*
23 // OrgUnits do not currently affect the retrieval of authority records,
24 // but this is how to display them if they become OrgUnit-aware
25 function authOUListInit() {
26     new openils.User().buildPermOrgSelector(
27         "STAFF_LOGIN", // anywhere you can log in
28         dijit.byId("authOU"),
29         null, // pre-selected org
30         null
31     );
32 }
33 dojo.addOnLoad(authOUListInit);
34 */
35 function displayAuthorities(data) { 
36
37     var idArr = [];
38     // Grab each record from the returned authority records
39     dojo.query("record", data).forEach(function(node) {
40         var auth = {};
41         auth.text = '';
42         auth.id = 0;
43
44         // Grab each authority record field from the authority record
45         dojo.query("datafield[tag^='1']", node).forEach(function(dfNode) {
46             auth.text += dojox.xml.parser.textContent(dfNode); 
47             auth.name = dojo.attr(dfNode, 'tag');
48             auth.ind1 = dojo.attr(dfNode, 'ind1');
49             auth.ind2 = dojo.attr(dfNode, 'ind2');
50         });
51
52         
53         // Grab the ID of the authority record
54         dojo.query("datafield[tag='901'] subfield[code='c']", node).forEach(function(dfNode) {
55             auth.id = dojox.xml.parser.textContent(dfNode); 
56         });
57
58         idArr.push(parseInt(auth.id));
59
60         // Create the authority record listing entry
61         dojo.place('<div class="authEntry" id="auth' + auth.id + '"><span class="text" id="authLabel' + auth.id + '">' + auth.text + '</span></div>', "authlist-div", "last");
62
63         // Add the menu of new/edit/delete/mark-for-merge options
64         var auth_menu = new dijit.Menu({});
65
66         // "Edit" menu item
67         new dijit.MenuItem({"id": "edit_" + auth.id, "onClick": function(){
68             var pcrud = new openils.PermaCrud();
69             var auth_rec = pcrud.retrieve("are", auth.id);
70             if (auth_rec) {
71                 loadMarcEditor(pcrud, auth_rec);
72             }
73         }, "label":auth_strings.MENU_EDIT}).placeAt(auth_menu, "first");
74
75         // "Merge" menu item
76         new dijit.MenuItem({"id": "merge_" + auth.id, "onClick":function(){
77             auth.text = '';
78             dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
79                 auth.text += dojox.xml.parser.textContent(node); 
80             });
81
82             // If there is a toMerge item already, this is a target record
83             var mergeRole = '<td style="border: 1px solid black; padding-left: 0.5em; padding-right: 1em;">';
84             var isTarget = dojo.query('.toMerge').length;
85             if (isTarget) {
86                 mergeRole += auth_strings.TARGET_RECORD + '</td>';
87             } else {
88                 mergeRole += auth_strings.MASTER_RECORD + '</td>';
89             }
90
91             dojo.place('<tr class="toMerge" id="toMerge_' + auth.id + '"><td>' + mergeRole + '</td><td  style="border: 1px solid black;" id="mergeMeta_' + auth.id + '"></td><td style="border: 1px solid black; padding-left: 1em; padding-right: 1em;" >' + auth.text + '</td></tr>', 'mergebox-tbody', 'last');
92             dojo.place('<span class="authmeta" style="font-family: monospace;">' + auth.name + ' ' + auth.ind1 + auth.ind2 + '</span>', 'mergeMeta_' + auth.id, 'last');
93             dojo.removeClass('mergebox-div', 'hidden');
94         }, "label":auth_strings.MENU_MERGE}).placeAt(auth_menu, "last");
95
96         // "Delete" menu item
97         new dijit.MenuItem({
98             "id": "delete_" + auth.id,
99             "onClick":function(){
100                 auth.text = '';
101
102                 var pcrud = new openils.PermaCrud();
103                 var auth_rec = pcrud.retrieve("are", auth.id);
104
105                 // Bit of a hack to get the linked bib count until an explicit ID
106                 var linkedBibs = dojox.xml.parser.textContent(
107                     dojo.query("#authLabel" + auth.id)[0].previousSibling
108                 );
109
110                 var delDlg = dijit.byId("delDialog_" + auth.id);
111
112                 dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
113                     auth.text += dojo.trim(dojox.xml.parser.textContent(node)); 
114                 });
115
116                 if (!delDlg) {
117                     var content = '<div>' + dojo.string.substitute(auth_strings.CONFIRM_DELETE_TITLE, [auth.text]) + '</div>';
118                     if (parseInt(linkedBibs) > 0) {
119                         content = "<div id='delAuthSum_" + auth.id + "'>"
120                             + dojo.string.substitute(auth_strings.LINKED_BIBS, [linkedBibs])
121                             + "</div>";
122                     }
123                     content += "<div id='authMARC" + auth.id + "' style='width: 100%; display:none;'>";
124                     content += "<hr style='width: 100%;' />";
125                     content += marcToHTML(auth_rec.marc());
126                     content += "</div><hr style='width: 100%;' /><div>";
127                     content += "<input type='button' dojoType='dijit.form.Button' label='" + auth_strings.CANCEL + "' onClick='cancelDelete(" + auth.id + ")'/>";
128                     content += "<input type='button' dojoType='dijit.form.Button' label='" + auth_strings.DELETE + "' onClick='confirmDelete(" + auth.id + ")'/>";
129                     content += "<input id='viewMARC" + auth.id + "' type='button' "
130                         + "style='float:right;' dojoType='dijit.form.Button' "
131                         + "label='" + auth_strings.VIEW_MARC + "' onClick='viewMARC(" + auth.id + ")'/>";
132                     content += "<input id='hideMARC" + auth.id + "' type='button' "
133                         + "style='display: none; float:right;' dojoType='dijit.form.Button' "
134                         + "label='" + auth_strings.HIDE_MARC + "' onClick='hideMARC(" + auth.id + ")'/>";
135                     content += "</div>";
136                     delDlg = new dijit.Dialog({
137                         "id":"delDialog_" + auth.id,
138                         "title": dojo.string.substitute(auth_strings.CONFIRM_DELETE_PROMPT, [auth.id]),
139                         "content": content
140                     });
141                 }
142                 delDlg.show();
143
144         }, "label":auth_strings.DELETE}).placeAt(auth_menu, "last");
145
146         auth_mb = new dijit.form.DropDownButton({dropDown: auth_menu, label: auth_strings.ACTIONS, id:"menu" + auth.id});
147         auth_mb.placeAt("auth" + auth.id, "first");
148         auth_menu.startup();
149     });
150
151     showBibCount(idArr);
152 }
153
154 function viewMARC(recId) {
155     dojo.style(dojo.byId("authMARC" + recId), 'display', 'block');
156     dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'none');
157     dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'block');
158 }
159
160 function hideMARC(recId) {
161     dojo.style(dojo.byId("authMARC" + recId), 'display', 'none');
162     dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'none');
163     dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'block');
164 }
165
166 function marcToHTML(marc) {
167     var html = '<table><tbody>';
168     marc = dojox.xml.parser.parse(marc);
169     dojo.query('leader', marc).forEach(function(node) {
170         html += '<tr><td>LDR</td><td>&nbsp;</td><td>&nbsp;</td><td>' + dojox.xml.parser.textContent(node) + '</td></tr>';
171     });
172     dojo.query('controlfield', marc).forEach(function(node) {
173         html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td>&nbsp;</td><td>&nbsp;</td><td>' + dojox.xml.parser.textContent(node) + '</td></tr>';
174     });
175     dojo.query('datafield', marc).forEach(function(node) {
176         var cnt = 0;
177         html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td>' + dojo.attr(node, "ind1") + '</td><td>' + dojo.attr(node, "ind2") + '</td>';
178         dojo.query('subfield', node).forEach(function(sf) {
179             if (cnt == 0) {
180                 html += '<td>$' + dojo.attr(sf, "code") + ' ' + dojox.xml.parser.textContent(sf) + '</td></tr>';
181                 cnt = 1;
182             } else {
183                 html += '<tr><td colspan="3"></td><td>$' + dojo.attr(sf, "code") + ' ' + dojox.xml.parser.textContent(sf) + '</td></tr>';
184             }
185         });
186     });
187     html += '</tbody></table>';
188     return html;
189 }
190
191 function cancelDelete(recId) {
192     dijit.byId("delDialog_" + recId).hide();
193 }
194
195 function confirmDelete(recId) {
196     var pcrud = new openils.PermaCrud();
197     var auth_rec = pcrud.retrieve("are", recId);
198     if (auth_rec) {
199         pcrud.eliminate(auth_rec);
200         dijit.byId("delDialog_" + recId).attr("content", dojo.string.substitute(auth_strings.CONFIRM_DELETE_RESULT, [recId]));
201         setTimeout(function() {
202             dijit.byId("delDialog_" + recId).hide();
203         }, 3000);
204     }
205 }
206
207 function showBibCount(authIds) {
208     /* Decorate the list with # of bibs linked to each authority record */
209     var ses = new OpenSRF.ClientSession('open-ils.cat');
210     var req = ses.request('open-ils.cat.authority.records.count_linked_bibs', authIds);
211     var linkedIds = [];
212     req.oncomplete = function(r) {
213         var msg = r.recv().content();
214         dojo.forEach(msg, function(auth) {
215                 linkedIds.push(auth.authority);
216                 dojo.place('<span class="bibcount">' + auth.bibs + '</span>', 'authLabel' + auth.authority, 'before');
217             }
218         );
219
220         /* Assign counts of 0 for every non-linked authority */
221         dojo.forEach(authIds, function (id) {
222             var found = false;
223             dojo.forEach(linkedIds, function (lid) {
224                 if (id == lid) {
225                     found = true;
226                 }
227             });
228             if (!found) {
229                 dojo.place('<span class="bibcount">0</span>', 'authLabel' + id, 'before');
230             }
231         });
232     }
233     req.send();
234 }
235
236 function loadMarcEditor(pcrud, rec) {
237     /*
238        To run in Firefox directly, must set signed.applets.codebase_principal_support
239        to true in about:config
240      */
241     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
242     win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
243
244     win.xulG = {
245         "record": {"marc": rec.marc(), "rtype": "are"},
246         "save": {
247             "label": auth_strings.SAVE,
248             "func": function(xmlString) {
249                 rec.marc(xmlString);
250                 rec.edit_date('now');
251                 rec.ischanged(true);
252                 pcrud.update(rec);
253                 alert(auth_strings.SAVE_RESULT_SUCCESS);
254                 win.close();
255             }
256         },
257         'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
258         'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
259     };
260 }
261
262 function authListInit() {
263     var term = cgi.param('authTerm') || '';
264     var page = cgi.param('authPage') || 0;
265     var axis = cgi.param('authAxis') || 'authority.author';
266     if (axis) {
267         dijit.byId('authAxis').attr('value', axis);
268     }
269     if (page) {
270         dijit.byId('authPage').attr('value', page);
271     }
272     if (term) {
273         dijit.byId('authTerm').attr('value', term);
274         displayRecords();
275     }
276
277     dojo.connect(dijit.byId('authAxis'), 'onKeyPress', function(evt) {
278         if (evt.keyCode == dojo.keys.ENTER) {
279             dijit.byId('authPage').attr('value', 0);
280             displayRecords();
281         }
282     }); 
283
284     dojo.connect(dijit.byId('authPage'), 'onKeyPress', function(evt) {
285         if (evt.keyCode == dojo.keys.ENTER) {
286             dijit.byId('authPage').attr('value', 0);
287             displayRecords();
288         }
289     });
290
291     dojo.connect(dijit.byId('authTerm'), 'onKeyPress', function(evt) {
292         if (evt.keyCode == dojo.keys.ENTER) {
293             dijit.byId('authPage').attr('value', 0);
294             displayRecords();
295         }
296     });
297
298     dijit.byId('authTerm').focus();
299
300 }
301 dojo.addOnLoad(authListInit);
302
303 function displayRecords(parms) {
304
305     if (parms && parms.page) {
306         if (parms.page == 'next') {
307             page = dijit.byId('authPage').attr('value');
308             dijit.byId('authPage').attr('value', page + 1);
309         } else if (parms.page == 'prev') {
310             page = dijit.byId('authPage').attr('value');
311             dijit.byId('authPage').attr('value', page - 1);
312         } else {
313             dijit.byId('authPage').attr('value', parms.page);
314         }
315     }
316
317     /* Protect against null input */
318     if (!dijit.byId('authTerm').attr('value')) {
319         return;
320     }
321
322     /* Clear out the current contents of the page */
323     var widgets = dijit.findWidgets(dojo.byId('authlist-div'));
324     dojo.forEach(widgets, function(w) { w.destroyRecursive(true); });
325
326     dojo.query("#authlist-div div").orphan();
327
328     var url = '/opac/extras/browse/marcxml/'
329         + dijit.byId('authAxis').attr('value')
330         // + '/' + dijit.byId('authOU').attr('value')
331         + '/1' // replace with preceding line if OUs gain some meaning
332         + '/' + dijit.byId('authTerm').attr('value')
333         + '/' + dijit.byId('authPage').attr('value')
334         + '/' + '20' // 20 results per page
335     ;
336     dojo.xhrGet({"url":url, "handleAs":"xml", "content":{"format":"marcxml"}, "preventCache": true, "load":displayAuthorities });
337 }
338
339 function clearMergeRecords() {
340     var records = dojo.query('.toMerge').orphan();
341     dojo.addClass('mergebox-div', 'hidden');
342 }
343
344 function mergeRecords() {
345     var records = dojo.query('.toMerge').attr('id');
346     dojo.forEach(records, function(item, idx) {
347         records[idx] = parseInt(item.slice(item.lastIndexOf('_') + 1));
348     });
349
350     /* Take the first record in the list and use that as the master */
351     fieldmapper.standardRequest(
352         ['open-ils.cat', 'open-ils.cat.authority.records.merge'],
353         {   async: false,
354             params: [openils.User.authtoken, records.shift(), records],
355             oncomplete : function(r) {
356                 alert(auth_strings.MERGE_RESULT_SUCCESS);
357                 clearMergeRecords();
358                 displayRecords();
359             }
360         }
361     );
362 }