2 [% ctx.page_title = "Triggered Event Log" %]
3 <script type="text/javascript">
4 dojo.require("dijit.form.Button");
5 dojo.require("dojo.data.ItemFileReadStore");
6 dojo.require("openils.CGI");
7 dojo.require("openils.widget.FlattenerGrid");
8 dojo.require("openils.widget.OrgUnitFilteringSelect");
9 dojo.require("openils.widget.ProgressDialog");
11 /* If you want to expand this list of supported core_types, you must also
12 change openils.widget._FSBuilder.CoreType further down, so that it
13 includes labels for these in its data store for filter widget
15 var initial_query = {"core_type": ["circ", "ahr"]};
17 /* Pre-filter by patron ID or copy ID if those are passed in as CGI
18 parameters. It's an either-or proposition for now. */
19 var cgi = new openils.CGI();
20 var patron_id = cgi.param("patron_id");
21 var copy_id = cgi.param("copy_id");
23 /* These features depends on target_{circ,hold}_{patron,copy}_id fields
24 being present in map_extras later. */
26 initial_query["-or"] = {
27 "target_circ_patron_id": patron_id,
28 "target_hold_patron_id": patron_id
30 openils.Util.addOnLoad(
31 function() { openils.Util.show("patron_specific", "inline"); }
34 initial_query["-or"] = {
35 "target_circ_copy_id": copy_id,
36 "target_hold_copy_id": copy_id
38 openils.Util.addOnLoad(
39 function() { openils.Util.show("copy_specific", "inline"); }
43 /* This semaphore business exists to prevent a race condition. Both
44 the OrgUnitFilteringSelect and the FlattenerFilterPane try to refresh
45 the grid when they're done loading, but that doesn't need to happen
46 until they're /both/ done loading. */
47 var _filter_semaphore_ctr = 2;
48 function filter_semaphore() { return --_filter_semaphore_ctr <= 0; }
49 function filter_semaphore_callback() {
50 grid.fetchLock = false;
51 grid.filterUi.doApply();
54 /* This and its subclasses exist because *FilterPane expect things that
55 act like AutoFieldWidget, which is a widget /builder/. */
57 "openils.widget._FSBuilder", null, {
62 "constructor": function(args) {
63 dojo.mixin(this, args);
67 var dijitArgs = dojo.mixin(
72 "searchAttr": "label",
77 new dijit.form.FilteringSelect(dijitArgs, this.parentNode);
83 "openils.widget._FSBuilder.CoreType",
84 [openils.widget._FSBuilder], {
85 "store": new dojo.data.ItemFileReadStore({
88 "items": [ /* XXX i18n */
89 {"name": "circ", "label": "Circulation"},
90 {"name": "ahr", "label": "Hold"}
98 "openils.widget._FSBuilder.EventState",
99 [openils.widget._FSBuilder], {
100 "store": new dojo.data.ItemFileReadStore({
102 "identifier": "name",
103 "items": [ /* XXX i18n */
104 {"name": "found", "label": "Found"},
105 {"name": "collected", "label": "Collected"},
106 {"name": "invalid", "label": "Invalid"},
107 {"name": "pending", "label": "Pending"},
108 {"name": "reacting", "label": "Reacting"},
109 {"name": "complete", "label": "Complete"},
110 {"name": "error", "label": "Error"}
117 /* Various things with which to initialize FlattenerGrid. */
119 "core_type": {"path": "hook.core_type", "filter": true},
120 "perm_lib": {"path": "perm_lib", "filter": true},
121 "target_circ_patron_id": {"path": "target_circ.usr", "filter": true},
122 "target_hold_patron_id": {"path": "target_hold.usr", "filter": true},
123 "target_circ_copy_id":{"path":"target_circ.target_copy","filter":true},
124 "target_hold_copy_id":{"path":"target_hold.current_copy","filter":true}
127 var filter_initializers = [
128 {"field": "state", "operator": "=", "value": "complete"},
129 {"field": "core_type", "operator": "=", "value": "circ"}
132 var filter_widget_builders = {
133 "ath:core_type": openils.widget._FSBuilder.CoreType,
134 "atul:state": openils.widget._FSBuilder.EventState,
137 function print_all() {
139 if ((n = parseInt(prompt('[% l("Up to how many rows?") %]','100'))) > 0)
143 function act_on_events(id_list, action) {
144 console.log(id_list);
145 var method = "open-ils.actor.user.event." + action + ".batch";
146 if (id_list.length < 1) {
147 alert("[% l('You selected nothing.') %]");
152 progress_dialog.show(true);
153 fieldmapper.standardRequest(
154 ["open-ils.actor", method], {
156 "params": [openils.User.authtoken, id_list],
157 "onresponse": function(r) {
158 if (r = openils.Util.readResponse(r)) {
159 progress_dialog.update(
160 {"maximum": id_list.length, "progress": ++count}
164 "oncomplete": function(r) {
165 progress_dialog.hide();
166 r = openils.Util.readResponse(r);
173 /* The callback fired when the OrgUnitFilteringSelect is changed */
174 function set_grid_query_from_org_selector() {
175 /* Naughty: shouldn't use _baseQuery like this, but need to rethink
176 multiple competing filtering mechanisms. */
177 grid._baseQuery.perm_lib = aou.descendantNodeList(
178 org_selector.attr("value"), /* as id */ true
181 /* But for the persistent filter UI, this would be grid.refresh() */
182 if (filter_semaphore()) /* avoid race between ou selector and other
184 filter_semaphore_callback();
187 /* Builds a OrgUnitFilteringSelect limited to org units where you have
188 a given permission. */
189 function prepare_org_selector(perm) {
190 new openils.User().buildPermOrgSelector(
191 perm, org_selector, null,
194 org_selector, "onChange", set_grid_query_from_org_selector
196 set_grid_query_from_org_selector();
201 openils.Util.addOnLoad(
203 prepare_org_selector("VIEW_TRIGGER_EVENT");
207 <div dojoType="dijit.layout.ContentPane" layoutAlign="client">
208 <div dojoType="dijit.layout.ContentPane"
209 layoutAlign="top" class="oils-header-panel">
212 <span id="copy_specific" class="hidden">([% l('copy specific') %])</span>
213 <span id="patron_specific" class="hidden">([% l('patron specific') %])</span>
216 <button dojoType="dijit.form.Button"
217 onClick="act_on_events(grid.getSelectedIDs(), 'reset');">[% l('Reset Selected Events') %]</button>
218 <button dojoType="dijit.form.Button"
219 onClick="act_on_events(grid.getSelectedIDs(), 'cancel');">[% l('Cancel Selected Events') %]</button>
220 <button dojoType="dijit.form.Button"
221 onClick="grid.printSelected();">[% l('Print Selected Events') %]</button>
222 <button dojoType="dijit.form.Button"
223 onClick="print_all();">[% l('Print All Events') %]</button>
226 <div class="oils-acq-basic-roomy">
227 <label for="org_selector">[% l('Show events at and below') %]:</label>
229 id="org_selector" jsId="org_selector"
230 dojoType="openils.widget.OrgUnitFilteringSelect"
231 searchAttr="name" labelAttr="name">
235 <div style="float: left; width: 66%;">
238 dojoType="openils.widget.FlattenerGrid"
239 columnPersistKey='"ui.grid_columns.actor.user.event_log"'
243 showLoadFilter="true"
244 filterAlwaysInDiv="'filter_holder'"
245 filterInitializers="filter_initializers"
246 filterWidgetBuilders="filter_widget_builders"
247 filterSemaphore="filter_semaphore"
248 filterSemaphoreCallback="filter_semaphore_callback"
250 autoFieldFields="['target_hold','target_circ']"
251 defaultSort="['run_time']"
252 mapExtras="map_extras"
254 query="initial_query">
257 <th field="name" fpath="name" ffilter="true">Event Name</th>
258 <th field="reactor" fpath="reactor" ffilter="true"></th>
259 <th field="run_time" fpath="run_time" ffilter="true"></th><!-- XXX TODO formatters for *_time -->
260 <th field="add_time" fpath="add_time" ffilter="true" _visible="false"></th>
261 <th field="start_time" fpath="start_time" ffilter="true" _visible="false"></th>
262 <th field="update_time" fpath="update_time" ffilter="true" _visible="false"></th>
263 <th field="complete_time" fpath="complete_time" ffilter="true" _visible="false"></th>
264 <th field="id" fpath="id" ffilter="true" _visible="false"></th>
265 <th field="state" fpath="state" ffilter="true"></th>
266 <th field="target_circ_copy_barcode" fpath="target_circ.target_copy.barcode" ffilter="true">Target Circulation - Copy Barcode</th>
267 <th field="target_circ_copy_title" fpath="target_circ.target_copy.call_number.record.simple_record.title">Target Circulation - Title</th>
268 <th field="target_circ_copy_author" fpath="target_circ.target_copy.call_number.record.simple_record.author">Target Circulation - Author</th>
269 <th field="target_circ_patron_barcode" fpath="target_circ.usr.card.barcode" ffilter="true">Target Circulation - Patron Barcode</th>
270 <th field="target_hold_patron_barcode" fpath="target_hold.usr.card.barcode" ffilter="true">Target Hold - Patron Barcode</th>
275 <div style="float: right; width: 33%;">
276 <div id="filter_holder"></div>
278 <div style="clear: both;"></div>
281 <div dojoType="openils.widget.ProgressDialog" jsId="progress_dialog"></div>