merge master into branch

This commit is contained in:
aynsix
2021-03-26 10:36:38 +03:00
20 changed files with 570 additions and 463 deletions

View File

@@ -13,5 +13,5 @@ module.exports = {
setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js',
// change this version when you change JS file for lazy loading
jsFileVersion: 11
jsFileVersion: 12
};

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=11";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=12";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=11";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=12";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=11";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=12";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=11";
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=12";
/******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {

View File

@@ -11491,7 +11491,6 @@ var thesaurusService = function thesaurusService(services) {
(0, _jquery2.default)('#THPD_T_tree').droppable({
accept: function accept(elem) {
var lstbr = searchSelection.asArray;
console.log("lstbr", lstbr);
dragUniqueSbid = null;
lstbr.forEach(function (sbid_rid) {
@@ -11503,7 +11502,7 @@ var thesaurusService = function thesaurusService(services) {
dragLstRecords = lstbr.join(';'); // a list as expected for RecordsRequest::fromRequest
(0, _jquery2.default)(this).removeClass('draggingOver');
console.log("accept", elem);
// console.log("accept", elem);
// if ($(elem).hasClass('grouping') && !$(elem).hasClass('SSTT')) {
// return true;
// }
@@ -11673,10 +11672,55 @@ var thesaurusService = function thesaurusService(services) {
'lst': lstRecords
}, function (dlgData) {
var $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
$container.addClass('black-dialog-wrap');
dlg.setOption("title", dlgData.dlg_title);
dlg.setContent(dlgData.dlg_content);
var $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
/**
* update the dlg (show/hide selects & buttons) depending on form status
*/
var updateUx = function updateUx() {
// console.log("====== update =========================");
var okbutton = false; // must we show the ok button ?
/**
* loop on advanced-mode fields
*/
(0, _jquery2.default)('#TXCLASSIFICATION_ADVANCED .action', $container).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
switch ($this.val()) {// action
case "":
// first "select..." option
(0, _jquery2.default)('.value_container._' + n, $container).hide();
break;
case "clear":
// clear a mono-value : no need value selection
(0, _jquery2.default)('.value_container._' + n, $container).hide();
okbutton = true;
break;
default:
(0, _jquery2.default)('.value_container._' + n, $container).show();
okbutton = true;
}
});
/**
* if the "simple-mode" is front, show "ok" button
*/
var seltab_idx = (0, _jquery2.default)('.tabs', $container).tabs('option', 'active');
var seltab_id = (0, _jquery2.default)('.tabs>UL.ui-tabs-nav>LI:eq(' + seltab_idx + ')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
if (seltab_id === "SIMPLE") {
// simple ux: ok is possible
okbutton = true;
}
(0, _jquery2.default)(' .okbutton', $container).toggle(okbutton);
};
/**
* add buttons
@@ -11687,31 +11731,60 @@ var thesaurusService = function thesaurusService(services) {
*/
{
text: "Ok",
class: "fieldSelected",
class: "fieldSelected okbutton",
style: "display:none",
click: function click() {
// don't submit the complex form, better build json
var actions = [];
(0, _jquery2.default)(' .fieldSelect', $container).filter(function () {
return (0, _jquery2.default)(this).prop('selectedIndex') > 0;
}).each(function () {
var n = (0, _jquery2.default)(this).data('n');
var action = (0, _jquery2.default)(' .actionSelect._' + n + ':visible', $container).val();
if (action === 'replace') {
// replace all multi-v needs a "replace_by" arg
/**
* find the active tab ("SIMPLE" or "ADVANCED")
*/
var seltab_idx = (0, _jquery2.default)('.tabs', $container).tabs('option', 'active');
var seltab_id = (0, _jquery2.default)('.tabs>UL.ui-tabs-nav>LI:eq(' + seltab_idx + ')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
/**
* extract data only from the front tab (div)
*/
var box = (0, _jquery2.default)("#TXCLASSIFICATION_" + seltab_id, $container);
(0, _jquery2.default)('.action', box).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
var action = $this.val();
if (action !== "") {
var field = (0, _jquery2.default)('.field._' + n, box).val();
var value = (0, _jquery2.default)('.value._' + n, box).val();
switch (action) {
case "replace":
// replace all multi-values
actions.push({
'field_name': (0, _jquery2.default)(this).val(),
'action': action,
'replace_with': (0, _jquery2.default)(' .synonym._' + n, $container).val()
'field_name': field,
'action': "replace",
'replace_with': value
});
} else {
break;
case "clear":
// clear a mono-value
actions.push({
'field_name': (0, _jquery2.default)(this).val(),
'field_name': field,
'action': "delete"
});
break;
default:
// all other actions don't need patch
actions.push({
'field_name': field,
'action': action,
'value': (0, _jquery2.default)(' .synonym._' + n, $container).val()
'value': value
});
}
}
});
/**
* post actions
*/
data = {
'records': dlgData.rec_refs,
'actions': {
@@ -11719,13 +11792,14 @@ var thesaurusService = function thesaurusService(services) {
}
};
// console.log(data);
_jquery2.default.ajax({
url: dlgData.commit_url,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
success: function success(data, textStatus) {
console.log(data);
success: function success() {
dlg.close();
}
});
@@ -11733,6 +11807,7 @@ var thesaurusService = function thesaurusService(services) {
return false;
}
},
/**
* Cancel button
*/
@@ -11744,49 +11819,15 @@ var thesaurusService = function thesaurusService(services) {
}]);
/**
* when a destination field is changed, show/hide the "action" menus
* format the dlg content
*/
(0, _jquery2.default)(' .fieldSelect', $container).change(function () {
var n_changed = (0, _jquery2.default)(this).data('n');
(0, _jquery2.default)('SELECT', $container).menu();
(0, _jquery2.default)('.tabs', $container).tabs({ 'activate': updateUx });
(0, _jquery2.default)('.action', $container).change(updateUx);
// show "action" menus depending on the selected fields (none, mono, multi)
var oneFieldSet = false; // if at least one destination field is set, we will show some elements
(0, _jquery2.default)(' .fieldSelect', $container).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
var selIndex = $this.prop('selectedIndex');
if (selIndex > 0) {
if (n === n_changed) {
// reset both mono an multi menus
(0, _jquery2.default)(' .actionSelect._' + n, $container).prop('selectedIndex', 0);
}
var multi = !!(0, _jquery2.default)('option:eq(' + selIndex + ')', $this).data('multi');
if (multi) {
(0, _jquery2.default)(' .actionSelect._' + n + '.mono', $container).hide();
(0, _jquery2.default)(' .actionSelect._' + n + '.multi', $container).show();
} else {
(0, _jquery2.default)(' .actionSelect._' + n + '.multi', $container).hide();
(0, _jquery2.default)(' .actionSelect._' + n + '.mono', $container).show();
}
oneFieldSet = true;
} else {
// hide both menus
(0, _jquery2.default)(' .actionSelect._' + n).hide();
}
});
(0, _jquery2.default)(' .fieldSelected', $container).toggle(oneFieldSet);
}).change(); // enforce initial update
/**
* the "other values" button
*/
(0, _jquery2.default)(' .moreFields BUTTON', $container).click(function () {
(0, _jquery2.default)(' .moreFields', $container).hide();
(0, _jquery2.default)(' .other', $container).show();
return false;
});
updateUx(); // enforce initial update;
}).fail(function (jqxhr, textStatus, error) {
// the dlg content failed, report onto the dlg (better than forever loading)
var err = textStatus + ", " + error;
dlg.setContent("Request Failed: " + err);
});

View File

@@ -11491,7 +11491,6 @@ var thesaurusService = function thesaurusService(services) {
(0, _jquery2.default)('#THPD_T_tree').droppable({
accept: function accept(elem) {
var lstbr = searchSelection.asArray;
console.log("lstbr", lstbr);
dragUniqueSbid = null;
lstbr.forEach(function (sbid_rid) {
@@ -11503,7 +11502,7 @@ var thesaurusService = function thesaurusService(services) {
dragLstRecords = lstbr.join(';'); // a list as expected for RecordsRequest::fromRequest
(0, _jquery2.default)(this).removeClass('draggingOver');
console.log("accept", elem);
// console.log("accept", elem);
// if ($(elem).hasClass('grouping') && !$(elem).hasClass('SSTT')) {
// return true;
// }
@@ -11673,10 +11672,55 @@ var thesaurusService = function thesaurusService(services) {
'lst': lstRecords
}, function (dlgData) {
var $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
$container.addClass('black-dialog-wrap');
dlg.setOption("title", dlgData.dlg_title);
dlg.setContent(dlgData.dlg_content);
var $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
/**
* update the dlg (show/hide selects & buttons) depending on form status
*/
var updateUx = function updateUx() {
// console.log("====== update =========================");
var okbutton = false; // must we show the ok button ?
/**
* loop on advanced-mode fields
*/
(0, _jquery2.default)('#TXCLASSIFICATION_ADVANCED .action', $container).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
switch ($this.val()) {// action
case "":
// first "select..." option
(0, _jquery2.default)('.value_container._' + n, $container).hide();
break;
case "clear":
// clear a mono-value : no need value selection
(0, _jquery2.default)('.value_container._' + n, $container).hide();
okbutton = true;
break;
default:
(0, _jquery2.default)('.value_container._' + n, $container).show();
okbutton = true;
}
});
/**
* if the "simple-mode" is front, show "ok" button
*/
var seltab_idx = (0, _jquery2.default)('.tabs', $container).tabs('option', 'active');
var seltab_id = (0, _jquery2.default)('.tabs>UL.ui-tabs-nav>LI:eq(' + seltab_idx + ')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
if (seltab_id === "SIMPLE") {
// simple ux: ok is possible
okbutton = true;
}
(0, _jquery2.default)(' .okbutton', $container).toggle(okbutton);
};
/**
* add buttons
@@ -11687,31 +11731,60 @@ var thesaurusService = function thesaurusService(services) {
*/
{
text: "Ok",
class: "fieldSelected",
class: "fieldSelected okbutton",
style: "display:none",
click: function click() {
// don't submit the complex form, better build json
var actions = [];
(0, _jquery2.default)(' .fieldSelect', $container).filter(function () {
return (0, _jquery2.default)(this).prop('selectedIndex') > 0;
}).each(function () {
var n = (0, _jquery2.default)(this).data('n');
var action = (0, _jquery2.default)(' .actionSelect._' + n + ':visible', $container).val();
if (action === 'replace') {
// replace all multi-v needs a "replace_by" arg
/**
* find the active tab ("SIMPLE" or "ADVANCED")
*/
var seltab_idx = (0, _jquery2.default)('.tabs', $container).tabs('option', 'active');
var seltab_id = (0, _jquery2.default)('.tabs>UL.ui-tabs-nav>LI:eq(' + seltab_idx + ')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
/**
* extract data only from the front tab (div)
*/
var box = (0, _jquery2.default)("#TXCLASSIFICATION_" + seltab_id, $container);
(0, _jquery2.default)('.action', box).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
var action = $this.val();
if (action !== "") {
var field = (0, _jquery2.default)('.field._' + n, box).val();
var value = (0, _jquery2.default)('.value._' + n, box).val();
switch (action) {
case "replace":
// replace all multi-values
actions.push({
'field_name': (0, _jquery2.default)(this).val(),
'action': action,
'replace_with': (0, _jquery2.default)(' .synonym._' + n, $container).val()
'field_name': field,
'action': "replace",
'replace_with': value
});
} else {
break;
case "clear":
// clear a mono-value
actions.push({
'field_name': (0, _jquery2.default)(this).val(),
'field_name': field,
'action': "delete"
});
break;
default:
// all other actions don't need patch
actions.push({
'field_name': field,
'action': action,
'value': (0, _jquery2.default)(' .synonym._' + n, $container).val()
'value': value
});
}
}
});
/**
* post actions
*/
data = {
'records': dlgData.rec_refs,
'actions': {
@@ -11719,13 +11792,14 @@ var thesaurusService = function thesaurusService(services) {
}
};
// console.log(data);
_jquery2.default.ajax({
url: dlgData.commit_url,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
success: function success(data, textStatus) {
console.log(data);
success: function success() {
dlg.close();
}
});
@@ -11733,6 +11807,7 @@ var thesaurusService = function thesaurusService(services) {
return false;
}
},
/**
* Cancel button
*/
@@ -11744,49 +11819,15 @@ var thesaurusService = function thesaurusService(services) {
}]);
/**
* when a destination field is changed, show/hide the "action" menus
* format the dlg content
*/
(0, _jquery2.default)(' .fieldSelect', $container).change(function () {
var n_changed = (0, _jquery2.default)(this).data('n');
(0, _jquery2.default)('SELECT', $container).menu();
(0, _jquery2.default)('.tabs', $container).tabs({ 'activate': updateUx });
(0, _jquery2.default)('.action', $container).change(updateUx);
// show "action" menus depending on the selected fields (none, mono, multi)
var oneFieldSet = false; // if at least one destination field is set, we will show some elements
(0, _jquery2.default)(' .fieldSelect', $container).each(function () {
var $this = (0, _jquery2.default)(this);
var n = $this.data('n');
var selIndex = $this.prop('selectedIndex');
if (selIndex > 0) {
if (n === n_changed) {
// reset both mono an multi menus
(0, _jquery2.default)(' .actionSelect._' + n, $container).prop('selectedIndex', 0);
}
var multi = !!(0, _jquery2.default)('option:eq(' + selIndex + ')', $this).data('multi');
if (multi) {
(0, _jquery2.default)(' .actionSelect._' + n + '.mono', $container).hide();
(0, _jquery2.default)(' .actionSelect._' + n + '.multi', $container).show();
} else {
(0, _jquery2.default)(' .actionSelect._' + n + '.multi', $container).hide();
(0, _jquery2.default)(' .actionSelect._' + n + '.mono', $container).show();
}
oneFieldSet = true;
} else {
// hide both menus
(0, _jquery2.default)(' .actionSelect._' + n).hide();
}
});
(0, _jquery2.default)(' .fieldSelected', $container).toggle(oneFieldSet);
}).change(); // enforce initial update
/**
* the "other values" button
*/
(0, _jquery2.default)(' .moreFields BUTTON', $container).click(function () {
(0, _jquery2.default)(' .moreFields', $container).hide();
(0, _jquery2.default)(' .other', $container).show();
return false;
});
updateUx(); // enforce initial update;
}).fail(function (jqxhr, textStatus, error) {
// the dlg content failed, report onto the dlg (better than forever loading)
var err = textStatus + ", " + error;
dlg.setContent("Request Failed: " + err);
});

View File

@@ -2288,17 +2288,15 @@ span.ww_winTitle {
height: auto !important;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content {
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content form {
margin-bottom: 0;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-menu OPTION {
color: #333333;
background-color: white;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-titlebar {
background: #282828;
border-top-left-radius: 5px !important;
@@ -6102,6 +6100,17 @@ form.phrasea_query input.query {
z-index: 1;
}
/******* Classification using thesaurus ************************************/
#TXCLASSIFICATION FORM {
padding: 0;
margin: 0;
}
#TXCLASSIFICATION #TXCLASSIFICATION_ADVANCED TD {
padding: 0 5px 0 5px;
}
.publish-dialog .ui-dialog-content {
max-height: 575px !important;
}

File diff suppressed because one or more lines are too long

View File

@@ -2303,17 +2303,15 @@ span.ww_winTitle {
height: auto !important;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content {
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content form {
margin-bottom: 0;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-menu OPTION {
color: #333333;
background-color: white;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-titlebar {
background: #b3b3b3;
border-top-left-radius: 5px !important;
@@ -6117,6 +6115,17 @@ form.phrasea_query input.query {
z-index: 1;
}
/******* Classification using thesaurus ************************************/
#TXCLASSIFICATION FORM {
padding: 0;
margin: 0;
}
#TXCLASSIFICATION #TXCLASSIFICATION_ADVANCED TD {
padding: 0 5px 0 5px;
}
.publish-dialog .ui-dialog-content {
max-height: 575px !important;
}

File diff suppressed because one or more lines are too long

View File

@@ -2305,17 +2305,15 @@ span.ww_winTitle {
height: auto !important;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content {
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-content form {
margin-bottom: 0;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-menu OPTION {
color: #333333;
background-color: white;
}
.black-dialog-wrap.ui-dialog.ui-widget-content .ui-dialog-titlebar {
background: #f5f5f5;
border-top-left-radius: 5px !important;
@@ -6119,6 +6117,17 @@ form.phrasea_query input.query {
z-index: 1;
}
/******* Classification using thesaurus ************************************/
#TXCLASSIFICATION FORM {
padding: 0;
margin: 0;
}
#TXCLASSIFICATION #TXCLASSIFICATION_ADVANCED TD {
padding: 0 5px 0 5px;
}
.publish-dialog .ui-dialog-content {
max-height: 575px !important;
}

File diff suppressed because one or more lines are too long

View File

@@ -112,7 +112,6 @@ const thesaurusService = services => {
.droppable({
accept: function(elem) {
let lstbr = searchSelection.asArray;
console.log("lstbr", lstbr);
dragUniqueSbid = null;
lstbr.forEach(sbid_rid => {
@@ -124,7 +123,7 @@ const thesaurusService = services => {
dragLstRecords = lstbr.join(';'); // a list as expected for RecordsRequest::fromRequest
$(this).removeClass('draggingOver');
console.log("accept", elem);
// console.log("accept", elem);
// if ($(elem).hasClass('grouping') && !$(elem).hasClass('SSTT')) {
// return true;
// }
@@ -313,10 +312,54 @@ const thesaurusService = services => {
},
function (dlgData) {
let $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
$container.addClass('black-dialog-wrap');
dlg.setOption("title", dlgData.dlg_title);
dlg.setContent(dlgData.dlg_content);
let $container = dlg.getDomElement().closest('.ui-dialog'); // the whole dlg, including title & buttons
/**
* update the dlg (show/hide selects & buttons) depending on form status
*/
let updateUx = function () {
// console.log("====== update =========================");
let okbutton = false; // must we show the ok button ?
/**
* loop on advanced-mode fields
*/
$('#TXCLASSIFICATION_ADVANCED .action', $container).each(function () {
let $this = $(this);
let n = $this.data('n');
switch($this.val()) { // action
case "": // first "select..." option
$('.value_container._'+n, $container).hide();
break;
case "clear": // clear a mono-value : no need value selection
$('.value_container._'+n, $container).hide();
okbutton = true;
break;
default:
$('.value_container._'+n, $container).show();
okbutton = true;
}
});
/**
* if the "simple-mode" is front, show "ok" button
*/
let seltab_idx = $('.tabs', $container).tabs('option', 'active');
let seltab_id = $('.tabs>UL.ui-tabs-nav>LI:eq('+seltab_idx+')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
if(seltab_id === "SIMPLE") {
// simple ux: ok is possible
okbutton = true;
}
$(' .okbutton', $container).toggle(okbutton);
}
/**
* add buttons
@@ -328,30 +371,59 @@ const thesaurusService = services => {
*/
{
text: "Ok",
class: "fieldSelected",
class: "fieldSelected okbutton",
style: "display:none",
click: function () {
// don't submit the complex form, better build json
let actions = [];
$(' .fieldSelect', $container).filter(function () { return $(this).prop('selectedIndex')>0;}).each(function () {
let n = $(this).data('n');
let action = $(' .actionSelect._'+n+':visible', $container).val();
if(action === 'replace') {
// replace all multi-v needs a "replace_by" arg
/**
* find the active tab ("SIMPLE" or "ADVANCED")
*/
let seltab_idx = $('.tabs', $container).tabs('option', 'active');
let seltab_id = $('.tabs>UL.ui-tabs-nav>LI:eq('+seltab_idx+')', $container).data('tab_id'); // "SIMPLE" or "ADVANCED"
/**
* extract data only from the front tab (div)
*/
let box = $("#TXCLASSIFICATION_"+seltab_id, $container);
$('.action', box).each(
function() {
let $this = $(this);
let n = $this.data('n');
let action = $this.val();
if(action !== "") {
let field = $('.field._' + n, box).val();
let value = $('.value._' + n, box).val();
switch(action) {
case "replace": // replace all multi-values
actions.push({
'field_name': $(this).val(),
'field_name': field,
'action': "replace",
'replace_with': value
});
break;
case "clear": // clear a mono-value
actions.push({
'field_name': field,
'action': "delete"
});
break;
default: // all other actions don't need patch
actions.push({
'field_name': field,
'action': action,
'replace_with': $(' .synonym._' + n, $container).val()
'value': value
});
}
else {
actions.push({
'field_name': $(this).val(),
'action': action,
'value': $(' .synonym._' + n, $container).val()
});
}
});
/**
* post actions
*/
data = {
'records': dlgData.rec_refs,
'actions': {
@@ -359,13 +431,14 @@ const thesaurusService = services => {
}
};
// console.log(data);
$.ajax({
url: dlgData.commit_url,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
success: function (data, textStatus) {
console.log(data);
success: function () {
dlg.close();
}
},
@@ -374,6 +447,7 @@ const thesaurusService = services => {
return false;
}
},
/**
* Cancel button
*/
@@ -387,55 +461,18 @@ const thesaurusService = services => {
);
/**
* when a destination field is changed, show/hide the "action" menus
* format the dlg content
*/
$(' .fieldSelect', $container)
.change(function () {
let n_changed = $(this).data('n');
$('SELECT', $container).menu();
$('.tabs', $container).tabs({'activate':updateUx});
$('.action', $container).change(updateUx)
// show "action" menus depending on the selected fields (none, mono, multi)
let oneFieldSet = false; // if at least one destination field is set, we will show some elements
$(' .fieldSelect', $container).each(function () {
let $this = $(this);
let n = $this.data('n');
let selIndex = $this.prop('selectedIndex');
if(selIndex > 0) {
if(n === n_changed) {
// reset both mono an multi menus
$(' .actionSelect._'+n, $container).prop('selectedIndex', 0);
}
let multi = !!$('option:eq(' + selIndex + ')', $this).data('multi');
if(multi) {
$(' .actionSelect._'+n+'.mono', $container).hide();
$(' .actionSelect._'+n+'.multi', $container).show();
}
else {
$(' .actionSelect._'+n+'.multi', $container).hide();
$(' .actionSelect._'+n+'.mono', $container).show();
}
updateUx(); // enforce initial update;
oneFieldSet = true;
}
else {
// hide both menus
$(' .actionSelect._'+n).hide();
}
});
$(' .fieldSelected', $container).toggle(oneFieldSet);
})
.change(); // enforce initial update
/**
* the "other values" button
*/
$(' .moreFields BUTTON', $container).click(function () {
$(' .moreFields', $container).hide();
$(' .other', $container).show();
return false;
})
}
).fail(function( jqxhr, textStatus, error ) {
// the dlg content failed, report onto the dlg (better than forever loading)
let err = textStatus + ", " + error;
dlg.setContent( "Request Failed: " + err );
});

View File

@@ -422,14 +422,22 @@ span.ww_winTitle {
}
}
.ui-dialog-content {
padding: 0;
display: flex;
align-items: center;
justify-content: center;
// padding: 0;
// display: flex;
// align-items: center;
// justify-content: center;
form {
margin-bottom: 0;
}
}
.ui-menu {
OPTION {
// dunno why option is rendered with white bg when style says "transparent"
// changing bg color causes glitches, so we change text
color: #333333;
background-color: white;
}
}
.ui-dialog-titlebar {
background: $dialogHeaderBg;
border-top-left-radius: 5px!important;
@@ -1319,6 +1327,7 @@ h3.metadatas-title {
@import 'ui-components/pagination';
@import 'ui-components/upload';
@import 'ui-components/modal-basket-pref';
@import 'ui-components/modal-classification';
@import 'ui-components/modal-publish';
@import 'ui-components/modal-edit';
@import 'ui-components/modal-export';

View File

@@ -0,0 +1,13 @@
/******* Classification using thesaurus ************************************/
#TXCLASSIFICATION {
FORM {
padding: 0;
margin: 0;
}
#TXCLASSIFICATION_ADVANCED TD {
padding: 0 5px 0 5px;
}
}

View File

@@ -92,6 +92,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
border-top: 1px solid $darkBorderColor;
}
}
#THPD_tabs {
right: 0;

View File

@@ -46,12 +46,10 @@ class ThesaurusController extends Controller
// twig parameters
$twp = [
'error' => null,
// 'dlg_level' => $request->get('dlg_level'),
// 'lst' => $records->serializedList(),
// 'records' => $recRefs,
'dlg_level' => $request->get('dlg_level'),
'received_cnt' => $records->received()->count(),
'rejected_cnt' => $records->rejected()->count(),
'up_paths' => [],
'by_fields' => [],
];
// find which field(s) can be updated, that is what tbranches are linked to a parent of the term
@@ -67,13 +65,16 @@ class ThesaurusController extends Controller
throw new Exception("error fetching th");
}
$upPaths = [];
$xpath = new DOMXPath($domth);
$fields = [];
foreach ($dbox->get_meta_structure() as $field) {
if($field->is_readonly() || !$field->get_gui_editable()) {
continue;
}
if (!($q = $field->get_tbranch())) {
continue;
}
$roots = $xpath->query($q); // linked nodes for this field
$q = '(' . $q . ')//sy[@id=\'' . $tx_term_id . '\']'; // can we find the term under the tbranch(es) ?
// normally we should find only one linked parent, since we search from a unique term
@@ -85,73 +86,96 @@ class ThesaurusController extends Controller
// going up, we decide to stop at the first link (B) (easier)
if (($droppedSy = $xpath->query($q))->length > 0) {
// yes (and since the query targets a unique id, there is only one result)
// yes this field is linked to a branch that contains the term
// since the query targets a unique id, there is only one result
$droppedSy = $droppedSy->item(0);
/** @var DOMElement $droppedSy */
$droppedlng = $droppedSy->getAttribute('lng'); // the lng of the dropped term is prefered
$values = [];
// go from the sy upto a linked branch (possibly multiples if the field is linked to many branches)
$ok = true; // == the term (level up-to top) can populate the current field
for ($te = $droppedSy->parentNode; $te->nodeType === XML_ELEMENT_NODE; $te = $te->parentNode) {
$depth = 0; // 0 for dropped-on level, will decrease while going up
$selectedValue = null;
for ($te = $droppedSy->parentNode; $te->nodeType === XML_ELEMENT_NODE; $te = $te->parentNode, $depth--) {
/** @var DOMElement $te */
$teid = $te->getAttribute('id');
for ($i = 0; $i < $roots->length; $i++) {
if ($te->isSameNode($roots->item($i))) {
$ok = false; // we met the link point, upmost terms are not "values" anymore
// we hit the link point, upmost terms are not "values" anymore
break 2; // no need to go higher
}
}
if ($ok) { // acceptable value for the current field
if (!array_key_exists($teid, $upPaths)) {
$upPaths[$teid] = [
'synonyms' => [],
'fields' => []
// here acceptable value for the current field
if($depth === 0) {
//
// dropped-on level : we accept the exact term (not searching synonyms)
//
$selectedValue = [
'value' => $droppedSy->getAttribute('v'),
'lng' => $droppedlng,
'selected' => true
];
// get all the sy so the user can choose which is prefered
$preferedId = null;
$values[$droppedSy->getAttribute('id')] = $selectedValue;
}
else {
//
// upper level : get all the sy so the user can choose which is prefered
//
// first, see if at least one sy is matching the lng
$lngFound = false;
foreach ($te->childNodes as $sy) {
if ($sy->nodeName == 'sy' && $sy->getAttribute('lng') == $droppedlng) {
$lngFound = true;
break;
}
}
// then rescan sy to add to the values
foreach ($te->childNodes as $sy) {
if ($sy->nodeName != 'sy') {
continue; // skip 'te' children
}
$lng = $sy->getAttribute('lng');
$id = $sy->getAttribute('id');
$s = [
if (!$lngFound || $lng == $droppedlng) {
$values[$sy->getAttribute('id')] = [
'value' => $sy->getAttribute('v'),
'lng' => $lng,
'selected' => false
'selected' => $sy->isSameNode($droppedSy)
];
// this sy is prefered if...
if ($sy->getAttribute('lng') === $droppedlng) {
$preferedId = $id; // ... it has the same lng as the dropped
}
if ($sy->isSameNode($droppedSy)) {
$preferedId = $id; // ... better : it was the dropped target
}
$upPaths[$teid]['synonyms'][$id] = $s;
}
if ($preferedId) {
$upPaths[$teid]['synonyms'][$preferedId]['selected'] = true;
}
}
$upPaths[$teid]['fields'][$field->get_id()] = $field;
}
}
$twp['up_paths'] = array_reverse($upPaths);
$twp['fields'][] = $field;
// $field->
}
}
if (empty($upPaths)) {
if(!empty($values)) {
$fields[$field->get_name()] = [
'field' => $field,
'values' => array_reverse($values),
'selected_value' => $selectedValue,
];
}
}
}
if(empty($fields)) {
// no fields (could happen if one drops on a top-level branch, or if the th is not linked, or...)
throw new Exception("this branch is not linked");
}
$twp['by_fields'] = $fields;
}
catch (Exception $e) {
$twp['error'] = $e->getMessage();
}
$zzz = $this->render('prod/Thesaurus/droppedrecords.html.twig', $twp);
return $this->app->json([
'dlg_title' => sprintf("editing %s record(s)", $records->received()->count()),
'dlg_content' => $this->render('prod/Thesaurus/droppedrecords.html.twig', $twp),

View File

@@ -59,7 +59,7 @@ class PhraseanetExtension extends \Twig_Extension
{
return [
// change this version when you change JS file to force the navigation to reload js file
'jsFileVersion' => 11
'jsFileVersion' => 12
];
}

View File

@@ -1,5 +1,5 @@
<h3 style="color: red">POC/Experimental.</h3>
<div id="TXCLASSIFICATION">
<h3 style="color: red">WIP/Experimental.</h3>
{% if error %}
@@ -8,190 +8,104 @@
{% else %}
{% if rejected_cnt > 0 %}
you don't have rights to edit {{ rejected_cnt }} record(s)
{% endif %}
<form id="DroppedOnTH_form">
<table>
<tr>
<th>value</th>
<th><span class="fieldSelected" style="display: none">operation</span></th>
<th>to field</th>
</tr>
{% if up_paths|length > 1 %}
<tr class="moreFields">
<td colspan="3">
<button>+</button>&nbsp;Other value(s)...
</td>
</tr>
{% set simple_possible = false %}
{% set advanced_needed = true %}
{% set selected_sy = null %}
{% set bf0 = by_fields|first %}
{% if by_fields|length == 1 %}
{# if there is only 1 field, we can propose a "simple" ux with the selected "value" (dropped-on) #}
{# bf0 is the only field #}
{% set simple_possible = true %}
{% endif %}
{% set n=1 %}
{% for tid,up_path in up_paths %}
{% set cl = (n == up_paths|length) ? "" : "class='other' style='display:none'"%}
<tr {{ cl|raw }}>
<td>
{# {% if up_path.synonyms|length == 1 %} #}{# too bad : we must use a select event for one option... #}
{# {% set synonym = up_path.synonyms|first %}#}
{# <input type="text" class="uneditable-input" value={{ synonym.value }} /> #}{# bad align because we changed "select" margins #}
{# {% else %}#}
<select class="synonym _{{ n }}">
{% for synonym in up_path.synonyms %}
<option {{ synonym.selected ? "selected" : "" }}>{{ synonym.value }}</option>
{% endfor%}
</select>
{# {% endif %}#}
</td>
<td>
<select class="actionSelect mono _{{ n }}">
<option class="mono" value="set">set to</option>
<option class="mono" value="delete">delete from</option>
</select>
<select class="actionSelect multi _{{ n }}">
<option class="multi" value="add">add to</option>
<option class="multi" value="replace">replace all</option>
<option class="multi" value="delete">remove from</option>
</select>
</td>
<td>
<select class="fieldSelect" data-n="{{ n }}">
{% set sel="" %}
{% if n == up_paths|length %}
<option data-multi="0">select...</option>
{% if up_path.fields|length == 1 %}
{% set sel="selected" %}
<div class="tabs">
<ul>
{% if simple_possible %}
<li data-tab_id="SIMPLE"><a href="#TXCLASSIFICATION_SIMPLE">simple mode</a></li>
{% endif %}
{% if advanced_needed %}
<li data-tab_id="ADVANCED"><a href="#TXCLASSIFICATION_ADVANCED">advanced mode</a></li>
{% endif %}
</ul>
{% if simple_possible %}
<div id="TXCLASSIFICATION_SIMPLE" style="padding: 20px 10px 20px 10px">
<form id="DroppedOnTH_form_simple">
<input type="hidden" class="field _0" value="{{ bf0.field.get_name() }}">
<input type="hidden" class="action _0" value="add" data-n="0">
<input type="hidden" class="value _0" value="{{ bf0.selected_value.value }}">
</form>
{% if bf0.field.is_multi() %}
add&nbsp;&nbsp;<b>{{ bf0.selected_value.value }}</b>&nbsp;&nbsp;to the field&nbsp;&nbsp;<b>{{ bf0.field.get_name() }}</b>
{% else %}
<option data-multi="0">none</option>
set&nbsp;&nbsp;<b>{{ bf0.field.get_name() }}</b>&nbsp;&nbsp;to&nbsp;&nbsp;<b>{{ bf0.selected_value.value }}</b>
{% endif %}
{% for field in up_path.fields %}
<option {{ sel }} data-multi="{{ field.is_multi() ? 1 : 0 }}" value="{{ field.get_name() }}">{{ field.get_name() }}</option>
</div>
{% endif %}
{% if advanced_needed %}
<div id="TXCLASSIFICATION_ADVANCED" style="padding: 10px;">
<form id="DroppedOnTH_form_advanced">
{% set n = 0 %}
<table>
<thead>
<tr>
<th>Field</th>
<th>Action</th>
<th class="okbutton">Value</th>
</tr>
</thead>
<tbody>
{% for bf in by_fields %}
<tr>
<td>
<input type="hidden" class="field _{{ n }}" value="{{ bf.field.get_name() }}">
{{ bf.field.get_name() }}&nbsp;:
</td>
<td>
<select class="action _{{ n }}" data-n="{{ n }}">
<option value="" {{ simple_possible ? "" : "selected"}}>...</option>
{% if bf.field.is_multi() %}
<option value="add" {{ simple_possible ? "selected" : ""}}>add</option>
<option value="replace">replace all with</option>
<option value="delete">remove</option>
{% else %}
<option value="set" {{ simple_possible ? "selected" : ""}}>set to</option>
<option value="clear">clear</option>
{% endif%}
</select>
</td>
<td>
<div class="value_container _{{ n }}" style="display: none">
{% if bf.values|length == 1 %}
<input type="hidden" class="value _{{ n }}" value="{{ (bf.values|first).value }}">
{{ (bf.values|first).value }}
{% else %}
<select class="value _{{ n }}" >
{% for v in bf.values %}
<option {{ v.selected ? "selected" : "" }}>{{ v.value }}</option>
{% endfor %}
</select>
{% endif %}
</div>
</td>
</tr>
{% set n = n+1 %}
{% endfor %}
</tbody>
</table>
</form>
</div>
{% endif %}
</div>
{% endif %}
</div>
{#
<script type="application/javascript">
//let dlg = dialog.get({{ dlg_level }});
// todo : find dlg container by .widget() ?
//let $container = dlg.getDomElement().parent(); // the whole dlg, including title & buttons
// todo : fix black-dialog-wrap
// $container.addClass('black-dialog-wrap');
// dlg.setOption("title", "editing {{ received_cnt }} record(s)");
dlg.setOption("buttons",
[
{
class: "fieldSelected",
text: "Ok",
style: "display:none",
click: function() {
// don't submit the complex form, better build json
let data = [];
$(' .fieldSelect').filter(function () { return $(this).prop('selectedIndex')>0;}).each(function () {
let n = $(this).data('n');
let action = $(' .actionSelect._'+n+':visible', $container).val();
if(action === 'replace') {
// replace ll multi-v needs a "replace_by" arg
data.push({
'field_name': $(this).val(),
'action': action,
'replace_with': $(' .synonym._' + n, $container).val()
});
}
else {
data.push({
'field_name': $(this).val(),
'action': action,
'value': $(' .synonym._' + n, $container).val()
});
}
});
data = {
'records': {{ records|json_encode|raw }},
'actions': {
'metadatas': data
}
};
console.log(data);
$.ajax({
url: "{{ path('prod_edit_applyJSAction') }}",
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
success: function (data, textStatus) {
console.log(data);
dlg.close();
}
},
);
}
},
{
text: "Cancel",
click: function() {
$( this ).dialog( "close" );
}
}
]
);
*/
// /**
// * when a destination field is changed, show/hide the "action" menus
// */
// $(' .fieldSelect', $container)
// .change(function () {
// let n_changed = $(this).data('n');
//
// // show "action" menus depending on the selected fields (none, mono, multi)
// let oneFieldSet = false; // if at least one destination field is set, we will show some elements
// $(' .fieldSelect', $container).each(function () {
// let $this = $(this);
// let n = $this.data('n');
// let selIndex = $this.prop('selectedIndex');
// if(selIndex > 0) {
// if(n === n_changed) {
// // reset both mono an multi menus
// $(' .actionSelect._'+n, $container).prop('selectedIndex', 0);
// }
// let multi = !!$('option:eq(' + selIndex + ')', $this).data('multi');
// if(multi) {
// $(' .actionSelect._'+n+'.mono', $container).hide();
// $(' .actionSelect._'+n+'.multi', $container).show();
// }
// else {
// $(' .actionSelect._'+n+'.multi', $container).hide();
// $(' .actionSelect._'+n+'.mono', $container).show();
// }
//
// oneFieldSet = true;
// }
// else {
// // hide both menus
// $(' .actionSelect._'+n).hide();
// }
// });
// $(' .fieldSelected', $container).toggle(oneFieldSet);
// })
// .change(); // enforce initial update
$(' .moreFields BUTTON', $container).click(function () {
$(' .moreFields', $container).hide();
$(' .other', $container).show();
return false;
})
</script>
#}