Commit 5682200b authored by Romain Courteaud's avatar Romain Courteaud

[erp5_web_renderjs_ui] Handle mass delete/change state from listbox select mode

This allow to pick up only few document on which to execute the action.

Listbox 'Edit' mode will contain copy/paste/delete actions.
Listbox 'Select' mode will contain include/exclude and all other erp5 actions (except delete).

Define the action on erp5 with the object_list_action category value.
parent a1887d06
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_delete_action</string> </value> <value> <string>object_list_action</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Delete Multiple Documents</string> </value> <value> <string>Delete</string> </value>
</item> </item>
<item> <item>
<key> <string>visible</string> </key> <key> <string>visible</string> </key>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_onlyjio_action</string> </value> <value> <string>object_list_action</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
......
...@@ -1341,7 +1341,8 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1341,7 +1341,8 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
}) })
global_action_type = ("view", "workflow", "object_new_content_action", global_action_type = ("view", "workflow", "object_new_content_action",
"object_clone_action", "object_delete_action") "object_clone_action", "object_delete_action",
"object_list_action")
if (erp5_action_key == view_action_type or if (erp5_action_key == view_action_type or
erp5_action_key in global_action_type or erp5_action_key in global_action_type or
"_jio" in erp5_action_key): "_jio" in erp5_action_key):
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
data-i18n=No records data-i18n=No records
data-i18n=Records data-i18n=Records
data-i18n=Select data-i18n=Select
data-i18n=Edit
data-i18n=Configure data-i18n=Configure
data-i18n=Sort data-i18n=Sort
data-i18n=sample of data-i18n=sample of
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>971.37684.40708.23176</string> </value> <value> <string>972.60114.22488.50688</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1545124793.17</float> <float>1547457320.7</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -278,7 +278,9 @@ ...@@ -278,7 +278,9 @@
"row_list": row_list, "row_list": row_list,
"show_anchor": gadget.state.show_anchor, "show_anchor": gadget.state.show_anchor,
"column_list": column_list, "column_list": column_list,
"show_line_selector": gadget.state.show_line_selector "show_line_selector": gadget.state.show_line_selector,
"show_select_action": gadget.state.show_select_action,
"show_clipboard_action": gadget.state.show_clipboard_action
}); });
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
...@@ -331,8 +333,12 @@ ...@@ -331,8 +333,12 @@
.declareAcquiredMethod("getTranslationList", "getTranslationList") .declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("getListboxSelectActionList", .declareAcquiredMethod("getListboxSelectActionList",
"getListboxSelectActionList") "getListboxSelectActionList")
.declareAcquiredMethod("getListboxClipboardActionList",
"getListboxClipboardActionList")
.declareAcquiredMethod("triggerListboxSelectAction", .declareAcquiredMethod("triggerListboxSelectAction",
"triggerListboxSelectAction") "triggerListboxSelectAction")
.declareAcquiredMethod("triggerListboxClipboardAction",
"triggerListboxClipboardAction")
////////////////////////////////////////////// //////////////////////////////////////////////
// initialize the gadget content // initialize the gadget content
...@@ -481,7 +487,9 @@ ...@@ -481,7 +487,9 @@
// No error message // No error message
has_error: false, has_error: false,
show_line_selector: false show_line_selector: false,
show_select_action: false,
show_clipboard_action: false
}); });
}); });
return queue; return queue;
...@@ -497,6 +505,7 @@ ...@@ -497,6 +505,7 @@
j, j,
result_queue = new RSVP.Queue(), result_queue = new RSVP.Queue(),
button_selector_list = ['button[name="Sort"]', 'button[name="Hide"]', button_selector_list = ['button[name="Sort"]', 'button[name="Hide"]',
'button[name="Clipboard"]',
'button[name="Configure"]', 'button[name="Configure"]',
'button[name="SelectRows"]'], 'button[name="SelectRows"]'],
button; button;
...@@ -614,7 +623,7 @@ ...@@ -614,7 +623,7 @@
} }
} }
if (gadget.state.show_line_selector) { if (gadget.state.show_select_action) {
select_list = gadget.getListboxSelectActionList() select_list = gadget.getListboxSelectActionList()
.push(undefined, function (error) { .push(undefined, function (error) {
if (error instanceof rJS.AcquisitionError) { if (error instanceof rJS.AcquisitionError) {
...@@ -627,12 +636,25 @@ ...@@ -627,12 +636,25 @@
}); });
} }
if (gadget.state.show_clipboard_action) {
select_list = gadget.getListboxClipboardActionList()
.push(undefined, function (error) {
if (error instanceof rJS.AcquisitionError) {
// Do not break if parent gadget does not implement it
// XXX this could be a new rJS function when doing
// declareAcquiredMethod
return [];
}
throw error;
});
}
return RSVP.all([ return RSVP.all([
gadget.getUrlForList(url_for_option_list), gadget.getUrlForList(url_for_option_list),
is_sortable_list, is_sortable_list,
gadget.getTranslationList(['Jump', gadget.getTranslationList(['Jump',
'Select', 'Configure', 'Sort', 'Select', 'Configure', 'Sort',
'Cancel']), 'Cancel', 'Edit']),
select_list select_list
]); ]);
}) })
...@@ -665,7 +687,7 @@ ...@@ -665,7 +687,7 @@
h1_element.appendChild(span_element); h1_element.appendChild(span_element);
div_element.appendChild(h1_element); div_element.appendChild(h1_element);
if (gadget.state.show_line_selector) { if (gadget.state.show_select_action) {
for (k = 0; k < select_option_list.length; k += 1) { for (k = 0; k < select_option_list.length; k += 1) {
// Add include button // Add include button
// <button data-rel="hide" data-i18n="Include" name="IncludeRows" type="button" class="ui-icon-eye ui-btn-icon-left {{hide_class}}"></button> // <button data-rel="hide" data-i18n="Include" name="IncludeRows" type="button" class="ui-icon-eye ui-btn-icon-left {{hide_class}}"></button>
...@@ -689,6 +711,30 @@ ...@@ -689,6 +711,30 @@
button_element.textContent = translation_list[4]; button_element.textContent = translation_list[4];
div_element.appendChild(button_element); div_element.appendChild(button_element);
} else if (gadget.state.show_clipboard_action) {
for (k = 0; k < select_option_list.length; k += 1) {
// Add include button
// <button data-rel="hide" data-i18n="Include" name="IncludeRows" type="button" class="ui-icon-eye ui-btn-icon-left {{hide_class}}"></button>
button_element = document.createElement('button');
button_element.setAttribute('data-rel', 'clipboard');
button_element.setAttribute('data-clipboard-action', select_option_list[k].action);
button_element.setAttribute('name', 'ClipboardAction');
button_element.type = 'button';
button_element.setAttribute('class', 'ui-icon-' + select_option_list[k].icon + ' ui-btn-icon-left ' + gadget.state.hide_class);
button_element.textContent = select_option_list[k].title;
div_element.appendChild(button_element);
}
// Add cancel button
// <button data-rel="cancel" data-i18n="Cancel" name="ExcludeRows" type="button" class="ui-icon-times ui-btn-icon-left {{hide_class}}"></button>
button_element = document.createElement('button');
button_element.setAttribute('data-rel', 'hide');
button_element.setAttribute('name', 'CancelSelect');
button_element.type = 'button';
button_element.setAttribute('class', 'ui-icon-times ui-btn-icon-left ' + gadget.state.hide_class);
button_element.textContent = translation_list[4];
div_element.appendChild(button_element);
} else { } else {
// Add Configure button // Add Configure button
...@@ -713,6 +759,17 @@ ...@@ -713,6 +759,17 @@
button_element.textContent = translation_list[3]; button_element.textContent = translation_list[3];
div_element.appendChild(button_element); div_element.appendChild(button_element);
// Add Do button
// <button {{disabled}} data-rel="hide" data-i18n="Select" name="Hide" type="button" class="ui-icon-check-square-o ui-btn-icon-left {{hide_class}}"></button>
button_element = document.createElement('button');
button_element.disabled = gadget.state.disabled;
button_element.setAttribute('data-rel', 'clipboard');
button_element.setAttribute('name', 'Clipboard');
button_element.type = 'button';
button_element.setAttribute('class', 'ui-icon-list-ul ui-btn-icon-left ' + gadget.state.hide_class);
button_element.textContent = translation_list[5];
div_element.appendChild(button_element);
// Add Select button // Add Select button
// <button {{disabled}} data-rel="hide" data-i18n="Select" name="Hide" type="button" class="ui-icon-check-square-o ui-btn-icon-left {{hide_class}}"></button> // <button {{disabled}} data-rel="hide" data-i18n="Select" name="Hide" type="button" class="ui-icon-check-square-o ui-btn-icon-left {{hide_class}}"></button>
button_element = document.createElement('button'); button_element = document.createElement('button');
...@@ -1217,6 +1274,7 @@ ...@@ -1217,6 +1274,7 @@
var gadget = this, var gadget = this,
sort_button = gadget.element.querySelector('button[name="Sort"]'), sort_button = gadget.element.querySelector('button[name="Sort"]'),
hide_button = gadget.element.querySelector('button[name="Hide"]'), hide_button = gadget.element.querySelector('button[name="Hide"]'),
clipboard_button = gadget.element.querySelector('button[name="Clipboard"]'),
configure_button = gadget.element.querySelector('button[name="Configure"]'), configure_button = gadget.element.querySelector('button[name="Configure"]'),
cancel_select_button = gadget.element.querySelector('button[name="CancelSelect"]'), cancel_select_button = gadget.element.querySelector('button[name="CancelSelect"]'),
url, url,
...@@ -1247,19 +1305,30 @@ ...@@ -1247,19 +1305,30 @@
if (evt.target === hide_button) { if (evt.target === hide_button) {
evt.preventDefault(); evt.preventDefault();
return gadget.changeState({ return gadget.changeState({
show_line_selector: true show_line_selector: true,
show_select_action: true
});
}
if (evt.target === clipboard_button) {
evt.preventDefault();
return gadget.changeState({
show_line_selector: true,
show_clipboard_action: true
}); });
} }
if (evt.target === cancel_select_button) { if (evt.target === cancel_select_button) {
evt.preventDefault(); evt.preventDefault();
return gadget.changeState({ return gadget.changeState({
show_line_selector: false show_line_selector: false,
show_select_action: false,
show_clipboard_action: false
}); });
} }
if ((evt.target.type === 'button') && if ((evt.target.type === 'button') &&
(evt.target.name === 'SelectAction')) { ((evt.target.name === 'SelectAction') || (evt.target.name === 'ClipboardAction'))) {
evt.preventDefault(); evt.preventDefault();
checked_uid_list = []; checked_uid_list = [];
...@@ -1275,7 +1344,10 @@ ...@@ -1275,7 +1344,10 @@
unchecked_uid_list.push(all_hide_element_list[i].getAttribute("data-uid")); unchecked_uid_list.push(all_hide_element_list[i].getAttribute("data-uid"));
} }
} }
return gadget.triggerListboxSelectAction(evt.target.getAttribute('data-select-action'), checked_uid_list, unchecked_uid_list); if (evt.target.name === 'SelectAction') {
return gadget.triggerListboxSelectAction(evt.target.getAttribute('data-select-action'), checked_uid_list, unchecked_uid_list);
}
return gadget.triggerListboxClipboardAction(evt.target.getAttribute('data-clipboard-action'), checked_uid_list, unchecked_uid_list);
} }
}, false, false) }, false, false)
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.27092.48077.63488</string> </value> <value> <string>972.64219.61976.2884</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1545386943.7</float> <float>1547458514.41</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.48331.62264.17646</string> </value> <value> <string>972.58906.44395.12356</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1546505106.65</float> <float>1547211850.35</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, RSVP, Handlebars, UriTemplate, calculatePageTitle, ensureArray */ /*global window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, UriTemplate, calculatePageTitle, ensureArray) { (function (window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray) {
"use strict"; "use strict";
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
* @param {Array} command_list - array of links obtained from ERP5 HATEOAS * @param {Array} command_list - array of links obtained from ERP5 HATEOAS
*/ */
function renderLinkList(gadget, jio_key, title, icon, erp5_link_list) { function renderLinkList(gadget, jio_key, title, icon, erp5_link_list) {
return gadget.getUrlParameter("extended_search") return new RSVP.Queue()
.push(function (query) { .push(function () {
// obtain RJS links from ERP5 links // obtain RJS links from ERP5 links
return RSVP.all( return RSVP.all(
erp5_link_list.map(function (erp5_link) { erp5_link_list.map(function (erp5_link) {
...@@ -75,8 +75,8 @@ ...@@ -75,8 +75,8 @@
return gadget.jio_getAttachment(options.jio_key, options.view || "links") return gadget.jio_getAttachment(options.jio_key, options.view || "links")
.push(function (result) { .push(function (result) {
var export_list = ensureArray(result._links.action_object_jio_exchange), var export_list = ensureArray(result._links.action_object_jio_exchange),
report_list = ensureArray(result._links.action_object_jio_report), report_list = ensureArray(result._links.action_object_jio_report),
print_list = ensureArray(result._links.action_object_jio_print); print_list = ensureArray(result._links.action_object_jio_print);
erp5_document = result; erp5_document = result;
...@@ -104,4 +104,4 @@ ...@@ -104,4 +104,4 @@
return; return;
}); });
}(window, rJS, RSVP, Handlebars, UriTemplate, calculatePageTitle, ensureArray)); }(window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.57045.3544.6092</string> </value> <value> <string>973.127.62172.31061</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1547052055.53</float> <float>1547544973.33</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<!-- <!--
data-i18n=Include data-i18n=Include
data-i18n=Exclude data-i18n=Exclude
data-i18n=Delete
--> -->
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.25327.46098.50073</string> </value> <value> <string>972.29743.559.65006</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1545389700.46</float> <float>1546423008.44</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery, /*global window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery,
Query, QueryFactory */ Query, QueryFactory, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3, continue: true */
(function (window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery, (function (window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery,
Query, QueryFactory) { Query, QueryFactory, ensureArray) {
"use strict"; "use strict";
function updateSearchQueryFromSelection(extended_search, checked_uid_list,
key, to_include) {
var i,
search_query,
query_list = [];
for (i = 0; i < checked_uid_list.length; i += 1) {
query_list.push(new SimpleQuery({
key: key,
type: "simple",
operator: to_include ? "=" : "!=",
value: checked_uid_list[i]
}));
}
if (extended_search) {
search_query = QueryFactory.create(extended_search);
}
if (to_include) {
// Lines must match the existing query and be one of the selected
// line. Which means that is user change the query, one of the
// selected line could disappear.
if (search_query) {
search_query = new ComplexQuery({
operator: "AND",
query_list: [
new ComplexQuery({
operator: "OR",
query_list: query_list,
type: "complex"
}),
search_query
],
type: "complex"
});
} else {
search_query = new ComplexQuery({
operator: "OR",
query_list: query_list,
type: "complex"
});
}
} else {
// Lines must match the existing query and must not be one of the
// selected line.
if (search_query) {
query_list.push(search_query);
}
search_query = new ComplexQuery({
operator: "AND",
query_list: query_list,
type: "complex"
});
}
return Query.objectToSearchText(search_query);
}
function triggerListboxClipboardAction(argument_list) {
var action_list = ensureArray(this.state.erp5_document._links.action_object_list_action || []),
action_name = argument_list[0],
checked_uid_list = argument_list[1],
gadget = this,
extended_search = gadget.state.extended_search,
view,
i;
for (i = 0; i < action_list.length; i += 1) {
if (action_name === action_list[i].name) {
view = action_list[i].href;
}
}
if (checked_uid_list.length !== 0) {
// If nothing is checked, use original query
extended_search = updateSearchQueryFromSelection(
extended_search,
checked_uid_list,
'catalog.uid',
true
);
}
if (view === undefined) {
// Action was not found.
// Reload
return gadget.redirect({
command: 'reload'
});
}
return gadget.redirect({
command: 'display_dialog_with_history',
options: {
"jio_key": gadget.state.jio_key,
"view": view,
"extended_search": extended_search
}
}, true);
}
rJS(window) rJS(window)
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Acquired methods // Acquired methods
...@@ -201,17 +300,38 @@ ...@@ -201,17 +300,38 @@
// Handle listbox custom button // Handle listbox custom button
.allowPublicAcquisition("getListboxSelectActionList", function getListboxSelectActionList() { .allowPublicAcquisition("getListboxSelectActionList", function getListboxSelectActionList() {
return this.getTranslationList(['Include', 'Exclude']) var gadget = this;
.push(function (result_list) { return gadget.getTranslationList(['Include', 'Exclude'])
return [{ .push(function (translation_list) {
title: result_list[0], var result_list = [{
title: translation_list[0],
icon: 'eye', icon: 'eye',
action: 'include' action: 'include'
}, { }, {
title: result_list[1], title: translation_list[1],
icon: 'low-vision', icon: 'low-vision',
action: 'exclude' action: 'exclude'
}]; }],
action_list = ensureArray(gadget.state.erp5_document._links.action_object_list_action || []),
i,
icon;
for (i = 0; i < action_list.length; i += 1) {
if (action_list[i].name === 'delete_document_list') {
continue;
}
if (action_list[i].name === 'mass_workflow_jio') {
icon = 'random';
} else {
icon = 'star';
}
result_list.unshift({
title: action_list[i].title,
icon: icon,
action: action_list[i].name
});
}
return result_list;
}); });
}) })
...@@ -219,10 +339,7 @@ ...@@ -219,10 +339,7 @@
var action = argument_list[0], var action = argument_list[0],
checked_uid_list = argument_list[1], checked_uid_list = argument_list[1],
unchecked_uid_list = argument_list[2], unchecked_uid_list = argument_list[2],
gadget = this, gadget = this;
i,
search_query,
query_list = [];
if ((action === 'include') || (action === 'exclude')) { if ((action === 'include') || (action === 'exclude')) {
if (checked_uid_list.length === 0) { if (checked_uid_list.length === 0) {
// If nothing is checked, use all unchecked values (same as xhtml style) // If nothing is checked, use all unchecked values (same as xhtml style)
...@@ -235,65 +352,48 @@ ...@@ -235,65 +352,48 @@
}); });
} }
for (i = 0; i < checked_uid_list.length; i += 1) {
query_list.push(new SimpleQuery({
key: "catalog.uid",
type: "simple",
operator: (action === 'include') ? "=" : "!=",
value: checked_uid_list[i]
}));
}
if (gadget.state.extended_search) {
search_query = QueryFactory.create(gadget.state.extended_search);
}
if (action === 'include') {
// Lines must match the existing query and be one of the selected
// line. Which means that is user change the query, one of the
// selected line could disappear.
if (search_query) {
search_query = new ComplexQuery({
operator: "AND",
query_list: [
new ComplexQuery({
operator: "OR",
query_list: query_list,
type: "complex"
}),
search_query
],
type: "complex"
});
} else {
search_query = new ComplexQuery({
operator: "OR",
query_list: query_list,
type: "complex"
});
}
} else {
// Lines must match the existing query and must not be one of the
// selected line.
if (search_query) {
query_list.push(search_query);
}
search_query = new ComplexQuery({
operator: "AND",
query_list: query_list,
type: "complex"
});
}
return gadget.redirect({ return gadget.redirect({
command: 'store_and_change', command: 'store_and_change',
options: { options: {
"extended_search": Query.objectToSearchText(search_query) "extended_search": updateSearchQueryFromSelection(
gadget.state.extended_search,
checked_uid_list,
'catalog.uid',
(action === 'include')
)
} }
}, true); }, true);
} }
if (action !== 'delete_document_list') {
return triggerListboxClipboardAction.apply(this, [argument_list]);
}
throw new Error('Unsupported triggerListboxSelectAction action: ' + action); throw new Error('Unsupported triggerListboxSelectAction action: ' + action);
}); })
// Handle listbox custom button
.allowPublicAcquisition("getListboxClipboardActionList", function getListboxClipboardActionList() {
var action_list = ensureArray(this.state.erp5_document._links.action_object_list_action || []),
i,
result_list = [],
icon;
for (i = 0; i < action_list.length; i += 1) {
if (action_list[i].name === 'delete_document_list') {
icon = 'trash-o';
} else {
continue;
}
result_list.push({
title: action_list[i].title,
icon: icon,
action: action_list[i].name
});
}
return result_list;
})
.allowPublicAcquisition("triggerListboxClipboardAction", triggerListboxClipboardAction);
}(window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery, Query, }(window, rJS, RSVP, calculatePageTitle, SimpleQuery, ComplexQuery, Query,
QueryFactory)); QueryFactory, ensureArray));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.58906.44395.12356</string> </value> <value> <string>973.131.13855.5137</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1547195702.72</float> <float>1547545219.53</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -51,17 +51,60 @@ ...@@ -51,17 +51,60 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" />
</tal:block> </tal:block>
<tr><td>waitForElementPresent</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_clipboard" />
<td>//a[@data-i18n='Actions']</td><td></td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr><td>click</td> <tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '2 Records'}">
<td>//a[@data-i18n='Actions']</td><td></td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//tbody/tr/td/input[@type="checkbox"]</td>
<td></td>
</tr>
<!-- Check the listbox column header -->
<tal:block tal:define="header_configuration python: {'text': 'ID', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_header" />
</tal:block>
<tal:block tal:define="header_configuration python: {'text': 'Title', 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_header" />
</tal:block>
<tal:block tal:define="header_configuration python: {'text': 'Quantity', 'index': 2}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_header" />
</tal:block>
<tal:block tal:define="header_configuration python: {'text': 'State', 'index': 3}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_header" />
</tal:block>
<!-- Check the listbox cell -->
<tal:block tal:define="cell_configuration python: {'text': 'Title 3', 'line': 0, 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
</tal:block>
<tal:block tal:define="cell_configuration python: {'text': 'Title 5', 'line': 1, 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
</tal:block>
<!-- Line checkbox -->
<tal:block tal:define="line_configuration python: {'value': 'off', 'line': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_line_selection" />
</tal:block>
<tal:block tal:define="line_configuration python: {'line': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/select_listbox_line" />
</tal:block>
<tr><td>waitForElementPresent</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/delete_selected_line" />
<td>//a[@data-i18n='Delete Multiple Documents']</td><td></td></tr>
<tr><td>click</td>
<td>//a[@data-i18n='Delete Multiple Documents']</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/assert_listbox_not_selectable" />
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '1 Records'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" />
</tal:block>
<tal:block tal:define="cell_configuration python: {'text': 'Title 5', 'line': 0, 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
...@@ -73,36 +116,25 @@ ...@@ -73,36 +116,25 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block> </tal:block>
<tal:block tal:define="parsed_query python: '( title:&nbsp; &quot;Title 3&quot; OR id:&nbsp; &quot;5&quot; )';
search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '2 Records'}"> <tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '2 Records'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" />
</tal:block> </tal:block>
<tal:block tal:define="cell_configuration python: {'text': 'Title 3', 'line': 0, 'index': 1}">
<tr><td>assertText</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[1]/td[4]//a</td> </tal:block>
<td>deleted</td></tr> <tal:block tal:define="cell_configuration python: {'text': 'draft', 'line': 0, 'index': 3}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
<tr><td>assertText</td> </tal:block>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[2]/td[4]//a</td> <tal:block tal:define="cell_configuration python: {'text': 'Title 5', 'line': 1, 'index': 1}">
<td>deleted</td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/clear_query" /> <tal:block tal:define="cell_configuration python: {'text': 'deleted', 'line': 1, 'index': 3}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_cell_text" />
<tal:block tal:define="pagination_configuration python: {'header': '(6)', 'footer': '6 Records'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_listbox_pagination_text" />
</tal:block> </tal:block>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[1]/td[4]//a</td>
<td>draft</td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[3]/td[4]//a</td>
<td>deleted</td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[5]/td[4]//a</td>
<td>deleted</td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[6]/td[4]//a</td>
<td>draft</td></tr>
</tbody></table> </tbody></table>
</body> </body>
......
...@@ -46,16 +46,12 @@ ...@@ -46,16 +46,12 @@
<tr><td>open</td> <tr><td>open</td>
<td>${renderjs_url}/#/foo_module</td><td></td></tr> <td>${renderjs_url}/#/foo_module</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<tr><td>waitForElementPresent</td>
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr>
<tr><td>click</td>
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tr><td>click</td>
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_select" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/change_state_selected_line" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr><th colspan="3">All actions are always visible</th></tr> <tr><th colspan="3">All actions are always visible</th></tr>
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//select[@name="field_your_mass_workflow_action"]/option</td><td></td></tr> <td>//select[@name="field_your_mass_workflow_action"]/option</td><td></td></tr>
...@@ -68,21 +64,15 @@ ...@@ -68,21 +64,15 @@
<tr><td>click</td> <tr><td>click</td>
<td>//div[@data-role="header"]//h1//a</td><td></td></tr> <td>//div[@data-role="header"]//h1//a</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tal:block tal:define='search_query string:( title: "Title 1%" OR title: "Title 3%" )'> <tal:block tal:define='search_query string:( title: "Title 1%" OR title: "Title 3%" )'>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/search_in_form_list" />
</tal:block> </tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr><td>waitForElementPresent</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_select" />
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr><td>click</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/change_state_selected_line" />
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tr><td>click</td>
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
...@@ -158,14 +148,12 @@ ...@@ -158,14 +148,12 @@
</tr> </tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr><td>waitForElementPresent</td>
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_select" />
<tr><td>click</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<td>//div[@data-role="header"]//a[@data-i18n="Actions"]</td><td></td></tr> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/change_state_selected_line" />
<tr><td>waitForElementPresent</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tr><td>click</td>
<td>//ul[@class="document-listview"]//a[@data-i18n="Change State"]</td><td></td></tr>
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//select[@name="field_your_mass_workflow_action"]/option[@value="invalidate_action"]</td><td></td></tr> <td>//select[@name="field_your_mass_workflow_action"]/option[@value="invalidate_action"]</td><td></td></tr>
......
...@@ -1401,6 +1401,46 @@ ...@@ -1401,6 +1401,46 @@
</tr> </tr>
</tal:block> </tal:block>
<tal:block metal:define-macro="triggle_clipboard">
<tr>
<td colspan="3"><b>Switch to clipboard mode</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard']</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard' and @disabled]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard']</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard']</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='Clipboard']</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="check_listbox_cell_text"> <tal:block metal:define-macro="check_listbox_cell_text">
<tr> <tr>
<td colspan="3"><b tal:content="python: 'Check the listbox cell %(line)i %(index)i' % cell_configuration"></b></td> <td colspan="3"><b tal:content="python: 'Check the listbox cell %(line)i %(index)i' % cell_configuration"></b></td>
...@@ -1507,6 +1547,54 @@ ...@@ -1507,6 +1547,54 @@
</tr> </tr>
</tal:block> </tal:block>
<tal:block metal:define-macro="delete_selected_line">
<tr>
<td colspan="3"><b>Delete selected lines</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='ClipboardAction' and @data-clipboard-action='delete_document_list']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='ClipboardAction' and @data-clipboard-action='delete_document_list']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='ClipboardAction' and @data-clipboard-action='delete_document_list']</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="change_state_selected_line">
<tr>
<td colspan="3"><b>Change state selected lines</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='SelectAction' and @data-select-action='mass_workflow_jio']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='SelectAction' and @data-select-action='mass_workflow_jio']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//button[@name='SelectAction' and @data-select-action='mass_workflow_jio']</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="assert_listbox_not_selectable"> <tal:block metal:define-macro="assert_listbox_not_selectable">
<tr> <tr>
<td colspan="3"><b tal:content="python: 'Check the listbox is not in select mode'"></b></td> <td colspan="3"><b tal:content="python: 'Check the listbox is not in select mode'"></b></td>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment