--- /dev/null
+dojo.require("dijit.Tree");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.data.ItemFileWriteStore");
+dojo.require("dojo.dnd.Source");
+dojo.require("openils.vandelay.TreeDndSource");
+dojo.require("openils.vandelay.TreeStoreModel");
+dojo.require("openils.CGI");
+dojo.require("openils.User");
+dojo.require("openils.Util");
+dojo.require("openils.PermaCrud");
+dojo.require("openils.widget.ProgressDialog");
+
+var localeStrings, node_editor, _crads, CGI, tree, match_set;
+
+function _find_crad_by_name(name) {
+ for (var i = 0; i < _crads.length; i++) {
+ if (_crads[i].name() == name)
+ return _crads[i];
+ }
+ return null;
+}
+
+function NodeEditor() {
+ var self = this;
+
+ var _svf_select_template = null;
+ var _factories_by_type = {
+ "svf": function() {
+ if (!_svf_select_template) {
+ _svf_select_template = dojo.create(
+ "select", {"fmfield": "svf"}
+ );
+ for (var i=0; i<_crads.length; i++) {
+ dojo.create(
+ "option", {
+ "value": _crads[i].name(),
+ "innerHTML": _crads[i].label()
+ }, _svf_select_template
+ );
+ }
+ }
+
+ var select = dojo.clone(_svf_select_template);
+ dojo.attr(select, "id", "svf-select");
+ var label = dojo.create(
+ "label", {
+ "for": "svf-select", "innerHTML": "Single-Value-Field:"
+ }
+ );
+
+ var tr = dojo.create("tr");
+ dojo.place(label, dojo.create("td", null, tr));
+ dojo.place(select, dojo.create("td", null, tr));
+
+ return [tr];
+ },
+ "tag": function() {
+ var rows = [dojo.create("tr"), dojo.create("tr")];
+ dojo.create(
+ "label", {
+ "for": "tag-input", "innerHTML": "Tag:"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "input", {
+ "id": "tag-input",
+ "type": "text",
+ "size": 4,
+ "maxlength": 3,
+ "fmfield": "tag"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "label", {
+ "for": "subfield-input", "innerHTML": "Subfield: \u2021"
+ }, dojo.create("td", null, rows[1])
+ );
+ dojo.create(
+ "input", {
+ "id": "subfield-input",
+ "type": "text",
+ "size": 2,
+ "maxlength": 1,
+ "fmfield": "subfield"
+ }, dojo.create("td", null, rows[1])
+ );
+ return rows;
+ },
+ "bool_op": function() {
+ var tr = dojo.create("tr");
+ dojo.create(
+ "label",
+ {"for": "operator-select", "innerHTML": "Operator:"},
+ dojo.create("td", null, tr)
+ );
+ var select = dojo.create(
+ "select", {"fmfield": "bool_op", "id": "operator-select"},
+ dojo.create("td", null, tr)
+ );
+ dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
+ dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
+
+ return [tr];
+ }
+ };
+
+ function _simple_value_getter(control) {
+ if (typeof control.selectedIndex != "undefined")
+ return control.options[control.selectedIndex].value;
+ else if (dojo.attr(control, "type") == "checkbox")
+ return control.checked;
+ else
+ return control.value;
+ };
+
+ this._init = function(dnd_source, node_editor_container) {
+ this.dnd_source = dnd_source;
+ this.node_editor_container = dojo.byId(node_editor_container);
+ };
+
+ this.clear = function() {
+ this.dnd_source.selectAll().deleteSelectedNodes();
+ dojo.create(
+ "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
+ this.node_editor_container, "only"
+ );
+ this.dnd_source._ready = false;
+ };
+
+ this.is_sensible = function(mp) {
+ var need_one = 0;
+ ["tag", "svf", "bool_op"].forEach(
+ function(field) { if (mp[field]()) need_one++; }
+ );
+
+ if (need_one != 1) {
+ alert(localeStrings.POINT_NEEDS_ONE);
+ return false;
+ }
+
+ if (mp.tag()) {
+ if (
+ !mp.tag().match(/^\d{3}$/) ||
+ mp.subfield().length != 1 ||
+ !mp.subfield().match(/\S/) ||
+ mp.subfield().charCodeAt(0) < 32
+ ) {
+ alert(localeStrings.FAULTY_MARC);
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ this.build_vmsp = function() {
+ var match_point = new vmsp();
+ var controls = dojo.query("[fmfield]", this.node_editor_container);
+ for (var i = 0; i < controls.length; i++) {
+ var field = dojo.attr(controls[i], "fmfield");
+ var value = _simple_value_getter(controls[i]);
+ match_point[field](value);
+ }
+
+ if (!this.is_sensible(match_point)) return null; /* will alert() */
+ else return match_point;
+ };
+
+ this.update_draggable = function(draggable) {
+ var mp;
+
+ if (!(mp = this.build_vmsp())) return; /* will alert() */
+
+ draggable.match_point = mp;
+ dojo.attr(draggable, "innerHTML", render_vmsp_label(mp));
+ this.dnd_source._ready = true;
+ };
+
+ this._add_consistent_controls = function(tgt) {
+ if (!this._consistent_controls) {
+ var trs = dojo.query("[consistent-controls]");
+ this._consistent_controls = [];
+ for (var i = 0; i < trs.length; i++)
+ this._consistent_controls[i] = dojo.clone(trs[i]);
+ dojo.empty(trs[0].parentNode);
+ }
+
+ this._consistent_controls.forEach(
+ function(node) { dojo.place(dojo.clone(node), tgt); }
+ );
+ };
+
+ this.add = function(type) {
+ this.clear();
+
+ /* a representation, not the editing widgets, but will also carry
+ * the fieldmapper object when dragged to the tree */
+ var draggable = dojo.create(
+ "li", {"innerHTML": localeStrings.DEFINE_MP}
+ );
+
+ /* these are the editing widgets */
+ var table = dojo.create("table", {"className": "node-editor"});
+
+ var nodes = _factories_by_type[type]();
+ for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
+
+ this._add_consistent_controls(table);
+
+ dojo.create(
+ "input", {
+ "type": "submit", "value": localeStrings.OK,
+ "onclick": function() { self.update_draggable(draggable); }
+ }, dojo.create(
+ "td", {"colspan": 2, "align": "center"},
+ dojo.create("tr", null, table)
+ )
+ );
+
+ dojo.place(table, this.node_editor_container, "only");
+
+ this.dnd_source.insertNodes(false, [draggable]);
+
+ /* nice */
+ try { dojo.query("select, input", table)[0].focus(); }
+ catch(E) { console.log(String(E)); }
+
+ };
+
+ this._init.apply(this, arguments);
+}
+
+function render_vmsp_label(point, minimal) {
+ /* quick and dirty */
+ if (point.bool_op()) {
+ return (openils.Util.isTrue(point.negate()) ? "N" : "") +
+ point.bool_op();
+ } else if (point.svf()) {
+ return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
+ minimal ? point.svf() :
+ (point.svf() + " / " + _find_crad_by_name(point.svf()).label())
+ );
+ } else {
+ return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
+ point.tag() + " \u2021" + point.subfield();
+ }
+}
+
+function replace_mode(explicit) {
+ if (typeof explicit == "undefined")
+ tree.model.replace_mode ^= 1;
+ else
+ tree.model.replace_mode = explicit;
+
+ dojo.attr(
+ "replacer", "innerHTML",
+ localeStrings[
+ (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
+ ]
+ );
+ dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
+ "replacer", "replace-mode"
+ );
+}
+
+function delete_selected_in_tree() {
+ /* relies on the fact that we only have one tree that would have
+ * registered a dnd controller. */
+ _tree_dnd_controllers[0].getSelectedItems().forEach(
+ function(item) {
+ if (item === tree.model.root)
+ alert(localeStrings.LEAVE_ROOT_ALONE);
+ else
+ tree.model.store.deleteItem(item);
+ }
+ );
+}
+
+function new_match_set_tree() {
+ var point = new vmsp();
+ point.bool_op("AND");
+ return [
+ {
+ "id": "root",
+ "children": [],
+ "name": render_vmsp_label(point),
+ "match_point": point
+ }
+ ];
+}
+
+/* dojoize_match_set_tree() takes an argument, "point", that is actually a
+ * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
+ * that into a syntactically flat array but preserving the hierarchy
+ * semantically in the language used by dojo data stores, i.e.,
+ *
+ * [
+ * {'id': 'root', children:[{'_reference': '0'}, {'_reference': '1'}]},
+ * {'id': '0', children:[]},
+ * {'id': '1', children:[]}
+ * ],
+ *
+ */
+function dojoize_match_set_tree(point, refgen) {
+ var root = false;
+ if (!refgen) {
+ if (!point) {
+ return new_match_set_tree();
+ }
+ refgen = 0;
+ root = true;
+ }
+
+ var bathwater = point.children();
+ point.children([]);
+ var item = {
+ "id": (root ? "root" : refgen),
+ "name": render_vmsp_label(point),
+ "match_point": point.clone(),
+ "children": []
+ };
+ point.children(bathwater);
+
+ var results = [item];
+
+ if (point.children()) {
+ for (var i = 0; i < point.children().length; i++) {
+ var child = point.children()[i];
+ item.children.push({"_reference": ++refgen});
+ results = results.concat(
+ dojoize_match_set_tree(child, refgen)
+ );
+ }
+ }
+
+ return results;
+}
+
+function render_vms_metadata(match_set) {
+ dojo.byId("vms-name").innerHTML = match_set.name();
+ dojo.byId("vms-owner").innerHTML =
+ aou.findOrgUnit(match_set.owner()).name();
+ dojo.byId("vms-mtype").innerHTML = match_set.mtype();
+}
+
+function redraw_expression_preview() {
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ dojo.attr(
+ "expr-preview",
+ "innerHTML",
+ render_expression_preview(r)
+ );
+ }
+ );
+ }
+ );
+}
+
+function render_expression_preview(r) {
+ if (r.children().length) {
+ return "(" + r.children().map(render_expression_preview).join(
+ " " + render_vmsp_label(r) + " "
+ ) + ")";
+ } else if (!r.bool_op()) {
+ return render_vmsp_label(r, true /* minimal */);
+ } else {
+ return "()";
+ }
+}
+
+function save_tree() {
+ progress_dialog.show(true);
+
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ fieldmapper.standardRequest(
+ ["open-ils.vandelay",
+ "open-ils.vandelay.match_set.update"],/* XXX TODO */{
+ "params": [
+ openils.User.authtoken, match_set.id(), r
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ /* catch exceptions */
+ r = openils.Util.readResponse(r);
+
+ location.href = location.href;
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+}
+function my_init() {
+ progress_dialog.show(true);
+
+ dojo.requireLocalization("openils.vandelay", "match_set");
+ localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
+
+ pcrud = new openils.PermaCrud();
+ CGI = new openils.CGI();
+
+ if (!CGI.param("match_set")) {
+ alert(localeStrings.NO_CAN_DO);
+ progress_dialog.hide();
+ return;
+ }
+
+ render_vms_metadata(
+ match_set = pcrud.retrieve("vms", CGI.param("match_set"))
+ );
+
+ /* No-one should have hundreds of these or anything, but theoretically
+ * this could be problematic with a big enough list of crad objects. */
+ _crads = pcrud.retrieveAll("crad", {"order_by": {"crad": "label"}});
+
+ var match_set_tree = fieldmapper.standardRequest(
+ ["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
+ [openils.User.authtoken, CGI.param("match_set")]
+ );
+
+ var store = new dojo.data.ItemFileWriteStore({
+ "data": {
+ "identifier": "id",
+ "label": "name",
+ "items": dojoize_match_set_tree(match_set_tree)
+ }
+ });
+
+ var tree_model = new openils.vandelay.TreeStoreModel({
+ "store": store, "query": {"id": "root"}
+ });
+
+ var src = new dojo.dnd.Source("src-here");
+ tree = new dijit.Tree(
+ {
+ "model": tree_model,
+ "dndController": openils.vandelay.TreeDndSource,
+ "dragThreshold": 8,
+ "betweenThreshold": 5,
+ "persist": false
+ }, "tree-here"
+ );
+
+ node_editor = new NodeEditor(src, "node-editor-container");
+
+ replace_mode(0);
+
+ dojo.connect(
+ src, "onDndDrop", null,
+ function(source, nodes, copy, target) {
+ /* Because of the... interesting... characteristics of DnD
+ * design in dojo/dijit (at least as of 1.3), this callback will
+ * fire both for our working node dndSource and for the tree!
+ */
+ if (source == this)
+ node_editor.clear(); /* ... because otherwise this acts like a
+ copy operation no matter what the user
+ does, even though we really want a
+ "move." */
+ }
+ );
+
+ redraw_expression_preview();
+ node_editor.clear();
+ progress_dialog.hide();
+}
+
+openils.Util.addOnLoad(my_init);
+++ /dev/null
-dojo.require("dijit.Tree");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dojo.dnd.Source");
-dojo.require("openils.vandelay.TreeDndSource");
-dojo.require("openils.vandelay.TreeStoreModel");
-dojo.require("openils.CGI");
-dojo.require("openils.User");
-dojo.require("openils.Util");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.widget.ProgressDialog");
-
-var localeStrings, node_editor, _crads, CGI, tree, match_set;
-
-function _find_crad_by_name(name) {
- for (var i = 0; i < _crads.length; i++) {
- if (_crads[i].name() == name)
- return _crads[i];
- }
- return null;
-}
-
-function NodeEditor() {
- var self = this;
-
- var _svf_select_template = null;
- var _factories_by_type = {
- "svf": function() {
- if (!_svf_select_template) {
- _svf_select_template = dojo.create(
- "select", {"fmfield": "svf"}
- );
- for (var i=0; i<_crads.length; i++) {
- dojo.create(
- "option", {
- "value": _crads[i].name(),
- "innerHTML": _crads[i].label()
- }, _svf_select_template
- );
- }
- }
-
- var select = dojo.clone(_svf_select_template);
- dojo.attr(select, "id", "svf-select");
- var label = dojo.create(
- "label", {
- "for": "svf-select", "innerHTML": "Single-Value-Field:"
- }
- );
-
- var tr = dojo.create("tr");
- dojo.place(label, dojo.create("td", null, tr));
- dojo.place(select, dojo.create("td", null, tr));
-
- return [tr];
- },
- "tag": function() {
- var rows = [dojo.create("tr"), dojo.create("tr")];
- dojo.create(
- "label", {
- "for": "tag-input", "innerHTML": "Tag:"
- }, dojo.create("td", null, rows[0])
- );
- dojo.create(
- "input", {
- "id": "tag-input",
- "type": "text",
- "size": 4,
- "maxlength": 3,
- "fmfield": "tag"
- }, dojo.create("td", null, rows[0])
- );
- dojo.create(
- "label", {
- "for": "subfield-input", "innerHTML": "Subfield: \u2021"
- }, dojo.create("td", null, rows[1])
- );
- dojo.create(
- "input", {
- "id": "subfield-input",
- "type": "text",
- "size": 2,
- "maxlength": 1,
- "fmfield": "subfield"
- }, dojo.create("td", null, rows[1])
- );
- return rows;
- },
- "bool_op": function() {
- var tr = dojo.create("tr");
- dojo.create(
- "label",
- {"for": "operator-select", "innerHTML": "Operator:"},
- dojo.create("td", null, tr)
- );
- var select = dojo.create(
- "select", {"fmfield": "bool_op", "id": "operator-select"},
- dojo.create("td", null, tr)
- );
- dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
- dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
-
- return [tr];
- }
- };
-
- function _simple_value_getter(control) {
- if (typeof control.selectedIndex != "undefined")
- return control.options[control.selectedIndex].value;
- else if (dojo.attr(control, "type") == "checkbox")
- return control.checked;
- else
- return control.value;
- };
-
- this._init = function(dnd_source, node_editor_container) {
- this.dnd_source = dnd_source;
- this.node_editor_container = dojo.byId(node_editor_container);
- };
-
- this.clear = function() {
- this.dnd_source.selectAll().deleteSelectedNodes();
- dojo.create(
- "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
- this.node_editor_container, "only"
- );
- this.dnd_source._ready = false;
- };
-
- this.is_sensible = function(mp) {
- var need_one = 0;
- ["tag", "svf", "bool_op"].forEach(
- function(field) { if (mp[field]()) need_one++; }
- );
-
- if (need_one != 1) {
- alert(localeStrings.POINT_NEEDS_ONE);
- return false;
- }
-
- if (mp.tag()) {
- if (
- !mp.tag().match(/^\d{3}$/) ||
- mp.subfield().length != 1 ||
- !mp.subfield().match(/\S/) ||
- mp.subfield().charCodeAt(0) < 32
- ) {
- alert(localeStrings.FAULTY_MARC);
- return false;
- }
- }
-
- return true;
- };
-
- this.build_vmsp = function() {
- var match_point = new vmsp();
- var controls = dojo.query("[fmfield]", this.node_editor_container);
- for (var i = 0; i < controls.length; i++) {
- var field = dojo.attr(controls[i], "fmfield");
- var value = _simple_value_getter(controls[i]);
- match_point[field](value);
- }
-
- if (!this.is_sensible(match_point)) return null; /* will alert() */
- else return match_point;
- };
-
- this.update_draggable = function(draggable) {
- var mp;
-
- if (!(mp = this.build_vmsp())) return; /* will alert() */
-
- draggable.match_point = mp;
- dojo.attr(draggable, "innerHTML", render_vmsp_label(mp));
- this.dnd_source._ready = true;
- };
-
- this._add_consistent_controls = function(tgt) {
- if (!this._consistent_controls) {
- var trs = dojo.query("[consistent-controls]");
- this._consistent_controls = [];
- for (var i = 0; i < trs.length; i++)
- this._consistent_controls[i] = dojo.clone(trs[i]);
- dojo.empty(trs[0].parentNode);
- }
-
- this._consistent_controls.forEach(
- function(node) { dojo.place(dojo.clone(node), tgt); }
- );
- };
-
- this.add = function(type) {
- this.clear();
-
- /* a representation, not the editing widgets, but will also carry
- * the fieldmapper object when dragged to the tree */
- var draggable = dojo.create(
- "li", {"innerHTML": localeStrings.DEFINE_MP}
- );
-
- /* these are the editing widgets */
- var table = dojo.create("table", {"className": "node-editor"});
-
- var nodes = _factories_by_type[type]();
- for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
-
- this._add_consistent_controls(table);
-
- dojo.create(
- "input", {
- "type": "submit", "value": localeStrings.OK,
- "onclick": function() { self.update_draggable(draggable); }
- }, dojo.create(
- "td", {"colspan": 2, "align": "center"},
- dojo.create("tr", null, table)
- )
- );
-
- dojo.place(table, this.node_editor_container, "only");
-
- this.dnd_source.insertNodes(false, [draggable]);
-
- /* nice */
- try { dojo.query("select, input", table)[0].focus(); }
- catch(E) { console.log(String(E)); }
-
- };
-
- this._init.apply(this, arguments);
-}
-
-function render_vmsp_label(point, minimal) {
- /* quick and dirty */
- if (point.bool_op()) {
- return (openils.Util.isTrue(point.negate()) ? "N" : "") +
- point.bool_op();
- } else if (point.svf()) {
- return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
- minimal ? point.svf() :
- (point.svf() + " / " + _find_crad_by_name(point.svf()).label())
- );
- } else {
- return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
- point.tag() + " \u2021" + point.subfield();
- }
-}
-
-function replace_mode(explicit) {
- if (typeof explicit == "undefined")
- tree.model.replace_mode ^= 1;
- else
- tree.model.replace_mode = explicit;
-
- dojo.attr(
- "replacer", "innerHTML",
- localeStrings[
- (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
- ]
- );
- dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
- "replacer", "replace-mode"
- );
-}
-
-function delete_selected_in_tree() {
- /* relies on the fact that we only have one tree that would have
- * registered a dnd controller. */
- _tree_dnd_controllers[0].getSelectedItems().forEach(
- function(item) {
- if (item === tree.model.root)
- alert(localeStrings.LEAVE_ROOT_ALONE);
- else
- tree.model.store.deleteItem(item);
- }
- );
-}
-
-function new_match_set_tree() {
- var point = new vmsp();
- point.bool_op("AND");
- return [
- {
- "id": "root",
- "children": [],
- "name": render_vmsp_label(point),
- "match_point": point
- }
- ];
-}
-
-/* dojoize_match_set_tree() takes an argument, "point", that is actually a
- * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
- * that into a syntactically flat array but preserving the hierarchy
- * semantically in the language used by dojo data stores, i.e.,
- *
- * [
- * {'id': 'root', children:[{'_reference': '0'}, {'_reference': '1'}]},
- * {'id': '0', children:[]},
- * {'id': '1', children:[]}
- * ],
- *
- */
-function dojoize_match_set_tree(point, refgen) {
- var root = false;
- if (!refgen) {
- if (!point) {
- return new_match_set_tree();
- }
- refgen = 0;
- root = true;
- }
-
- var bathwater = point.children();
- point.children([]);
- var item = {
- "id": (root ? "root" : refgen),
- "name": render_vmsp_label(point),
- "match_point": point.clone(),
- "children": []
- };
- point.children(bathwater);
-
- var results = [item];
-
- if (point.children()) {
- for (var i = 0; i < point.children().length; i++) {
- var child = point.children()[i];
- item.children.push({"_reference": ++refgen});
- results = results.concat(
- dojoize_match_set_tree(child, refgen)
- );
- }
- }
-
- return results;
-}
-
-function render_vms_metadata(match_set) {
- dojo.byId("vms-name").innerHTML = match_set.name();
- dojo.byId("vms-owner").innerHTML =
- aou.findOrgUnit(match_set.owner()).name();
- dojo.byId("vms-mtype").innerHTML = match_set.mtype();
-}
-
-function redraw_expression_preview() {
- tree.model.getRoot(
- function(root) {
- tree.model.get_simple_tree(
- root, function(r) {
- dojo.attr(
- "expr-preview",
- "innerHTML",
- render_expression_preview(r)
- );
- }
- );
- }
- );
-}
-
-function render_expression_preview(r) {
- if (r.children().length) {
- return "(" + r.children().map(render_expression_preview).join(
- " " + render_vmsp_label(r) + " "
- ) + ")";
- } else if (!r.bool_op()) {
- return render_vmsp_label(r, true /* minimal */);
- } else {
- return "()";
- }
-}
-
-function save_tree() {
- progress_dialog.show(true);
-
- tree.model.getRoot(
- function(root) {
- tree.model.get_simple_tree(
- root, function(r) {
- fieldmapper.standardRequest(
- ["open-ils.vandelay",
- "open-ils.vandelay.match_set.update"],/* XXX TODO */{
- "params": [
- openils.User.authtoken, match_set.id(), r
- ],
- "async": true,
- "oncomplete": function(r) {
- progress_dialog.hide();
- /* catch exceptions */
- r = openils.Util.readResponse(r);
-
- location.href = location.href;
- }
- }
- );
- }
- );
- }
- );
-}
-function my_init() {
- progress_dialog.show(true);
-
- dojo.requireLocalization("openils.vandelay", "match_set");
- localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
-
- pcrud = new openils.PermaCrud();
- CGI = new openils.CGI();
-
- if (!CGI.param("match_set")) {
- alert(localeStrings.NO_CAN_DO);
- progress_dialog.hide();
- return;
- }
-
- render_vms_metadata(
- match_set = pcrud.retrieve("vms", CGI.param("match_set"))
- );
-
- /* No-one should have hundreds of these or anything, but theoretically
- * this could be problematic with a big enough list of crad objects. */
- _crads = pcrud.retrieveAll("crad", {"order_by": {"crad": "label"}});
-
- var match_set_tree = fieldmapper.standardRequest(
- ["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
- [openils.User.authtoken, CGI.param("match_set")]
- );
-
- var store = new dojo.data.ItemFileWriteStore({
- "data": {
- "identifier": "id",
- "label": "name",
- "items": dojoize_match_set_tree(match_set_tree)
- }
- });
-
- var tree_model = new openils.vandelay.TreeStoreModel({
- "store": store, "query": {"id": "root"}
- });
-
- var src = new dojo.dnd.Source("src-here");
- tree = new dijit.Tree(
- {
- "model": tree_model,
- "dndController": openils.vandelay.TreeDndSource,
- "dragThreshold": 8,
- "betweenThreshold": 5,
- "persist": false
- }, "tree-here"
- );
-
- node_editor = new NodeEditor(src, "node-editor-container");
-
- replace_mode(0);
-
- dojo.connect(
- src, "onDndDrop", null,
- function(source, nodes, copy, target) {
- /* Because of the... interesting... characteristics of DnD
- * design in dojo/dijit (at least as of 1.3), this callback will
- * fire both for our working node dndSource and for the tree!
- */
- if (source == this)
- node_editor.clear(); /* ... because otherwise this acts like a
- copy operation no matter what the user
- does, even though we really want a
- "move." */
- }
- );
-
- redraw_expression_preview();
- node_editor.clear();
- progress_dialog.hide();
-}
-
-openils.Util.addOnLoad(my_init);
--- /dev/null
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = 'Vandelay Match Sets' %]
+<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class="oils-header-panel">
+ <div>[% ctx.page_title %]</div>
+ <div>
+ <button dojoType="dijit.form.Button"
+ onClick="vms_grid.showCreateDialog()">New Match Set</button>
+ <button dojoType="dijit.form.Button"
+ onClick="vms_grid.deleteSelected()">Delete Selected</button>
+ </div>
+ </div>
+ <div>
+ Show sets owned at or below:
+ <select dojoType="openils.widget.OrgUnitFilteringSelect"
+ jsId="context_org_selector"></select>
+ </div>
+ <table jsId="vms_grid"
+ dojoType="openils.widget.AutoGrid"
+ query="{id: '*'}"
+ defaultCellWidth="'16em'"
+ fmClass="vms"
+ fieldorder="['name', 'owner']"
+ suppressEditFields="['id']"
+ showPaginator="true"
+ editOnEnter="true">
+ <thead>
+ <tr>
+ <th field="name" get="field_plus_id" formatter="tree_editor_link"></th>
+ <th field="owner" get="openils.widget.AutoGrid.orgUnitGetter">
+ </th>
+ </tr>
+ </thead>
+ </table>
+</div>
+<div class="hidden">
+ <select dojoType="dijit.form.FilteringSelect" jsId="mtype_selector">
+ [%# for the origin of these hard coded options, see the definition
+ of vandelay.match_set.mtype in 012.schema.vandelay.sql %]
+ <option value="biblio">biblio</option>
+ <option value="authority">authority</option>
+ <!-- XXX: nah <option value="mfhd">mfhd</option> -->
+ </select>
+</div>
+
+<script type="text/javascript">
+ dojo.require("dijit.form.FilteringSelect");
+ dojo.require("openils.widget.AutoGrid");
+ dojo.require("openils.widget.OrgUnitFilteringSelect");
+
+ var context_org;
+
+ function load_grid(search) {
+ if (!search) search = {"id": {"!=": null}};
+
+ vms_grid.loadAll({"order_by": {"vms": "name"}}, search);
+ }
+
+ function field_plus_id(rowIndex, item) {
+ if (!item) return null;
+ var datum = {};
+ datum[this.field] = this.grid.store.getValue(item, this.field);
+ datum.id = this.grid.store.getValue(item, "id");
+ return datum;
+ }
+
+ function tree_editor_link(datum) {
+ if (!datum) return "";
+ return '<a href="[% ctx.base_path %]/eg/conify/global/vandelay/match_set_tree?match_set=' +
+ datum.id + '">' + datum.name + '</a>';
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ new openils.User().buildPermOrgSelector(
+ "ADMIN_IMPORT_MATCH_SET", context_org_selector,
+ null, function() {
+ context_org_selector.onChange = function() {
+ context_org = this.attr("value");
+ vms_grid.resetStore();
+ load_grid({
+ "owner": aou.descendantNodeList(context_org, true)
+ });
+ };
+ }
+ );
+
+ vms_grid.overrideEditWidgets.mtype = mtype_selector;
+ vms_grid.overrideEditWidgets.mtype.shove = {"create": "biblio"};
+ load_grid();
+ }
+ );
+</script>
+[% END %]
--- /dev/null
+[% WRAPPER 'default/base.tt2' %]
+[% ctx.page_title = 'Vandelay Match Set Editor' %]
+<style type="text/css">
+ h1 { margin: 1ex 0; }
+ .outer { clear: both; margin-bottom: 1ex; }
+ button { margin: 0 0.5em; }
+ input[type=submit] { padding: 0 0.5em; }
+ #tree-here { margin-bottom: 1.5em; }
+ #vms-table { padding-bottom: 2ex; }
+ #vms-table th { text-align: right; }
+ #vms-table td { padding-left: 1em; }
+ #src-pane { float: left; width: 49%; }
+ #tree-pane { float: right; width: 50%; }
+ #submit-row { clear: both; text-align: center; padding-top: 1.5ex; }
+ #submit-row hr { margin: 1.5ex 0; }
+ #expr-preview-row { margin: 2ex 0; }
+ #expr-preview {
+ font-family: monospace;
+ font-size: 125%;
+ font-weight: bold;
+ background-color: #000066;
+ color: white;
+ }
+ .node-editor { margin-bottom: 1.5ex; }
+ .node-editor td { padding: 0.5ex; }
+ li { background-color: #ddd; }
+ .replace-mode { background-color: #990; color: #fff; }
+</style>
+<h1>[% ctx.page_title %]</h1>
+<table id="vms-table">
+ <tbody>
+ <tr>
+ <th>Match set name:</th>
+ <td><strong id="vms-name"></strong></td>
+ </tr>
+ <tr>
+ <th>Owning Library:</th>
+ <td id="vms-owner"></td>
+ </tr>
+ <tr>
+ <th>Type:</th>
+ <td id="vms-mtype"></td>
+ </tr>
+ </tbody>
+</table>
+<hr />
+<!-- XXX TODO
+ give some indication of which match set we're editing the tree for
+ -->
+<table class="hidden">
+ <tr consistent-controls="1">
+ <td>
+ <label for="quality-input"
+ title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
+ Quality:
+ </label>
+ </td>
+ <td>
+ <input id="quality-input" type="text" value="1"
+ size="4" maxlength="3" fmfield="quality" />
+ </td>
+ </tr>
+ <tr consistent-controls="1">
+ <td>
+ <label for="negate-input">Negate?</label>
+ </td>
+ <td>
+ <input id="negate-input" type="checkbox" fmfield="negate" />
+ </td>
+ </tr>
+</table>
+<div class="outer">
+ <div id="expr-preview-row">
+ <em>Your Expression:</em>
+ <span id="expr-preview"></span>
+ </div>
+ <div id="vmsp-buttons">
+ Add new
+ <button onclick="node_editor.add('svf');">Single-Value-Field</button>
+ <button onclick="node_editor.add('tag');">MARC Tag and Subfield</button>
+ <button onclick="node_editor.add('bool_op');">Boolean Operator</button>
+ </div>
+</div>
+<div class="outer" style="margin-top: 2ex;">
+ <div id="src-pane">
+ <div><big>Working Match Point</big></div>
+ <div>
+ <form id="node-editor-container" onsubmit="return false;"></form>
+ </div>
+ <ul id="src-here"></ul>
+ </div>
+
+ <div id="tree-pane">
+ <div><big>Your Expression</big></div>
+ <div id="tree-here"></div>
+ <div>
+ <button id="deleter" onclick="delete_selected_in_tree()">
+ Delete Selected Node
+ </button>
+ <button id="replacer" onclick="replace_mode()"></button>
+ </div>
+ </div>
+</div>
+<div id="submit-row">
+ <hr />
+ <button onclick="save_tree()">Save Changes</button>
+</div>
+<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
+<script type="text/javascript"
+ src="[% ctx.media_prefix %]/js/ui/default/conify/global/vandelay/match_set.js"></script>
+[% END %]
+++ /dev/null
-[% WRAPPER default/base.tt2 %]
-[% ctx.page_title = 'Vandelay Match Sets' %]
-<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
- <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class="oils-header-panel">
- <div>[% ctx.page_title %]</div>
- <div>
- <button dojoType="dijit.form.Button"
- onClick="vms_grid.showCreateDialog()">New Match Set</button>
- <button dojoType="dijit.form.Button"
- onClick="vms_grid.deleteSelected()">Delete Selected</button>
- </div>
- </div>
- <div>
- Show sets owned at or below:
- <select dojoType="openils.widget.OrgUnitFilteringSelect"
- jsId="context_org_selector"></select>
- </div>
- <table jsId="vms_grid"
- dojoType="openils.widget.AutoGrid"
- query="{id: '*'}"
- defaultCellWidth="'16em'"
- fmClass="vms"
- fieldorder="['name', 'owner']"
- suppressEditFields="['id']"
- showPaginator="true"
- editOnEnter="true">
- <thead>
- <tr>
- <th field="name" get="field_plus_id" formatter="tree_editor_link"></th>
- <th field="owner" get="openils.widget.AutoGrid.orgUnitGetter">
- </th>
- </tr>
- </thead>
- </table>
-</div>
-<div class="hidden">
- <select dojoType="dijit.form.FilteringSelect" jsId="mtype_selector">
- [%# for the origin of these hard coded options, see the definition
- of vandelay.match_set.mtype in 012.schema.vandelay.sql %]
- <option value="biblio">biblio</option>
- <option value="authority">authority</option>
- <!-- XXX: nah <option value="mfhd">mfhd</option> -->
- </select>
-</div>
-
-<script type="text/javascript">
- dojo.require("dijit.form.FilteringSelect");
- dojo.require("openils.widget.AutoGrid");
- dojo.require("openils.widget.OrgUnitFilteringSelect");
-
- var context_org;
-
- function load_grid(search) {
- if (!search) search = {"id": {"!=": null}};
-
- vms_grid.loadAll({"order_by": {"vms": "name"}}, search);
- }
-
- function field_plus_id(rowIndex, item) {
- if (!item) return null;
- var datum = {};
- datum[this.field] = this.grid.store.getValue(item, this.field);
- datum.id = this.grid.store.getValue(item, "id");
- return datum;
- }
-
- function tree_editor_link(datum) {
- if (!datum) return "";
- return '<a href="[% ctx.base_path %]/vandelay/match_set_tree?match_set=' +
- datum.id + '">' + datum.name + '</a>';
- }
-
- openils.Util.addOnLoad(
- function() {
- new openils.User().buildPermOrgSelector(
- "ADMIN_IMPORT_MATCH_SET", context_org_selector,
- null, function() {
- context_org_selector.onChange = function() {
- context_org = this.attr("value");
- vms_grid.resetStore();
- load_grid({
- "owner": aou.descendantNodeList(context_org, true)
- });
- };
- }
- );
-
- vms_grid.overrideEditWidgets.mtype = mtype_selector;
- vms_grid.overrideEditWidgets.mtype.shove = {"create": "biblio"};
- load_grid();
- }
- );
-</script>
-[% END %]
+++ /dev/null
-[% WRAPPER 'default/base.tt2' %]
-[% ctx.page_title = 'Vandelay Match Set Editor' %]
-<style type="text/css">
- h1 { margin: 1ex 0; }
- .outer { clear: both; margin-bottom: 1ex; }
- button { margin: 0 0.5em; }
- input[type=submit] { padding: 0 0.5em; }
- #tree-here { margin-bottom: 1.5em; }
- #vms-table { padding-bottom: 2ex; }
- #vms-table th { text-align: right; }
- #vms-table td { padding-left: 1em; }
- #src-pane { float: left; width: 49%; }
- #tree-pane { float: right; width: 50%; }
- #submit-row { clear: both; text-align: center; padding-top: 1.5ex; }
- #submit-row hr { margin: 1.5ex 0; }
- #expr-preview-row { margin: 2ex 0; }
- #expr-preview {
- font-family: monospace;
- font-size: 125%;
- font-weight: bold;
- background-color: #000066;
- color: white;
- }
- .node-editor { margin-bottom: 1.5ex; }
- .node-editor td { padding: 0.5ex; }
- li { background-color: #ddd; }
- .replace-mode { background-color: #990; color: #fff; }
-</style>
-<h1>[% ctx.page_title %]</h1>
-<table id="vms-table">
- <tbody>
- <tr>
- <th>Match set name:</th>
- <td><strong id="vms-name"></strong></td>
- </tr>
- <tr>
- <th>Owning Library:</th>
- <td id="vms-owner"></td>
- </tr>
- <tr>
- <th>Type:</th>
- <td id="vms-mtype"></td>
- </tr>
- </tbody>
-</table>
-<hr />
-<!-- XXX TODO
- give some indication of which match set we're editing the tree for
- -->
-<table class="hidden">
- <tr consistent-controls="1">
- <td>
- <label for="quality-input"
- title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
- Quality:
- </label>
- </td>
- <td>
- <input id="quality-input" type="text" value="1"
- size="4" maxlength="3" fmfield="quality" />
- </td>
- </tr>
- <tr consistent-controls="1">
- <td>
- <label for="negate-input">Negate?</label>
- </td>
- <td>
- <input id="negate-input" type="checkbox" fmfield="negate" />
- </td>
- </tr>
-</table>
-<div class="outer">
- <div id="expr-preview-row">
- <em>Your Expression:</em>
- <span id="expr-preview"></span>
- </div>
- <div id="vmsp-buttons">
- Add new
- <button onclick="node_editor.add('svf');">Single-Value-Field</button>
- <button onclick="node_editor.add('tag');">MARC Tag and Subfield</button>
- <button onclick="node_editor.add('bool_op');">Boolean Operator</button>
- </div>
-</div>
-<div class="outer" style="margin-top: 2ex;">
- <div id="src-pane">
- <div><big>Working Match Point</big></div>
- <div>
- <form id="node-editor-container" onsubmit="return false;"></form>
- </div>
- <ul id="src-here"></ul>
- </div>
-
- <div id="tree-pane">
- <div><big>Your Expression</big></div>
- <div id="tree-here"></div>
- <div>
- <button id="deleter" onclick="delete_selected_in_tree()">
- Delete Selected Node
- </button>
- <button id="replacer" onclick="replace_mode()"></button>
- </div>
- </div>
-</div>
-<div id="submit-row">
- <hr />
- <button onclick="save_tree()">Save Changes</button>
-</div>
-<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
-<script type="text/javascript"
- src="[% ctx.media_prefix %]/js/ui/default/vandelay/match_set.js"></script>
-[% END %]