Commit 33655726 authored by Roque's avatar Roque

erp5_officejs: new approach for officejs apps

parent ac9d82b0
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Common Utils</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_officejs_common_utils.js"></script>
</head>
<body>
</body>
</html>
/*global document, window, rJS, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (document, window, rJS, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("jio_put", "jio_put")
.declareAcquiredMethod("jio_post", "jio_post")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("isDesktopMedia", "isDesktopMedia")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod('getUrlParameter', 'getUrlParameter')
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("redirect", "redirect")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var gadget = this,
default_view,
app_view,
form_definition,
gadget_utils,
jio_document,
portal_type,
front_page;
return RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.declareGadget("gadget_officejs_common_utils.html"),
gadget.getSetting('app_view_reference'),
gadget.getSetting('default_view_reference'),
gadget.getSetting('documents_editable')
]);
})
.push(function (result_list) {
gadget_utils = result_list[0];
app_view = options.action || result_list[1];
default_view = result_list[2];
options.editable = ((result_list[3] == "1") ? true : options.editable);
return gadget.jio_get(options.jio_key);
})
.push(function (result) {
jio_document = result;
if (jio_document.portal_type === undefined) {
throw new Error('Can not display document: ' + options.jio_key);
}
}, function (error) {
// instaceof error is Object, so use status_code and undefined jio_key
if (error.status_code === 400 && !options.jio_key) {
return gadget.getSetting('parent_portal_type');
}
throw error;
})
.push(function (parent_portal_type) {
if (jio_document) {
portal_type = jio_document.portal_type;
} else if (options.portal_type) {
portal_type = options.portal_type;
} else {
portal_type = parent_portal_type;
}
front_page = portal_type === parent_portal_type;
return gadget_utils.getFormDefinition(portal_type, app_view);
})
.push(function (result) {
return result;
}, function (error) {
if (error.status_code === 400) {
return gadget_utils.getFormDefinition(portal_type, default_view);
}
throw error;
})
.push(function (result) {
form_definition = result;
return gadget_utils.getFormInfo(form_definition);
})
.push(function (form_info) {
var form_type = form_info[0],
child_gadget_url = form_info[1];
return gadget.changeState({
jio_key: options.jio_key,
doc: jio_document,
portal_type: portal_type,
child_gadget_url: child_gadget_url,
form_definition: form_definition,
form_type: form_type,
editable: options.editable,
view: options.view || default_view,
front_page: front_page
});
});
})
.onStateChange(function () {
var fragment = document.createElement('div'),
gadget = this;
while (this.element.firstChild) {
this.element.removeChild(this.element.firstChild);
}
this.element.appendChild(fragment);
return gadget.declareGadget("gadget_officejs_form_view.html", {element: fragment,
scope: 'form_view'})
.push(function (form_view_gadget) {
return form_view_gadget.render(gadget.state);
});
})
.allowPublicAcquisition('notifySubmit', function () {
return this.triggerSubmit();
})
.allowPublicAcquisition('submitContent', function (param_list) {
var gadget = this,
//target_url = options[1],
content_dict = param_list[2];
return gadget.jio_get(gadget.state.jio_key)
.push(function (doc) {
var property;
for (property in content_dict) {
if (content_dict.hasOwnProperty(property)) {
doc[property] = content_dict[property];
}
}
return gadget.jio_put(gadget.state.jio_key, doc);
})
.push(function () {
return gadget.notifySubmitting();
})
.push(function () {
return gadget.notifySubmitted({message: 'Data Updated', status: 'success'});
});
})
.declareMethod("triggerSubmit", function () {
var argument_list = arguments;
return this.getDeclaredGadget('form_view')
.push(function (view_gadget) {
return view_gadget.triggerSubmit(argument_list);
});
});
}(document, window, rJS, RSVP));
\ No newline at end of file
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Form View</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_officejs_form_view.js"></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Local Jio Gadget</title>
<!-- renderjs -->
<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="jio_ojs_storage.js" type="text/javascript"></script>
<script src="jio_appcachestorage.js"></script>
<!-- custom script -->
<script src="gadget_ojs_local_jio.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<!--
data-i18n=Workflows
data-i18n=Actions
data-i18n=Clone
data-i18n=Delete
-->
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Officejs Page Action</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="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_action_officejs.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>
</html>
\ No newline at end of file
/*global window, rJS, RSVP, Handlebars */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars) {
"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, title, icon, erp5_link_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": erp5_link_list[index].href
};
})
})
);
}
gadget_klass
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getSetting", "getSetting")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("getHTMLElementList", function (element_list) {
var gadget = this,
i = 0,
element_info_list = [],
url_for_parameter_list = [],
element_info,
key;
for (key in element_list) {
if (element_list.hasOwnProperty(key)) {
element_info = element_list[key];
url_for_parameter_list.push({ command: 'change', options: element_info });
element_info_list[i] = { reference: element_info.reference, title: element_info.title};
i += 1;
}
}
return gadget.getUrlForList(url_for_parameter_list)
.push(function (url_list) {
var html_element_list = [], j, element;
for (j = 0; j < url_list.length; j += 1) {
element = { href: url_list[j],
icon: null,
name: element_info_list[j].reference,
title: element_info_list[j].title };
html_element_list.push(element);
}
return html_element_list;
});
})
.declareMethod("render", function (options) {
var gadget = this,
portal_type,
document_title;
return gadget.jio_get(options.jio_key)
.push(function (document) {
document_title = document.title;
return document.portal_type;
}, function () {
document_title = options.portal_type;
return options.portal_type;
})
.push(function (result) {
portal_type = result;
return gadget.declareGadget("gadget_officejs_common_utils.html");
})
.push(function (gadget_utils) {
// TODO views are also listed here
// should views be handled in another gadget like "..tab_office.js" ?
return gadget_utils.getAllViewsAndActions(portal_type, options.jio_key);
})
.push(function (action_info_dict) {
return RSVP.all([
gadget.getHTMLElementList(action_info_dict.views),
gadget.getHTMLElementList(action_info_dict.actions)
]);
})
// check other lists like clone or delete? NO. For now, they will be actions
.push(function (all_html_elements) {
return RSVP.all([
renderLinkList(gadget, "Views", "eye", all_html_elements[0]),
renderLinkList(gadget, "Actions", "gear", all_html_elements[1])
]);
})
.push(function (translated_html_link_list) {
gadget.element.innerHTML = translated_html_link_list.join("\n");
return gadget.getUrlFor({command: 'change', options: {page: undefined}});
})
.push(function (back_url) {
return gadget.updateHeader({
page_title: document_title,
back_url: back_url
});
});
})
.declareMethod("triggerSubmit", function () {
return;
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<!--
data-i18n=Workflows
data-i18n=Actions
data-i18n=Clone
data-i18n=Delete
-->
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Officejs Page Action</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="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_create_document.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>
</html>
\ No newline at end of file
/*global window, document, rJS */
/*jslint nomen: true, indent: 2, maxerr: 13 */
(function (window, document, rJS) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_post", "jio_post")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("createDocument", function (portal_type, parent_portal_type) {
var gadget = this,
doc = {
title: "Untitled Document",
portal_type: portal_type,
parent_relative_url: parent_portal_type
};
return gadget.jio_post(doc)
.push(function (id) {
return gadget.redirect({
command: 'display',
options: {
jio_key: id,
editable: true
}
});
});
})
.declareMethod("render", function (options) {
var gadget = this,
allowed_sub_types_list = options.allowed_sub_types_list.split(","),
parent_portal_type = options.portal_type,
portal_type,
form_definition,
document_title;
return gadget.jio_get(options.jio_key)
.push(function (document) {
document_title = document.title;
return document.portal_type;
}, function () {
document_title = options.portal_type;
return options.portal_type;
})
.push(function (portal_type_result) {
portal_type = portal_type_result;
// TODO: somehow (a generic action?) get the path string:${object_url}/Base_viewNewContentDialog
return gadget.jio_get("portal_skins/erp5_hal_json_style/Base_viewNewContentDialog");
})
.push(function (form_result) {
form_definition = form_result.raw_dict._embedded._view._embedded.form_definition;
form_definition.fields_raw_properties = form_result.raw_dict._embedded._view.my_fields_raw_properties["default"];
form_definition._actions = form_result.raw_dict._embedded._view._actions;
form_definition.group_list = form_result.raw_dict.group_list;
form_definition.title = "Create Document";
return gadget.changeState({
doc: { title: document_title, portal_type: allowed_sub_types_list },
parent_portal_type: parent_portal_type,
action_options: options,
child_gadget_url: 'gadget_erp5_pt_form_dialog.html',
form_type: 'dialog',
form_definition: form_definition,
view: "view",
show_dialog: allowed_sub_types_list.length > 1
});
});
})
.onStateChange(function () {
var fragment = document.createElement('div'),
gadget = this;
if (gadget.state.show_dialog) {
while (this.element.firstChild) {
this.element.removeChild(this.element.firstChild);
}
this.element.appendChild(fragment);
return gadget.declareGadget("gadget_officejs_form_view.html", {element: fragment,
scope: 'fg'})
.push(function (form_view_gadget) {
return form_view_gadget.render(gadget.state);
});
} else {
// if there is only one sub portal type, skip create document dialog rendering
return gadget.createDocument(gadget.state.doc.portal_type[0],
gadget.state.parent_portal_type.replace(/ /g, '_').toLowerCase());
}
})
.allowPublicAcquisition('submitContent', function (options) {
var gadget = this,
content_dict = options[2];
return gadget.createDocument(content_dict.portal_type,
gadget.state.parent_portal_type.replace(/ /g, '_').toLowerCase());
});
}(window, document, rJS));
\ No newline at end of file
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Handle Action</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_erp5_page_handle_action.js"></script>
</head>
<body>
</body>
</html>
/*global window, document, rJS, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, document, rJS, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("redirect", "redirect")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("getActionFormDefinition", function (action_reference) {
var gadget = this, parent_portal_type;
return RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getUrlParameter("parent_portal_type"),
gadget.declareGadget("gadget_officejs_common_utils.html")
]);
})
.push(function (result) {
parent_portal_type = result[0];
return result[1].getFormDefinition(parent_portal_type, action_reference);
});
})
.declareMethod("render", function (options) {
var gadget = this, action_reference, gadget_utils, form_definition;
return RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getUrlParameter('portal_type'),
gadget.getUrlParameter('parent_relative_url'),
gadget.getUrlParameter("action"),
gadget.declareGadget("gadget_officejs_common_utils.html")
]);
})
.push(function (result) {
if (result[0] !== undefined) { options.portal_type = result[0]; }
if (result[1] !== undefined) { options.parent_relative_url = result[1]; }
action_reference = result[2];
gadget_utils = result[3];
return gadget.getActionFormDefinition(action_reference);
})
.push(function (result) {
form_definition = result;
return gadget_utils.getFormInfo(form_definition);
})
.push(function (form_info) {
var fragment = document.createElement('div'),
action_gadget_url,
form_type = form_info[0],
child_gadget_url = form_info[1],
//an action form must have a GadgetField called "gadget_field_new_action_js_script"
//this gadget will point the custom action gadget
valid_action = form_definition.action_type === "object_jio_js_script" &&
form_definition.fields_raw_properties.hasOwnProperty("gadget_field_action_js_script"),
state_options = {
doc: {},
action_options: options,
child_gadget_url: child_gadget_url,
form_type: form_type,
form_definition: form_definition,
view: action_reference,
valid_action: valid_action
};
if (valid_action) {
action_gadget_url = form_definition.fields_raw_properties.gadget_field_action_js_script.values.gadget_url;
// as custom gadget render is being done here, avoid to child gadget to render it
delete form_definition.fields_raw_properties.gadget_field_action_js_script;
gadget.element.appendChild(fragment);
return gadget.declareGadget(action_gadget_url, {
scope: "action_field",
element: fragment
})
.push(function (action_gadget) {
return action_gadget.preRenderDocument(options);
})
.push(function (doc) {
state_options.doc = doc;
state_options.action_gadget_url = action_gadget_url;
return gadget.changeState(state_options);
});
} else {
return gadget.changeState(state_options);
}
});
})
.onStateChange(function () {
var fragment = document.createElement('div'),
gadget = this;
while (this.element.firstChild) {
this.element.removeChild(this.element.firstChild);
}
this.element.appendChild(fragment);
return gadget.declareGadget("gadget_officejs_form_view.html", {element: fragment,
scope: 'fg'})
.push(function (form_view_gadget) {
return form_view_gadget.render(gadget.state);
});
})
.declareMethod('triggerSubmit', function () {
return this.getDeclaredGadget('fg')
.push(function (gadget) {
return gadget.triggerSubmit();
});
})
.allowPublicAcquisition('submitContent', function (options) {
var gadget = this,
//target_url = options[1],
content_dict = options[2],
fragment = document.createElement('div'),
jio_key;
if (gadget.state.valid_action) {
gadget.element.appendChild(fragment);
return gadget.declareGadget(gadget.state.action_gadget_url, {
scope: "action_field",
element: fragment
})
.push(function (action_gadget) {
return action_gadget.handleSubmit(content_dict, gadget.state);
})
.push(function (id) {
jio_key = id;
return gadget.notifySubmitting();
})
.push(function () {
return gadget.notifySubmitted({message: 'Data Updated', status: 'success'});
})
.push(function () {
return gadget.redirect({
command: 'display',
options: {
jio_key: jio_key,
editable: gadget.state.view === "edit"
}
});
});
} else {
return gadget.notifySubmitted({message: 'Could not perform this action: configuration error', status: 'fail'});
}
});
}(window, document, rJS, RSVP));
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>ERP5 Local Controller</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="jio_appcachestorage.js"></script>
<!-- custom script -->
<script src="gadget_erp5_page_ojs_local_controller.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
......@@ -40,4 +40,5 @@ web_site_module/officejs_todomvc
web_site_module/officejs_wallsearch
web_site_module/officejs_wallsearch/**
web_site_module/officejs_whiteboard
web_site_module/officejs_media_player/**
\ No newline at end of file
web_site_module/officejs_media_player/**
web_site_module/hateoas_appcache
\ No newline at end of file
......@@ -40,4 +40,5 @@ web_site_module/officejs_todomvc
web_site_module/officejs_wallsearch
web_site_module/officejs_wallsearch/**
web_site_module/officejs_whiteboard
web_site_module/officejs_media_player/**
\ No newline at end of file
web_site_module/officejs_media_player/**
web_site_module/hateoas_appcache
\ No newline at end of file
......@@ -5,6 +5,10 @@ image_module/hr_logo_svg
image_module/officejs_audioplayer_*
image_module/officejs_todomvc_*
image_module/wallsearch_icon_svg
portal_types/Web Page Module/text_editor_view
portal_types/Web Page/jio_view
portal_types/Web Page/text_editor_clone
portal_types/Web Page/text_editor_view
web_page_module/dhtmlx_gantt_*
web_page_module/fb_sdk_js
web_page_module/gadget_field_*
......@@ -14,6 +18,7 @@ web_page_module/officejs_audioplayer_*
web_page_module/officejs_todomvc_*
web_page_module/ojs_*
web_page_module/wallsearch_privacy_policy_html
web_site_module/hateoas_appcache
web_site_module/officejs_audioplayer
web_site_module/officejs_audioplayer/**
web_site_module/officejs_bookmark_manager
......
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