cb79e82b7931a1a73d5a3659e0022e9775250597
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / URLVerify / CreateSession.js
1 if (!dojo._hasResource["openils.URLVerify.CreateSession"]) {
2     dojo.require("dojo.data.ItemFileWriteStore");
3     dojo.require("dojox.jsonPath");
4     dojo.require("fieldmapper.OrgUtils");
5     dojo.require("openils.Util");
6     dojo.require("openils.PermaCrud");
7     dojo.require("openils.widget.FilteringTreeSelect");
8
9     dojo.requireLocalization("openils.URLVerify", "URLVerify");
10
11     dojo._hasResource["openils.URLVerify.CreateSession"] = true;
12     dojo.provide("openils.URLVerify.CreateSession");
13
14     dojo.declare("openils.URLVerify.CreateSession", null, {});
15
16     /* Take care that we add nothing to the global namespace. */
17
18 (function() {
19     var module = openils.URLVerify.CreateSession;
20     var localeStrings =
21         dojo.i18n.getLocalization("openils.URLVerify", "URLVerify");
22     var uvus_progress = 0;
23
24     /* Take search text box input, selected saved search ids, and selected
25      * scope shortname to produce one search string. */
26     module._prepare_search = function(basic, saved, scope) {
27         if (saved.length) {
28             basic += " " + dojo.map(
29                 saved, function(s) { return "saved_query(" + s + ")"; }
30             ).join(" ");
31         }
32
33         if (scope && !basic.match(/site\(.+\)/))
34             basic += " site(" + scope + ")";
35
36         return basic;
37     };
38
39     /* Reacting to the interface's "Begin" button, this function triggers the
40      * first of three server-side processes necessary to create a session:
41      *
42      * 1) create the session itself (API call), */
43     module.begin = function() {
44         var name = uv_session_name.attr("value");
45
46         var scope;
47         try {
48             scope = module.org_selector.store.getValue(
49                 module.org_selector.item,
50                 "shortname"
51             );
52         } catch (E) {
53             /* probably nothing valid is selected; move on */
54             void(0);
55         }
56
57         var search = module._prepare_search(
58             uv_search.attr("value"),
59             dojo.filter(
60                 dojo.byId("saved-searches").options,
61                 function(o) { return o.selected; }
62             ).map(
63                 function(o) { return o.value; }
64             ),
65             scope
66         );
67
68         if (!module.tag_and_subfields.any()) {
69             alert(localeStrings.NEED_UVUS);
70             return;
71         }
72
73         module.progress_dialog.attr("title", localeStrings.CREATING);
74         module.progress_dialog.show(true);
75         fieldmapper.standardRequest(
76             ["open-ils.url_verify", "open-ils.url_verify.session.create"], {
77                 "params": [openils.User.authtoken, name, search],
78                 "async": true,
79                 "onresponse": function(r) {
80                     if (r = openils.Util.readResponse(r)) {
81                         /* I think we're modal enough to get away with this. */
82                         module.session_id = r;
83                         module.save_tags();
84                     }
85                 }
86             }
87         );
88     };
89
90     /* 2) save the tag/subfield sets for URL extraction, */
91     module.save_tags = function() {
92         module.progress_dialog.attr("title", localeStrings.SAVING_TAGS);
93         module.progress_dialog.show(); /* sic */
94
95         uvus_progress = 0;
96
97         /* Note we're not using openils.PermaCrud, which is inadequate
98          * when you want transactions. Thanks for figuring it out, Bill. */
99         var pcrud_raw = new OpenSRF.ClientSession("open-ils.pcrud");
100
101         pcrud_raw.connect();
102
103         pcrud_raw.request({
104             "method": "open-ils.pcrud.transaction.begin",
105             "params": [openils.User.authtoken],
106             "oncomplete": function(r) {
107                 module._create_uvus_one_at_a_time(
108                     pcrud_raw,
109                     module.tag_and_subfields.generate_uvus(
110                         module.session_id
111                     )
112                 );
113             }
114         }).send();
115     };
116
117     /* 2b */
118     module._create_uvus_one_at_a_time = function(pcrud_raw, uvus_list) {
119         pcrud_raw.request({
120             "method": "open-ils.pcrud.create.uvus",
121             "params": [openils.User.authtoken, uvus_list[0]],
122             "oncomplete": function(r) {
123                 var new_uvus = openils.Util.readResponse(r);
124                 module.progress_dialog.update(
125                     {"maximum": uvus_list.length, "progress": ++uvus_progress}
126                 );
127
128                 uvus_list.shift();  /* /now/ actually shorten the list */
129
130                 if (uvus_list.length < 1) {
131                     pcrud_raw.request({
132                         "method": "open-ils.pcrud.transaction.commit",
133                         "params": [openils.User.authtoken],
134                         "oncomplete": function(r) {
135                             pcrud_raw.disconnect();
136                             module.perform_search();
137                         }
138                     }).send();
139
140                 } else {
141                     module._create_uvus_one_at_a_time(
142                         pcrud_raw, uvus_list
143                     );
144                 }
145              }
146         }).send();
147     };
148
149     /* 3) search and populate the container (API call). */
150     var search_result_count = 0;
151     module.perform_search = function() {
152         module.progress_dialog.attr("title", localeStrings.PERFORMING_SEARCH);
153         module.progress_dialog.show(true);
154
155         fieldmapper.standardRequest(
156             ["open-ils.url_verify",
157                 "open-ils.url_verify.session.search_and_extract"], {
158                 "params": [openils.User.authtoken, module.session_id],
159                 "async": true,
160                 "onresponse": function(r) {
161                     r = openils.Util.readResponse(r);
162                     if (!search_result_count) {
163                         search_result_count = Number(r);
164
165                         module.progress_dialog.show(); /* sic */
166                         module.progress_dialog.attr(
167                             "title", localeStrings.EXTRACTING_URLS
168                         );
169                         module.progress_dialog.update(
170                             {"maximum": search_result_count, "progress": 0}
171                         );
172                     } else {
173                         module.progress_dialog.update({"progress": r.length})
174                     }
175                 },
176                 "oncomplete": function() {
177                     module.progress_dialog.attr(
178                         "title", localeStrings.REDIRECTING
179                     );
180                     module.progress_dialog.show(true);
181
182                     if (no_url_selection.checked) {
183                         location.href = oilsBasePath +
184                             "/url_verify/validation_review?" +
185                             "session_id=" + module.session_id +
186                             "&validate=1";
187                     } else {
188                         location.href = oilsBasePath +
189                             "/url_verify/select_urls?session_id=" +
190                             module.session_id;
191                     }
192                 }
193             }
194         );
195     };
196
197     /* At least in Dojo 1.3.3 (I know, I know), dijit.form.MultiSelect does
198      * not behave like FilteringSelect, like you might expect, or work from a
199      * data store.  So we'll use a native <select> control, which will have
200      * fewer moving parts that can go haywire anyway.
201      */
202     module._populate_saved_searches = function(node) {
203         var pcrud = new openils.PermaCrud();
204         var list = pcrud.retrieveAll(
205             "asq", {"order_by": {"asq": "label"}}
206         );
207
208         dojo.forEach(
209             list,
210             function(o) {
211                 dojo.create(
212                     "option", {
213                         "innerHTML": o.label(),
214                         "value": o.id(),
215                         "title": o.query_text()
216                     }, node, "last"
217                 );
218             }
219         );
220
221         pcrud.disconnect();
222     };
223
224     /* set up an all-org-units-in-the-tree selector */
225     module._prepare_org_selector = function(node) {
226         var widget = new openils.widget.FilteringTreeSelect(null, node);
227         widget.searchAttr = "name";
228         widget.labelAttr = "name";
229         widget.tree = fieldmapper.aou.globalOrgTree;
230         widget.parentField = 'parent_ou';
231         widget.startup();
232         widget.attr("value", openils.User.user.ws_ou());
233
234         module.org_selector = widget;
235     };
236
237     module.setup = function(saved_search_id, org_selector_id, progress_dialog) {
238         module.progress_dialog = progress_dialog;
239
240         module.progress_dialog.attr("title", localeStrings.INTERFACE_SETUP);
241         module.progress_dialog.show(true);
242
243         module._populate_saved_searches(dojo.byId(saved_search_id));
244         module._prepare_org_selector(dojo.byId(org_selector_id));
245
246         module.progress_dialog.hide();
247     };
248
249     /* This is the thing that lets you add/remove rows of tab/subfield pairs */
250     function TagAndSubfieldsMgr(container_id) {
251         var self = this;
252
253         this.container_id = container_id;
254         this.counter = 0;
255
256         this.read_new = function() {
257             var controls = dojo.query(".tag-and-subfield-add-another input");
258
259             return {
260                 "tag": controls[0].value,
261                 "subfields": openils.Util.uniqueElements(
262                     controls[1].value.replace(/[^0-9a-z]/g, "").split("")
263                 ).sort().join("")
264             };
265         };
266
267         this.add = function() {
268             var newdata = this.read_new();
269             var newid = "t-and-s-row-" + String(this.counter++);
270             var div = dojo.create(
271                 "div", {
272                     "id": newid,
273                     "innerHTML": "<span class='t-and-s-tag'>" +
274                         newdata.tag +
275                         "</span> \u2021<span class='t-and-s-subfields'>" +
276                         newdata.subfields + "</span> "
277                 }, this.container_id, "last"
278             );
279             dojo.create(
280                 "a", {
281                     "href": "javascript:void(0);",
282                     "onclick": function() {
283                         var me = dojo.byId(newid);
284                         me.parentNode.removeChild(me);
285                     },
286                     "innerHTML": "[X]" /* XXX i18n */
287                 }, div, "last"
288             );
289
290             this.counter++;
291         };
292
293         /* return a boolean indicating whether or not we have any rows */
294         this.any = function() {
295             return Boolean(
296                 dojo.query(
297                     '[id^="t-and-s-row-"]', dojo.byId(this.container_id)
298                 ).length
299             );
300         };
301
302         /* Return one uvus object for each unique tag we have a row for,
303          * and use the given session_id for the uvus.session field. */
304         this.generate_uvus = function(session_id) {
305             var uniquely_grouped = {};
306             dojo.query(
307                 '[id^="t-and-s-row-"]', dojo.byId(this.container_id)
308             ).forEach(
309                 function(row) {
310                     var tag = dojo.query(".t-and-s-tag", row)[0].innerHTML;
311                     var subfield = dojo.query(".t-and-s-subfields", row)[0].innerHTML;
312
313                     var existing;
314                     if ((existing = uniquely_grouped[tag])) { /* sic, assignment */
315                         existing = openils.Util.uniqueElements(
316                             (existing + subfield).split("")
317                         ).sort().join("");
318                     } else {
319                         uniquely_grouped[tag] = subfield;
320                     }
321                 }
322             );
323
324             var uvus_list = [];
325             for (var tag in uniquely_grouped) {
326                 var obj = new uvus();
327
328                 obj.session(session_id);
329
330                 /* XXX TODO handle control fields (no subfields) */
331                 obj.xpath(
332                     "//*[@tag='" + tag + "']/*[" +
333                     uniquely_grouped[tag].split("").map(
334                         function(c) { return "@code='" + c + "'"; }
335                     ).join(" or ") +
336                     "]"
337                 );
338
339                 uvus_list.push(obj);
340             }
341
342             return uvus_list;
343         };
344
345     }
346
347     module.tag_and_subfields =
348         new TagAndSubfieldsMgr("uv-tags-and-subfields");
349
350 }());
351
352 }