source: main/trunk/greenstone3/web/interfaces/default/js/documentedit_scripts_usercomments.js@ 38766

Last change on this file since 38766 was 38431, checked in by anupama, 7 months ago
  1. For editing user comments with the document editor, I want to set metamode to override just once instead of for each docid (that is, for each docrecord). This didn't work before because the perl code didn't allow it as optional argument, although the actual set-metadata-array() perl subroutines were coded for it. 2. The Java code needs to allow an array of document records, without requiring that each docrecord contains a metatable field (a sub array of meta records). This is because the perl code set-metadata-array() subroutines allowed for this, but when set-metadata functionality started needing authentication/user editing powers (authentication goes through java, which then relays the command to perl), this pre-existing, optional way of setting metadata in the perl code wasn't opened up through java.
File size: 12.2 KB
Line 
1/** Javascript file for editing and especially deleting user comments in a documentediting situation */
2
3// Function called by documentedit_scripts_util.js when saving and rebuilding.
4// This function should return usercomments data (only exists for doc root's section) so that
5// setMetadataArray can be called for doc root and the entire collection rebuilt with the changes
6function getUserCommentsEditDataForSaving(userCommentsMetaFields, userCommentsRowsChanged,
7 docids_to_delCommentsMetapositions) {
8 // https://medium.com/@martin.crabtree/javascript-tracking-key-value-pairs-using-hashmaps-7de6df598257
9 // Just using JS object. Not using Map in case it's not always compatible with older
10 // browsers we still support on 32 bit linux.
11 var docIDs_to_metatable_map = {};
12
13 var i = 0;
14 for (i = 0; i < userCommentsRowsChanged.length; i++) {
15 // need docID, metaname, metaval, metapos, and set metamode to override
16
17 var changedElem = userCommentsRowsChanged[i];
18 //console.dir(changedElem);
19
20 var metaval = changedElem.value; //changedElem.textContent; // gets orig value
21 metaval = metaval.replace(/&nbsp;/g, " "); // copied from docedit_scripts_utl, when procsesing the array called changes.
22 metaval = encodeDelimiters(metaval);
23
24 var currentElem = changedElem;
25 while((currentElem = currentElem.parentNode).tagName != "TABLE");
26 var docID = currentElem.getAttribute("id").substring("usercomments-".length);
27
28 currentElem = changedElem;
29 while((currentElem = currentElem.parentNode).tagName != "TR");
30 var metapos = currentElem.firstElementChild.textContent;
31
32 // don't consider edits in user comment rows that have also been marked for deletion
33 var metapositionsToBeDeleted = docids_to_delCommentsMetapositions[docID];
34 if(metapositionsToBeDeleted !== undefined) {
35 // https://www.digitalocean.com/community/tutorials/js-array-search-methods
36 if(metapositionsToBeDeleted.indexOf(metapos) != -1) {
37 alert("Discarding edit at metapos " + metapos + " as user comment row is to be deleted.");
38 continue;
39 }
40 }
41
42 //currentElem = changedElem.parentNode; //TD
43 currentElem = changedElem;
44 while((currentElem = currentElem.parentNode).tagName != "TD");
45 // count number of previous siblings
46 var th = 0;
47 while((currentElem = currentElem.previousSibling) != null) {
48 th++;
49 }
50 var metaname = userCommentsMetaFields[th-1]; // first column is invisible metapos col
51
52 //alert("docid: " + docID + " metaname: " + metaname + " metaval: " + metaval + " metapos: " + metapos);
53
54 // https://dmitripavlutin.com/check-if-object-has-property-javascript/
55 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null
56 if(docIDs_to_metatable_map[docID] === undefined) {
57 docIDs_to_metatable_map[docID] = [];
58 }
59 docIDs_to_metatable_map[docID].push({metaname:metaname,metavalue:metaval,metapos:metapos});
60 }
61
62 var docids = Object.keys(docIDs_to_metatable_map);
63 i = 0;
64 var docArray = [];
65 for(i = 0; i < docids.length; i++) {
66 var docid = docids[i];
67 var metatable = docIDs_to_metatable_map[docid];
68 docArray.push({
69 docid:docid,
70 metatable:metatable/*,
71 metamode:"override"*/ // metamode set universally to override in
72 // documentedit_scripts_util.js::processChangesLoop when change.type=editUserComments
73 });
74 }
75
76 //alert("editing: " + JSON.stringify(docArray));
77
78 return docArray;
79}
80
81// Function called by documentedit_scripts_util.js when saving and rebuilding.
82// This function should return usercomments data (only exists for doc root's section) so that
83// removeMetadataArray can be called for doc root and the collection rebuilt with the deletions
84function getUserCommentsDeletions(userCommentsMetaFields, docids_to_delCommentsMetapositions) {
85
86 var docids = Object.keys(docids_to_delCommentsMetapositions);
87 var docArray = [];
88 var i = 0;
89 for(i = 0; i < docids.length; i++) { //if(docids.length > 0) {
90 var _docid = docids[i];
91 var delCommentsMetapositions = docids_to_delCommentsMetapositions[_docid].sort();
92 // sort unnecessary as modmetadataaction.pm ensures (reverse) sort of metapositions
93
94 // build up the data structure for all the usercomments to be deleted
95 if(delCommentsMetapositions.length > 0) {
96 //console.log("About to delete position: " + delCommentsMetapositions);
97 var timestamp_rec = {
98 metaname: userCommentsMetaFields[0],
99 metapositions: delCommentsMetapositions
100 };
101 var username_rec = {
102 metaname: userCommentsMetaFields[1],
103 metapositions: delCommentsMetapositions
104 };
105 var comment_rec = {
106 metaname: userCommentsMetaFields[2],
107 metapositions: delCommentsMetapositions
108 };
109
110
111 var doc_rec = {
112 docid: _docid,
113 metatable: [username_rec, timestamp_rec, comment_rec]
114 };
115
116 docArray.push(doc_rec);
117 }
118 }
119
120 //alert("deleting: " + JSON.stringify(docArray));
121 return docArray;
122}
123
124// Determine if the user comment edits should be a synchronous AJAX call
125function forceSyncUserCommentsEdits(editsDocArray, docids_to_delCommentsMetapositions) {
126 var forceSync = false;
127 var docids = Object.keys(docids_to_delCommentsMetapositions);
128 if(docids.length == 0) { // no user comments deletions, so can process user comment edits async
129 return false;
130 }
131 var edits = Object.keys(editsDocArray);
132 if(edits.length == 0) { // no user comments edits
133 return false;
134 }
135
136 var i = 0;
137 for(i = 0; i < docids.length; i++) {
138 var docid = docids[i];
139
140 // sort metapositions of deletes to get at lowest metaposition for this docid
141 var metapositions = docids_to_delCommentsMetapositions[docid].sort(); // non-zero length array
142 var lowestDelMetapos = metapositions[0]; // lowest metaposition at lowest index
143
144 // https://javascript.plainenglish.io/check-if-an-array-contains-an-object-with-a-certain-property-value-in-javascript-5325295a5820
145 // https://stackoverflow.com/questions/237104/how-do-i-check-if-an-array-includes-a-value-in-javascript/24827594#24827594
146 // https://stackoverflow.com/questions/254302/how-can-i-determine-the-type-of-an-html-element-in-javascript
147
148 var match_docRecord = editsDocArray.find((doc_rec) => doc_rec.docid === docid);
149 if (match_docRecord) { // defined: this docid exists in an object in array
150 //if(editsDocArray.some(item => item.docid === docid)) { // this docid exists in object
151 //if(editsDocArray[docid] !== undefined) {
152 // compare lowest metaposition of user comment to be deleted for this docid
153 // against the highest metapos of user comment being edited for this docid
154 // Metapositions array of deletes would contain metapos in ascending order
155 var metatable = match_docRecord.metatable; // array of non-zero length
156 //alert("Found docid match " + JSON.stringify(match_docRecord) + " comparing low metapos " + lowestDelMetapos);
157
158 // https://www.digitalocean.com/community/tutorials/js-array-search-methods
159 // Get array of user comment edits that are affected by deletions happening earlier
160 // in the file (deletes that have a lower metapos than the metapos of the edit).
161 var editsAffectedByDeletes = metatable.filter(meta_rec => meta_rec.metapos >= lowestDelMetapos);
162 if(editsAffectedByDeletes.length > 0) { //if any edits affected by dels, forceSync ajax
163 forceSync = true; // ensure we process all edits first before processing deletes
164 //alert("FORCE_SYNC because " + JSON.stringify(editsAffectedByDeletes)
165 // + " are affected by deletes starting: " + lowestDelMetapos);
166 } // else all user comment edits for this docid happen earlier (lower metapos) to deletes
167 }
168 }
169 return forceSync;
170}
171
172function addEditUserCommentsLink(cell) {
173 cell = $(cell);
174 var doc_id = cell.attr("id").substring(6);
175
176 var edit_usercomments_table = document.getElementById("usercomments-"+doc_id);
177
178 var edit_meta_table = document.getElementById("meta"+doc_id);
179 var comments = edit_meta_table.querySelectorAll('.metaTableCellArea.gsusercomment');
180 var gsMetaPrefix = "gs"; // metadata name prefix
181
182 var unames = [];
183 var timestamps = [];
184
185
186 if(comments.length <= 0) {
187 gsMetaPrefix = "";
188
189 comments = edit_meta_table.querySelectorAll('.metaTableCellArea.usercomment');
190 if(comments.length <= 0) {
191 return;
192 }
193 }
194
195
196 var classname = ".metaTableCellArea." + gsMetaPrefix + "username";
197 unames = edit_meta_table.querySelectorAll(classname);
198 classname = ".metaTableCellArea." + gsMetaPrefix + "usertimestamp";
199 timestamps = edit_meta_table.querySelectorAll(classname);
200
201 //console.log(comments[0].textContent);
202 //console.log(unames[0].textContent);
203 //console.log(timestamps[0].textContent);
204
205
206 var headerRow = document.createElement("tr");
207 edit_usercomments_table.appendChild(headerRow);
208
209 var i = 0;
210 // work with tbody child of metadatatable's table element
211 edit_meta_table = edit_meta_table.firstElementChild;
212 for(i = 0; i < comments.length; i++) {
213 var newRow = document.createElement("tr");
214 edit_usercomments_table.appendChild(newRow);
215
216 var rowNumCell, txtNode;
217 if(i == 0) {
218 rowNumCell = document.createElement("th");
219 rowNumCell.setAttribute("class", "metaposCell");
220 txtNode = document.createTextNode("metapos");
221 rowNumCell.appendChild(txtNode);
222 headerRow.appendChild(rowNumCell);
223 }
224 rowNumCell = document.createElement("td");
225 rowNumCell.setAttribute("class", "metaposCell");
226 txtNode = document.createTextNode(i+"");
227 rowNumCell.appendChild(txtNode);
228 newRow.appendChild(rowNumCell);
229
230
231 //Row we work with each time: get the closest ancestor of comments[i] that is a <tr>
232 // If you change the order the rows are moved into usercomments-table below, the
233 // userCommentsMetaFields[] array ordering in documentedit_scripts_util.js will be affected
234 shiftRowData(timestamps[i].closest("tr"), edit_meta_table, newRow, i, headerRow);
235 shiftRowData(unames[i].closest("tr"), edit_meta_table, newRow, i, headerRow);
236 shiftRowData(comments[i].closest("tr"), edit_meta_table, newRow, i, headerRow);
237
238 //console.log("NEWROW:" + newRow.firstElementChild.textContent);
239 addRemoveLinkToRow(newRow);
240
241 }
242
243 var row = cell.parent();
244 var newCell = $("<td>", {
245 "style": "font-size:0.7em; padding:0px 10px",
246 "class": "editMapGPSButton"
247 });
248 var linkSpan = $("<span>", {
249 "class": "ui-state-default ui-corner-all",
250 "style": "padding: 2px; float:left;"
251 });
252
253 var linkLabel = $("<span>" + gs.text.de.edit_usercomments + "</span>");
254 var linkIcon = $("<span>", {
255 "class": "ui-icon ui-icon-folder-collapsed"
256 });
257 newCell.linkIcon = linkIcon;
258 newCell.linkLabel = linkLabel;
259
260 var uList = $("<ul>", {
261 "style": "outline: 0 none; margin:0px; padding:0px;"
262 });
263 var labelItem = $("<li>", {
264 "style": "float:left; list-style:none outside none;"
265 });
266 var iconItem = $("<li>", {
267 "style": "float:left; list-style:none outside none;"
268 });
269
270 uList.append(iconItem);
271 uList.append(labelItem);
272 labelItem.append(linkLabel);
273 iconItem.append(linkIcon);
274
275 var newLink = $("<a>", {
276 "href": "javascript:;"
277 });
278
279 newLink.on("click", function () {
280 if (edit_usercomments_table.style.display == "none") {
281 linkLabel.html(gs.text.de.hide_usercomments);
282 linkIcon.attr("class", "ui-icon ui-icon-folder-open");
283 edit_usercomments_table.style.display = "block";
284 } else {
285 linkLabel.html(gs.text.de.edit_usercomments);
286 linkIcon.attr("class", "ui-icon ui-icon-folder-collapsed");
287 edit_usercomments_table.style.display = "none";
288
289 }
290 });
291
292 newLink.append(uList);
293 linkSpan.append(newLink);
294 newCell.append(linkSpan);
295 row.append(newCell);
296}
297
298function makeHeaderCellFrom(row, headerRow) {
299 var cellName = row.querySelector('.metaTableCellName').textContent;
300 var headerCell = document.createElement("th");
301 headerCell.setAttribute("class", "metaTableCellName");
302 var txt = document.createTextNode(cellName);
303 headerCell.appendChild(txt);
304 headerRow.appendChild(headerCell);
305}
306
307function shiftRowData(row, edit_meta_table, newRow, rownum, headerRow) {
308 if(rownum == 0) {
309 makeHeaderCellFrom(row, headerRow);
310 }
311 edit_meta_table.removeChild(row);
312 var oldCell = row.querySelector('.metaTableCell');
313 newRow.appendChild(oldCell);
314 var el = oldCell.querySelector('.metaTableCellArea');
315 el.classList.add("threecol");
316}
Note: See TracBrowser for help on using the repository browser.