[% WRAPPER base.tt2 %]
[% ctx.page_title = l('Configure Monograph Parts') %]
-<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
- <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel'>
- <div>[% l('Monograph Parts') %]</div>
- <div>
- <button dojoType='dijit.form.Button' onClick='monoPartGrid.showCreateDialog()'>[% l('New Monograph Part') %]</button>
- <button dojoType='dijit.form.Button' onClick='monoPartGrid.deleteSelected()'>[% l('Delete Selected') %]</button>
+ <div dojoType="dijit.layout.BorderContainer" design="headline" >
+
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class='oils-header-panel' region="top" style="height:30px;">
+ <div>[% l('Monograph Parts') %]</div>
+ <div>
+ <button dojoType='dijit.form.Button' onClick='openils.biblio.monographPartMerge.showMergeDialog(monoPartGrid)'>[% l('Merge Selected') %]</button>
+ <button dojoType='dijit.form.Button' onClick='monoPartGrid.showCreateDialog()'>[% l('New Monograph Part') %]</button>
+ <button dojoType='dijit.form.Button' onClick='monoPartGrid.deleteSelected()'>[% l('Delete Selected') %]</button>
+
+ </div>
</div>
- </div>
- <div>
- <table jsId="monoPartGrid"
+ <div id="sortContentPane" dojoType="dijit.layout.ContentPane" layoutAlign="client" region="center" style="width:500px;overflow-x:hidden;">
+ <table id="monoGrid" jsId="monoPartGrid"
dojoType="openils.widget.AutoGrid"
- autoHeight='true'
+ hidePaginator='true'
+ autoHeight='true'
fieldOrder="['label']"
+ displayLimit=0
suppressFields="['id','record','label_sortkey']"
suppressEditFields="['id','label_sortkey']"
query="{id: null}"
fmClass='bmp'
editOnEnter='true'/>
-</div>
+ </div>
+ </div>
<script type="text/javascript">
+ dojo.require('dijit.layout.BorderContainer');
dojo.require('openils.CGI');
dojo.require('openils.Util');
dojo.require('openils.widget.AutoGrid');
+ dojo.require('openils.biblio.monographPartMerge');
var cgi = new openils.CGI();
openils.Util.addOnLoad( function() {
monoPartGrid.overrideEditWidgets.record = new dijit.form.TextBox({"disabled": true});
monoPartGrid.overrideEditWidgets.record.shove = { create : cgi.param('r') };
- monoPartGrid.loadAll({order_by : {bmp : 'label'}}, {record : cgi.param('r')});
+ monoPartGrid.loadAll({order_by : [{class : 'bmp', field : 'label_sortkey'}]}, {record : cgi.param('r')});
});
</script>
[% END %]
-
-
--- /dev/null
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2014 C/W MARS Inc.
+ * Dan Pearl <dpearl@cwmars.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * Support for the facility to merge multiple part designations into
+ * one.
+ */
+
+if(!dojo._hasResource["openils.biblio.monographPartMerge"]) {
+ dojo._hasResource["openils.biblio.monographPartMerge"] = true;
+ dojo.provide("openils.biblio.monographPartMerge");
+ dojo.declare("openils.biblio.monographPartMerge", null, {});
+
+ /*
+ * Generate a pop-up to control part merging
+ */
+ openils.biblio.monographPartMerge.showMergeDialog = function(gridControl) {
+ dojo.requireLocalization("openils.biblio","biblio_messages");
+
+ var items = gridControl.getSelectedItems();
+ var total = items.length;
+
+ if (total < 2 ) // Validate number of selected items
+ {
+ alert(dojo.i18n.getLocalization("openils.biblio","biblio_messages").SELECT_TWO);
+ return;
+ }
+
+ var mergePartsPopup = new dijit.Dialog({title:
+ dojo.i18n.getLocalization("openils.biblio","biblio_messages").MERGE_PARTS_TITLE});
+
+ var mergeDiv = dojo.create("div");
+
+ /*
+ * Establish handler when an item is clicked upon
+ */
+ mergeDiv.processMerge = function (obj) {
+ mergePartsPopup.hide();
+ dojo.require('openils.PermaCrud');
+
+ var searchParams = {};
+ searchParams["part"] = new Array() ;
+
+ /*
+ * Establish a list of id's of monograph_parts that are affected by remap. Later, find
+ * all copy_part_map items that reference any of these parts
+ */
+
+ dojo.forEach (this.items,
+ function(item) {
+ searchParams["part"].push(String(item.id)) /* Must be String in json */
+ });
+ // var testString = searchParams["part"].join(', '); /* DEBUG */
+
+ var pcrud = new openils.PermaCrud();
+ var cpmList = pcrud.search("acpm", searchParams);
+
+ dojo.forEach(cpmList,
+ function (g) {
+ g.part(parseInt(obj.itemID)) /* Assign "winner" DB id of mono_part. */
+ });
+
+ if (cpmList.length > 0) {
+ pcrud.update( cpmList, {});
+ }
+
+ /*
+ * Close the connection and commit the transaction. This is necessary to do before
+ * the subsequent delete operation (because of ON DELETE CASCADE issues).
+ */
+
+ pcrud.disconnect();
+
+ /*
+ * Update the AutoGrid to delete the items being mapped out of existence so that
+ * the display reflects the updated situation.
+ * Then use a PermaCrud connection to delete/eliminate the object. This
+ * code is adapted from the delete case in AutoGrid.js. Note that this code
+ * uses a total==1 as the exit condition (because you are not deleting the
+ * winning/prevailing/surviving part.
+ */
+
+ dojo.forEach (items,
+ function(item) {
+ if (item.id != parseInt(obj.itemID)) {
+ var fmObject = new fieldmapper[gridControl.fmClass]().fromStoreItem(item);
+ new openils.PermaCrud()['eliminate'](
+ fmObject, {
+ oncomplete : function(r) {
+ gridControl.store.deleteItem(item);
+ if (--total == 1 && gridControl.onPostSubmit) {
+ gridControl.onPostSubmit();
+ }
+ }
+ }
+ );
+ }
+ }
+ );
+
+ };
+
+ mergeDiv.innerHTML = "<div class=\"biblio-merge-prevail-title\" >" +
+ dojo.i18n.getLocalization("openils.biblio","biblio_messages").CLICK_PREVAILING +
+ "</div>";
+ mergeDiv.items = items;
+
+ /*
+ * Create a DIV for each selected item, and put in the container DIV
+ */
+ for (var i = 0; i < total; i++) {
+ var newDiv = dojo.create("div");
+ newDiv.className = "biblio-merge-item";
+ newDiv.itemID = items[i].id;
+ newDiv.onclick = function() {mergeDiv.processMerge(this);};
+ var newText = new String(items[i].label);
+
+ /* To make spacing more visible, replace spaces with a middot character */
+ newText = newText.replace(/ /g, String.fromCharCode(183) /* middot*/);
+ newDiv.appendChild(document.createTextNode( newText ));
+ mergeDiv.appendChild(newDiv);
+ }
+ mergePartsPopup.setContent(mergeDiv);
+
+ mergePartsPopup.show();
+
+ };
+
+}
--- /dev/null
+New Feature: Monograph Part Merging
+===================================
+
+The monograph part list for a bibliographic record may, over time, diverge from the
+proscribed format, resulting in multiple labels for what are essentially the same
+item. For instance, ``++Vol.{nbsp}1++'' may have variants like ``++V.1++'', ``++Vol{nbsp}1++'', or ``++{nbsp}Vol.{nbsp}1++'' (leading space).
+This feature will allow catalog staff to collapse the variants into one value.
+
+In the Monograph Parts display:
+
+. Click the checkbox for all items you wish to merge including the one you wish to prevail when done.
+. Click on the ``Merge Selected'' button. A pop-up window will list the selected items in
+a monospaced font, with blanks represented by a middle-dot character for more visibility.
+. Click on the item you wish to prevail.
+
+The undesired part labels will be deleted, and any copies that previously used those labels will
+now use the prevailing label.