Commit 7e9f3d80 authored by Romain Courteaud's avatar Romain Courteaud

erp5_web_renderjs_ui: stop using handlebars

Replace it by domsugar.

This speed up gadget class generation (handlebars template parsing is
slow).
parent 230ceb15
<!DOCTYPE html>
<html>
<head>
<!--
data-i18n=Submit
data-i18n=Configure Editor
data-i18n=Close
data-i18n=Add Criteria
data-i18n=Reset
-->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>ERP5 Configure Editor</title>
......@@ -9,52 +16,11 @@
<!-- renderjs -->
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<!-- custom script -->
<script src="gadget_erp5_configure_editor.js"></script>
<script id="column-item-template" type="text/x-handlebars-template">
<button type="button" class="ui-icon ui-icon-minus"></button>
<div class="column_item ui-controlgroup-controls" >
<select>
{{#each option}}
{{#equal value selected_option}}
<option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
{{else}}
<option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
{{/equal}}
{{/each}}
</select>
</div>
</script>
<script id="column-template" type="text/x-handlebars-template">
<div>
<div data-role="header" class="ui-header">
<div class="ui-btn-right">
<div class="ui-controlgroup-controls">
<button data-i18n="Submit" type="submit" class="submit ui-btn-icon-left ui-icon-check">Submit</button>
</div>
</div>
<h1 data-i18n="Configure Editor">Configure Editor</h1>
<div class="ui-btn-left">
<div class="ui-controlgroup-controls">
<button data-i18n="Close" type="button" class="close ui-btn-icon-left ui-icon-times">Close</button>
</div>
</div>
</div>
<section>
<div class="column_item_container"></div>
<button type="button" class="plus ui-icon-plus ui-btn-icon-left">Add Criteria</button>
<button type="button" class="trash ui-icon-trash-o ui-btn-icon-left">Reset</button>
</section>
</div>
</script>
</head>
<body>
<form>
......
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, document, rJS, RSVP, Handlebars*/
(function (window, document, rJS, RSVP, Handlebars) {
/*global window, rJS, domsugar*/
(function (window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
template_element = gadget_klass.__template_element,
column_item_template = Handlebars.compile(template_element
.getElementById("column-item-template")
.innerHTML),
column_template = Handlebars.compile(template_element
.getElementById("column-template")
.innerHTML);
Handlebars.registerHelper('equal', function (left_value, right_value, options) {
if (arguments.length < 3) {
throw new Error("Handlebars Helper equal needs 2 parameters");
}
if (left_value !== right_value) {
return options.inverse(this);
}
return options.fn(this);
});
function createColumnItemTemplate(gadget, column_value, displayable_column_list) {
function createColumnItemTemplate(column_value, displayable_column_list) {
var column_value_list = column_value || [],
option_list = [],
dom_option_list = [],
option_dict,
i;
for (i = 0; i < displayable_column_list.length; i += 1) {
option_list.push({
text: displayable_column_list[i][1],
option_dict = {
value: displayable_column_list[i][0],
selected_option: column_value_list[0]
});
// Used to be translated
text: displayable_column_list[i][1]
};
if (column_value_list[0] === option_dict.value) {
option_dict.selected = "selected";
}
dom_option_list.push(domsugar('option', option_dict));
}
return gadget.translateHtml(column_item_template({
option: option_list
}));
return domsugar('div', [
domsugar('button', {class: 'ui-icon ui-icon-minus'}),
domsugar('div', {class: 'column_item ui-controlgroup-controls'}, [
domsugar('select', dom_option_list)
])
]);
}
gadget_klass
rJS(window)
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("trigger", "trigger")
.onStateChange(function onStateChange() {
var gadget = this,
div = document.createElement("div"),
container = gadget.element.querySelector(".container");
return gadget.translateHtml(column_template())
.push(function (translated_html) {
div.innerHTML = translated_html;
return RSVP.all(gadget.state.column_list
.map(function (column_item) {
return createColumnItemTemplate(gadget, column_item, gadget.state.displayable_column_list);
})
);
})
.push(function (result_list) {
var i,
subdiv,
filter_item_container = div.querySelector('.column_item_container');
for (i = 0; i < result_list.length; i += 1) {
subdiv = document.createElement("div");
subdiv.innerHTML = result_list[i];
filter_item_container.appendChild(subdiv);
}
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(div);
var gadget = this;
return gadget.getTranslationList([
'Submit',
'Configure Editor',
'Close',
'Add Criteria',
'Reset'
])
.push(function (translation_list) {
var column_dom_list =
gadget.state.column_list.map(
function (column_item) {
return createColumnItemTemplate(
column_item,
gadget.state.displayable_column_list
);
}
);
domsugar(gadget.element.querySelector(".container"), [
domsugar('div', [
domsugar('div', {'data-role': 'header', 'class': 'ui-header'}, [
domsugar('div', {class: 'ui-btn-right'}, [
domsugar('div', {class: 'ui-controlgroup-controls'}, [
domsugar('button', {
type: 'submit',
class: 'submit ui-btn-icon-left ui-icon-check',
text: translation_list[0]
})
])
]),
domsugar('h1', {text: translation_list[1]}),
domsugar('div', {class: 'ui-btn-left'}, [
domsugar('div', {class: 'ui-controlgroup-controls'}, [
domsugar('button', {
type: 'submit',
class: 'close ui-btn-icon-left ui-icon-times',
text: translation_list[2]
})
])
])
]),
domsugar('section', [
domsugar('div', {class: 'column_item_container'},
column_dom_list),
domsugar('button', {
class: 'plus ui-icon-plus ui-btn-icon-left',
text: translation_list[3]
}),
domsugar('button', {
class: 'trash ui-icon-trash-o ui-btn-icon-left',
text: translation_list[4]
})
])
])
]);
});
})
......@@ -92,15 +109,11 @@
})
.onEvent('click', function click(evt) {
var gadget = this,
container;
var gadget = this;
if (evt.target.classList.contains('trash')) {
evt.preventDefault();
container = gadget.element.querySelector(".column_item_container");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
domsugar(gadget.element.querySelector(".column_item_container"));
}
if (evt.target.classList.contains('close')) {
......@@ -110,13 +123,11 @@
if (evt.target.classList.contains('plus')) {
evt.preventDefault();
return createColumnItemTemplate(gadget, undefined, gadget.state.displayable_column_list)
.push(function (template) {
var tmp = document.createElement("div");
container = gadget.element.querySelector(".column_item_container");
tmp.innerHTML = template;
container.appendChild(tmp);
});
return gadget.element.querySelector(".column_item_container")
.appendChild(
createColumnItemTemplate(undefined,
gadget.state.displayable_column_list)
);
}
if (evt.target.classList.contains('ui-icon-minus')) {
......@@ -156,4 +167,4 @@
}, true);
});
}(window, document, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, domsugar));
\ No newline at end of file
......@@ -9,20 +9,9 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="gadget_erp5_field_matrixbox.js" type="text/javascript"></script>
<script id="table-template" type="text/x-handlebars-template">
<thead>
<tr>
<th>{{table_title}}</th>
{{#each header}}
<th>{{this}}</th>
{{/each}}
</tr>
</thead>
</script>
</head>
<body>
<div class="document_table"></div>
......
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, document, rJS, RSVP, Handlebars, JSON*/
/*global window, document, rJS, RSVP, domsugar, JSON*/
/** MatrixBox renders a N-dimensional cube of editable values based on axes description.
*
* Example JSON returned from HATEOAS where cell_range format is
......@@ -33,15 +33,9 @@
see around https://lab.nexedi.com/nexedi/erp5/blob/feature/renderjs-matrixbox/product/ERP5Form/MatrixBox.py#L427
*
*/
(function (window, document, rJS, RSVP, Handlebars, JSON) {
(function (window, document, rJS, RSVP, domsugar, JSON) {
"use strict";
var gadget_klass = rJS(window),
table_template_source = gadget_klass.__template_element
.getElementById("table-template")
.innerHTML,
table_template = Handlebars.compile(table_template_source);
/** Recursively introspect an object if it is empty */
function is_empty_recursive(data) {
var item;
......@@ -77,23 +71,11 @@
key: ''
})
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getFieldTypeGadgetUrl", "getFieldTypeGadgetUrl")
.declareAcquiredMethod("renderEditorPanel", "renderEditorPanel")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("translate", "translate")
/** Render constructs and saves gadgets into `props.gadget_dict` if they don not exist yet.
*/
.declareMethod('render', function (options) {
var gadget = this,
element = gadget.element.querySelector('div.document_table'),
data = options.field_json.data,
// note we make COPY of data in their original form - important since
// data.shift used later modify the structure inplace!
......@@ -117,11 +99,7 @@
.push(function () {
return RSVP.all(data.map(function (table, table_index) {
var header = table.shift(), // first item of table is the header
table_title = header.shift(), // first item of header is the table (tab) title
table_body = document.createElement('tbody'),
table_element = document.createElement('table');
table_element.innerHTML = table_template({table_title: table_title, header: header});
table_title = header.shift(); // first item of header is the table (tab) title
return new RSVP.Queue()
.push(function () {
......@@ -158,18 +136,25 @@
}));
})
.push(function (row_element_list) {
row_element_list.forEach(function (row_element) {
table_body.appendChild(row_element);
});
table_element.appendChild(table_body);
return table_element;
var th_dom_list = [
domsugar('th', {text: table_title})
],
i;
for (i = 0; i < header.length; i += 1) {
th_dom_list.push(domsugar('th', {html: header[i]}));
}
return domsugar('table', [
domsugar('thead', [
domsugar('tr', th_dom_list)
]),
domsugar('tbody', row_element_list)
]);
});
}));
})
.push(function (table_element_list) {
table_element_list.forEach(function (table_element) {
element.appendChild(table_element);
});
domsugar(gadget.element.querySelector('div.document_table'),
table_element_list);
return gadget.changeState(new_state);
});
})
......@@ -270,4 +255,4 @@
return true;
});
}(window, document, rJS, RSVP, Handlebars, JSON));
}(window, document, rJS, RSVP, domsugar, JSON));
......@@ -9,16 +9,7 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script id="success-button-template" type="text/x-handlebars-template">
<button type="submit" class='success'>{{message}}</button>
</script>
<script id="error-button-template" type="text/x-handlebars-template">
<button type="submit" class='error'>{{message}}</button>
</script>
<script src="domsugar.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_erp5_notification.js" type="text/javascript"></script>
......
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, Node, rJS, Handlebars */
(function (window, Node, rJS, Handlebars) {
/*global window, Node, rJS, domsugar */
(function (window, Node, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
success_button_source = gadget_klass.__template_element
.getElementById("success-button-template")
.innerHTML,
success_button_template = Handlebars.compile(success_button_source),
error_button_source = gadget_klass.__template_element
.getElementById("error-button-template")
.innerHTML,
error_button_template = Handlebars.compile(error_button_source);
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
gadget_klass
rJS(window)
.declareMethod('notify', function (options) {
if (options && options.message) {
return this.changeState({
......@@ -51,15 +40,13 @@
}
if (modification_dict.hasOwnProperty('message')) {
if (this.state.status === 'success') {
this.element.innerHTML = success_button_template({
message: this.state.message
});
} else {
this.element.innerHTML = error_button_template({
message: this.state.message
});
}
domsugar(this.element, [
domsugar('button', {
type: 'submit',
class: (this.state.status === 'success') ? 'success' : 'error',
text: this.state.message
})
]);
}
})
......@@ -71,4 +58,4 @@
}
}, false, false);
}(window, Node, rJS, Handlebars));
\ No newline at end of file
}(window, Node, rJS, domsugar));
\ No newline at end of file
......@@ -16,7 +16,7 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
......@@ -24,20 +24,6 @@
<script src="gadget_erp5_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_action.js" type="text/javascript"></script>
<script id="table-template" type="text/x-handlebars-template">
<section class="ui-content-header-plain">
<h3 data-i18n="[last]{{definition_i18n}}">
<span class="ui-icon ui-icon-{{definition_icon}}">&nbsp;</span>
{{definition_title}}
</h3>
</section>
<ul class="document-listview">
{{#each document_list}}
<li><a data-i18n="{{title}}" href="{{link}}">{{title}}</a></li>
{{/each}}
</ul>
</script>
</head>
<body>
</body>
......
/*global window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray */
/*global window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray) {
(function (window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
table_template = Handlebars.compile(gadget_klass.__template_element
.getElementById("table-template")
.innerHTML);
/** Render translated HTML of title + links
*
* @param {string} title - H3 title of the section with the links
* @param {string} icon - alias used in font-awesome iconset
* @param {Array} command_list - array of links obtained from ERP5 HATEOAS
*/
function renderLinkList(gadget, jio_key, title, icon, erp5_link_list,
editable) {
return new RSVP.Queue()
.push(function () {
return RSVP.all(
erp5_link_list.map(function (erp5_link) {
return gadget.getUrlFor({
"command": 'display_with_history_and_cancel',
"options": {
"jio_key": jio_key,
"view": erp5_link.href,
"editable": editable
}
});
})
);
})
.push(function (url_list) {
// prepare links for template (replace @href for RJS link)
return gadget.translateHtml(
table_template({
"definition_i18n": title,
"definition_title": title,
"definition_icon": icon,
"document_list": erp5_link_list.map(function (erp5_link, index) {
return {
"title": erp5_link.title,
"i18n": erp5_link.title,
"link": url_list[index]
};
})
})
);
});
}
function generateSection(title, icon, view_list) {
var i,
dom_list = [];
for (i = 0; i < view_list.length; i += 1) {
dom_list.push(domsugar('li', [domsugar('a', {
href: view_list[i].link,
text: view_list[i].title
})]));
}
return domsugar(null, [
domsugar('section', {class: 'ui-content-header-plain'}, [
domsugar('h3', [
domsugar('span', {class: 'ui-icon ui-icon-' + icon, html: '&nbsp;'}),
title
])
]),
domsugar('ul', {class: 'document-listview'}, dom_list)
]);
gadget_klass
}
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
/** Render only transforms its arguments and passes them to mutex-protected onStateChange
options:
jio_key: {string} currently viewed document (e.g. foo/1)
page: {string} selected page (always "tab" for page_tab)
view: {string} always "view"
selection, history, selection_index
*/
.declareMethod("render", function (options) {
return this.changeState({
jio_key: options.jio_key,
editable: options.editable,
view: options.view
});
})
.onStateChange(function () {
var gadget = this,
erp5_document;
erp5_document,
group_list;
// Get the whole view as attachment because actions can change based on
// what view we are at. If no view available than fallback to "links".
return gadget.jio_getAttachment(options.jio_key, options.view || "links")
return gadget.jio_getAttachment(gadget.state.jio_key, gadget.state.view || "links")
.push(function (jio_attachment) {
var transition_list = ensureArray(jio_attachment._links.action_workflow),
action_list = ensureArray(jio_attachment._links.action_object_jio_action)
.concat(ensureArray(jio_attachment._links.action_object_jio_button))
.concat(ensureArray(jio_attachment._links.action_object_jio_fast_input)),
clone_list = ensureArray(jio_attachment._links.action_object_clone_action),
delete_list = ensureArray(jio_attachment._links.action_object_delete_action);
erp5_document = jio_attachment;
return RSVP.all([
renderLinkList(gadget, options.jio_key, "Workflows", "random", transition_list),
renderLinkList(gadget, options.jio_key, "Actions", "gear", action_list),
// Stay in editable mode after cloning, as user will probably edit the new document
renderLinkList(gadget, options.jio_key, "Clone", "clone", clone_list, true),
renderLinkList(gadget, options.jio_key, "Delete", "trash-o", delete_list)
]);
})
.push(function (translated_html_link_list) {
gadget.element.innerHTML = translated_html_link_list.join("\n");
return RSVP.all([
calculatePageTitle(gadget, erp5_document),
gadget.getUrlFor({command: 'cancel_dialog_with_history'})
]);
var i,
j,
url_for_kw_list = [];
group_list = [
// Action list, editable, icon
ensureArray(erp5_document._links.action_workflow), undefined, 'random',
ensureArray(erp5_document._links.action_object_jio_action)
.concat(ensureArray(erp5_document._links.action_object_jio_button))
.concat(ensureArray(erp5_document._links.action_object_jio_fast_input)), undefined, 'gear',
ensureArray(erp5_document._links.action_object_clone_action), true, 'clone',
ensureArray(erp5_document._links.action_object_delete_action), undefined, 'trash-o'];
for (i = 0; i < group_list.length; i += 3) {
for (j = 0; j < group_list[i].length; j += 1) {
url_for_kw_list.push({command: 'display_with_history_and_cancel', options: {
jio_key: gadget.state.jio_key,
view: group_list[i][j].href,
editable: group_list[i + 1]
}});
}
}
url_for_kw_list.push({command: 'cancel_dialog_with_history'});
return RSVP.hash({
url_list: gadget.getUrlForList(url_for_kw_list),
translation_list: gadget.getTranslationList(['Workflows', 'Actions', 'Clone', 'Delete']),
page_title: calculatePageTitle(gadget, erp5_document)
});
})
.push(function (result_list) {
.push(function (result_dict) {
var i,
j,
k = 0,
dom_list = [],
link_list;
for (i = 0; i < group_list.length; i += 3) {
link_list = [];
for (j = 0; j < group_list[i].length; j += 1) {
link_list.push({
title: group_list[i][j].title,
link: result_dict.url_list[k]
});
k += 1;
}
dom_list.push(
generateSection(result_dict.translation_list[i / 3], group_list[i + 2], link_list)
);
}
domsugar(gadget.element, dom_list);
return gadget.updateHeader({
page_title: result_list[0],
back_url: result_list[1]
back_url: result_dict.url_list[result_dict.url_list.length - 1],
page_title: result_dict.page_title
});
});
})
......@@ -111,4 +133,4 @@
return;
});
}(window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray));
\ No newline at end of file
}(window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray));
......@@ -2,18 +2,20 @@
<html>
<head>
<!--
data-i18n=Report
data-i18n=Export
data-i18n=Reports
data-i18n=Print
-->
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>ERP5 Page Action</title>
<title>ERP5 Page Export</title>
<link rel="http://www.renderjs.org/rel/interface" href="interface_page.html">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
......@@ -21,20 +23,6 @@
<script src="gadget_erp5_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_export.js" type="text/javascript"></script>
<script id="table-template" type="text/x-handlebars-template">
<section class="ui-content-header-plain">
<h3 data-i18n="[last]{{definition_i18n}}">
<span class="ui-icon ui-icon-{{definition_icon}}">&nbsp;</span>
{{definition_title}}
</h3>
</section>
<ul class="document-listview">
{{#each document_list}}
<li><a data-i18n="{{title}}" href="{{link}}">{{title}}</a></li>
{{/each}}
</ul>
</script>
</head>
<body>
</body>
......
/*global window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray */
/*global window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray) {
(function (window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
table_template = Handlebars.compile(gadget_klass.__template_element
.getElementById("table-template")
.innerHTML);
/** Render translated HTML of title + links
*
* @param {string} title - H3 title of the section with the links
* @param {string} icon - alias used in font-awesome iconset
* @param {Array} command_list - array of links obtained from ERP5 HATEOAS
*/
function renderLinkList(gadget, jio_key, title, icon, erp5_link_list) {
return new RSVP.Queue()
.push(function () {
// obtain RJS links from ERP5 links
return RSVP.all(
erp5_link_list.map(function (erp5_link) {
return gadget.getUrlFor({
"command": 'display_with_history_and_cancel',
"options": {
"jio_key": jio_key,
"view": erp5_link.href
}
});
})
);
})
.push(function (url_list) {
// prepare links for template (replace @href for RJS link)
return gadget.translateHtml(
table_template({
"definition_i18n": title,
"definition_title": title,
"definition_icon": icon,
"document_list": erp5_link_list.map(function (erp5_link, index) {
return {
"title": erp5_link.title,
"i18n": erp5_link.title,
"link": url_list[index]
};
})
})
);
});
function generateSection(title, icon, view_list) {
var i,
dom_list = [];
for (i = 0; i < view_list.length; i += 1) {
dom_list.push(domsugar('li', [domsugar('a', {
href: view_list[i].link,
text: view_list[i].title
})]));
}
return domsugar(null, [
domsugar('section', {class: 'ui-content-header-plain'}, [
domsugar('h3', [
domsugar('span', {class: 'ui-icon ui-icon-' + icon, html: '&nbsp;'}),
title
])
]),
domsugar('ul', {class: 'document-listview'}, dom_list)
]);
}
gadget_klass
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("updateHeader", "updateHeader")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
/** Render only transforms its arguments and passes them to mutex-protected onStateChange
options:
jio_key: {string} currently viewed document (e.g. foo/1)
page: {string} selected page (always "tab" for page_tab)
view: {string} always "view"
selection, history, selection_index
*/
.declareMethod("render", function (options) {
return this.changeState({
jio_key: options.jio_key,
editable: options.editable,
view: options.view
});
})
.onStateChange(function () {
var gadget = this,
erp5_document;
erp5_document,
group_list;
// Get the whole view as attachment because actions can change based on
// what view we are at. If no view available than fallback to "links".
return gadget.jio_getAttachment(options.jio_key, options.view || "links")
.push(function (result) {
var export_list = ensureArray(result._links.action_object_jio_exchange),
report_list = ensureArray(result._links.action_object_jio_report),
print_list = ensureArray(result._links.action_object_jio_print);
erp5_document = result;
return RSVP.all([
renderLinkList(gadget, options.jio_key, "Export", "exchange", export_list),
renderLinkList(gadget, options.jio_key, "Reports", "bar-chart-o", report_list),
renderLinkList(gadget, options.jio_key, "Print", "print", print_list)
]);
})
.push(function (translated_html_link_list) {
gadget.element.innerHTML = translated_html_link_list.join("\n");
return RSVP.all([
calculatePageTitle(gadget, erp5_document),
gadget.getUrlFor({command: 'cancel_dialog_with_history', options: {jio_key: options.jio_key}})
]);
return gadget.jio_getAttachment(gadget.state.jio_key, gadget.state.view || "links")
.push(function (jio_attachment) {
erp5_document = jio_attachment;
var i,
j,
url_for_kw_list = [];
group_list = [
// Action list, icon
ensureArray(erp5_document._links.action_object_jio_exchange), "exchange",
ensureArray(erp5_document._links.action_object_jio_report), "bar-chart-o",
ensureArray(erp5_document._links.action_object_jio_print), "print"
];
for (i = 0; i < group_list.length; i += 2) {
for (j = 0; j < group_list[i].length; j += 1) {
url_for_kw_list.push({command: 'display_with_history_and_cancel', options: {
jio_key: gadget.state.jio_key,
view: group_list[i][j].href
}});
}
}
url_for_kw_list.push({command: 'cancel_dialog_with_history'});
return RSVP.hash({
url_list: gadget.getUrlForList(url_for_kw_list),
translation_list: gadget.getTranslationList(['Export', 'Reports', 'Print']),
page_title: calculatePageTitle(gadget, erp5_document)
});
})
.push(function (result_list) {
.push(function (result_dict) {
var i,
j,
k = 0,
dom_list = [],
link_list;
for (i = 0; i < group_list.length; i += 2) {
link_list = [];
for (j = 0; j < group_list[i].length; j += 1) {
link_list.push({
title: group_list[i][j].title,
link: result_dict.url_list[k]
});
k += 1;
}
dom_list.push(
generateSection(result_dict.translation_list[i / 2], group_list[i + 1], link_list)
);
}
domsugar(gadget.element, dom_list);
return gadget.updateHeader({
page_title: result_list[0],
back_url: result_list[1]
back_url: result_dict.url_list[result_dict.url_list.length - 1],
page_title: result_dict.page_title
});
});
})
......@@ -104,4 +130,4 @@
return;
});
}(window, rJS, RSVP, Handlebars, calculatePageTitle, ensureArray));
\ No newline at end of file
}(window, rJS, RSVP, domsugar, calculatePageTitle, ensureArray));
\ No newline at end of file
......@@ -9,22 +9,13 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_history.js" type="text/javascript"></script>
<!-- XXX must set theme here! -->
<script id="table-template" type="text/x-handlebars-template">
<ul class="document-listview">
{{#each document_list}}
<li><a href="{{link}}">{{title}}</a></li>
{{/each}}
</ul>
</script>
</head>
<body>
<section class="document_list"></section>
......
/*global window, rJS, RSVP, Handlebars, SimpleQuery, ComplexQuery, Query */
/*global window, rJS, RSVP, domsugar, SimpleQuery, ComplexQuery, Query */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, SimpleQuery, ComplexQuery, Query) {
(function (window, rJS, RSVP, domsugar, SimpleQuery, ComplexQuery, Query) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.getElementById("table-template")
.innerHTML,
table_template = Handlebars.compile(source);
gadget_klass
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
......@@ -74,25 +64,29 @@
})
.push(function (url_list) {
var i,
document_list = [],
dom_list = [],
document_dict = {};
for (i = 2; i < url_list.length; i += 1) {
document_dict[row_list[i - 2].id] = {
link: url_list[i],
title: (row_list[i - 2].value.title || row_list[i - 2].id) +
href: url_list[i],
text: (row_list[i - 2].value.title || row_list[i - 2].id) +
" (" + row_list[i - 2].value.translated_portal_type + ")"
};
}
// Sort by access time
for (i = 0; i < id_list.length; i += 1) {
if (document_dict.hasOwnProperty(id_list[i])) {
document_list.push(document_dict[id_list[i]]);
dom_list.push(domsugar('li', [
domsugar('a', document_dict[id_list[i]])
]));
}
}
gadget.element.querySelector('.document_list').innerHTML = table_template(
{document_list: document_list}
);
domsugar(gadget.element.querySelector('.document_list'), [
domsugar('ul', {class: 'document-listview'}, dom_list)
]);
return gadget.updateHeader({
page_title: 'History',
page_icon: 'history',
......@@ -104,4 +98,4 @@
.declareMethod("triggerSubmit", function () {
return;
});
}(window, rJS, RSVP, Handlebars, SimpleQuery, ComplexQuery, Query));
\ No newline at end of file
}(window, rJS, RSVP, domsugar, SimpleQuery, ComplexQuery, Query));
\ No newline at end of file
......@@ -13,29 +13,13 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_worklist.js" type="text/javascript"></script>
<!-- XXX must set theme here! -->
<script id="table-template" type="text/x-handlebars-template">
{{#if document_list }}
<ul class="document-listview">
{{#each document_list}}
<li class="ui-li-has-count"><a href="{{link}}">{{title}} <span class="ui-li-count">{{count}}</span></a></li>
{{/each}}
</ul>
{{else}}
<div class="worklist-empty">
<h2>{{empty_text}}</h2>
<img src="gadget_erp5_worklist_empty.svg?format=svg">
</div>
{{/if}}
</script>
</head>
<body>
<section class="document_list"></section>
......
/*global window, rJS, RSVP, Handlebars, URI */
/*global window, rJS, RSVP, domsugar, URI */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, URI) {
(function (window, rJS, RSVP, domsugar, URI) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.getElementById("table-template")
.innerHTML,
table_template = Handlebars.compile(source);
gadget_klass
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
......@@ -85,23 +75,34 @@
})
// Add in the page
.push(function (result_list) {
var line_list = [],
url_list = result_list[1],
i;
var url_list = result_list[1],
i,
dom_list = [];
for (i = 2; i < url_list.length; i += 1) {
line_list.push({
link: url_list[i],
// Remove the counter from the title
title: action_list[i - 2].name,
count: action_list[i - 2].count
});
dom_list.push(domsugar('li', {class: 'ui-li-has-count'}, [
domsugar('a', {href: url_list[i]}, [
action_list[i - 2].name,
' ',
domsugar('span', {class: 'ui-li-count',
text: action_list[i - 2].count})
])
]));
}
if (dom_list.length) {
domsugar(gadget.element.querySelector('.document_list'), [
domsugar('ul', {class: 'document-listview'}, dom_list)
]);
} else {
domsugar(gadget.element.querySelector('.document_list'), [
domsugar('div', {class: 'worklist-empty'}, [
domsugar('h2', {text: result_list[0]}),
domsugar('img', {src: 'gadget_erp5_worklist_empty.svg?format=svg'})
])
]);
}
gadget.element.querySelector('.document_list').innerHTML =
table_template({
document_list: line_list,
empty_text: result_list[0]
});
return gadget.updateHeader({
page_title: 'Worklist',
page_icon: 'tasks',
......@@ -114,4 +115,4 @@
return;
});
}(window, rJS, RSVP, Handlebars, URI));
\ No newline at end of file
}(window, rJS, RSVP, domsugar, URI));
\ No newline at end of file
......@@ -11,7 +11,7 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script id="dialog-button-template" type="text/x-handlebars-template">
{{#if show_update_button}}
......
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, document, rJS, RSVP, calculatePageTitle, Handlebars,
/*global window, rJS, RSVP, calculatePageTitle, domsugar,
ensureArray */
(function (window, document, rJS, RSVP, calculatePageTitle, Handlebars,
(function (window, rJS, RSVP, calculatePageTitle, domsugar,
ensureArray) {
"use strict";
......@@ -86,7 +86,8 @@
(!result.view)) {
// don't update navigation history when not really redirecting
return gadget.redirect({command: 'cancel_dialog_with_history'});
} else if (gadget.state.jio_key === result.jio_key) {
}
if (gadget.state.jio_key === result.jio_key) {
command = 'display_with_history_and_cancel';
} else {
// Check if the redirection goes to a same parent's subdocument.
......@@ -133,13 +134,7 @@
return submitDialog.apply(this, [false, param_list[0]]);
}
var gadget_klass = rJS(window),
dialog_button_source = gadget_klass.__template_element
.getElementById("dialog-button-template")
.innerHTML,
dialog_button_template = Handlebars.compile(dialog_button_source);
gadget_klass
rJS(window)
.setState({
'redirect_to_parent': false, // set by a presence of special field
'has_update_action': undefined // default "submit" issue update in case of its presence
......@@ -152,8 +147,7 @@
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("translate", "translate")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("submitContent", "submitContent")
.allowPublicAcquisition("submitDialogWithCustomDialogMethod",
submitDialogWithCustomDialogMethod)
......@@ -238,31 +232,43 @@
// Set the dialog button
if (modification_dict.hasOwnProperty('has_update_action') ||
modification_dict.hasOwnProperty('update_action_title')) {
return form_gadget.translateHtml(dialog_button_template({
show_update_button: form_gadget.state.has_update_action
}))
.push(function (html) {
var div = document.createElement('div'),
dialog_button_container = form_gadget.element
.querySelector('.dialog_button_container');
div.innerHTML = html;
if (form_gadget.state.has_update_action && form_gadget.state.update_action_title) {
div.querySelector('button[name="action_update"]')
.textContent = form_gadget.state.form_definition
.update_action_title;
}
while (dialog_button_container.firstChild) {
dialog_button_container.firstChild.remove();
return form_gadget.getTranslationList(['Update', 'Proceed', 'Cancel'])
.push(function (translation_list) {
var dom_list = [];
if (form_gadget.state.has_update_action) {
dom_list.push(
domsugar('button', {disabled: true,
name: 'action_update',
type: 'button',
text: form_gadget.state.update_action_title || translation_list[0]}
)
);
}
dialog_button_container.innerHTML = div.innerHTML;
dom_list.push(
domsugar('input', {disabled: true,
name: 'action_confirm',
class: 'dialogconfirm',
type: 'submit',
value: translation_list[1]}),
domsugar('a', {class: 'dialogcancel',
text: translation_list[2]})
);
domsugar(form_gadget.element
.querySelector('.dialog_button_container'),
dom_list);
});
}
})
.push(function () {
// Calculate the h3 properties
return RSVP.all([
form_gadget.translate(form_gadget.state.form_definition.title),
form_gadget.translate(title)
return form_gadget.getTranslationList([
form_gadget.state.form_definition.title,
title
]);
})
.push(function (translated_title_list) {
......@@ -345,4 +351,4 @@
}
});
}(window, document, rJS, RSVP, calculatePageTitle, Handlebars, ensureArray));
\ No newline at end of file
}(window, rJS, RSVP, calculatePageTitle, domsugar, ensureArray));
\ No newline at end of file
......@@ -16,18 +16,7 @@
<!-- custom script -->
<script src="jiodev.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script id="card-list-template" type="text/x-handlebars-template">
{{#each card_list}}<li>
<h2>{{business_application_translated_title}}</h2>
<ul>
{{#each module_list}}
<li><a href="{{link}}">{{translated_title}}</a></li>
{{/each}}
</ul>
</li>{{/each}}
</script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="gadget_erp5_page_front.js" type="text/javascript"></script>
......
......@@ -14,11 +14,8 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script id="dialog-button-template" type="text/x-handlebars-template">
<input name="action_update" type="submit" value="{{button_text}}"></input>
</script>
<script src="gadget_erp5_page_language.js" type="text/javascript"></script>
</head>
......
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>981.4557.25079.32187</string> </value>
<value> <string>981.62315.62619.21640</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1578663234.35</float>
<float>1582128721.85</float>
<string>UTC</string>
</tuple>
</state>
......
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