Commit 9687dbbf authored by Roque's avatar Roque

-rebase more than 50 commits-

erp5_discussion: initial commits for discussion tool (WIP)

erp5_officejs: web site and gadgets for discussion tool

erp5_officejs_connector: forms for discussion tool

erp5_post: html post jio view for discussion tool

erp5_officejs_ui_test: unit tests for discussion tool

[HARDCODED] only discussion tool tests

erp5_discussion: adding officejs dependency to install the discussion tool site

testing a fix for migration test in discussion tool

erp5_hal_json_style: hateoas script extended to retrieve raw form definition

erp5_officejs: rendering form on JS side
- hardcoded JSON was removed
- form definition is get from jio storage (erp5 for now)
- rendering is done in controller.js using form definition and context (jio document)

erp5_officejs_connector: changes on HTML post view as jio for discussion tool

erp5_post: changes on html post view for discussion tool

erp5_officejs: store json form definition in indexedDB

erp5_officejs: adding a layer in jio data storage to replicate appcache content

erp5_officejs: bug fix - missing resource in appcache file

WIP: erp5_officejs: replicate appcache content into local storage

erp5_officejs: new file manifest to list form json urls and other configurations
- this prevents the appcache-local storage sync to store unnecessary resources like gadgets

erp5_officejs: replicate appcache content into local storage
- configurations like form definitions are saved as objects into data-storage.metadata to allow jio.get

erp5_officejs: minor fixes and cleanup

erp5_officejs: include non-json resources from appcache as blobs

WIP erp5_officejs: getting rid of editable view for form rendering

erp5_officejs: got rid of editable view form and using gadget_erp5_form directly

erp5_officejs: removing unnecessary redirect

erp5_officejs_ui_test: updating test

erp5_officejs: fix in appcachestorage sync

[HARCODED]  erp5_hal_json_style: remove permission controls to appcache hatoas return-dict

erp5_officejs: removing comments in appcache manifest

erp5_officejs: revert get rid of editable view
- editable view is generic enough for form editing, so it will be kept
- but submit handling is done in controller gadget

erp5_officejs: cleanup in controller html

erp5_officejs: bug fixing on storage migration
- new appcachestorage hash layer is created when new storage is selected

erp5_hal_json_style: missing jio_view action in ERP5 Form portal type
- needed to get the form definition from hateoas script

erp5_officejs: new parameter appcache in hateoas script
- this new parameter disable permission check when hateoas is called by bootloader
- appcache storage sync is canceled if storage requires authentication
- WIP: redirect to login not working

erp5_officejs: extra controls in appcachestorage sync error handling

erp5_officejs: logging more error details for failing unit test

erp5_officejs: more error logging for tests
- attempt to fix test

erp5_officejs: more details in log for test

erp5_officejs: adding configuration manifest explicitly
- even is it committed, test fails due to "can't get manifest"

erp5_officejs: using old appcache manifest instead of the configuration one

erp5_officejs: no need of explicitly commit the configuration manifest or use old manifest
- the test failed the same with both attempts

erp5_officejs_ui_test: add a check for manifest configuration file

erp5_officejs_ui_test: fix in configuration manifest url

erp5_officejs: attempt to fix unit test appcache sync

erp5_officejs_ui_test: cleanup

erp5_officejs: clean up after test fix

erp5_hal_json_style: fix permission issue for appcache storage sync
- new parameter added for this scenario

[HARDCODED] erp5_hal_json_style: forcing value of html post action jio_view

erp5_hal_json_style: error handling in hardcoded action value

[WIP] erp5_officejs: get rid of hardcoded form name in controller gadget
- form name comes from the document portal type action
- for now, path to action is hardcoded. It will come from a allDocs query (not implemented yet in appcachestorage sync)

erp5_hal_json_style: fix test due to hardcode

erp5_officejs: jio_allDocs queries can be done on local data storage after appcachestorage sync

erp5_officejs: missing hateoas urls in appcache and configuration manifests

Removing unnecessary modified files from merge request

erp5_officejs: minor refactoring

erp5_officejs: code cleanup
parent 16b10406
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>new_thread</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Add portal content</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>New Thread</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DiscussionThreadModule_viewAddThreadDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>reply</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Add portal content</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Reply</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DiscussionThread_viewAddReplyDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
discussion_thread = context.getPortalObject().discussion_thread_module.newContent(
title = thread_title,
portal_type = "Discussion Thread"
)
discussion_thread.setReference(discussion_thread.getId())
discussion_thread.DiscussionThread_createPost(thread_title, text_content)
portal_status_message = "New thread created"
discussion_thread.Base_redirect("view", keep_items = dict(portal_status_message = portal_status_message))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>thread_title, text_content, form_id, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThreadModule_addThread</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>DiscussionThreadModule_addThread</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>my_text_content</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_thread_title</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThreadModule_viewAddThreadDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>DiscussionThreadModule_viewAddThreadDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>New Thread</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewWebFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Text</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_doSelect</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThreadModule_viewDiscussionThreadList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>DiscussionThreadModule_viewDiscussionThreadList</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_list</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Discussion Threads</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>portal_type</string>
<string>selection_name</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Discussion Thread</string>
<string>Discussion Thread</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>discussion_thread_module_selection</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Discussion Threads</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
assert context.getPortalType() == "Discussion Thread"
title = "Re: " + context.getTitle()
context.DiscussionThread_createPost(title, text_content)
portal_status_message = "New post created"
context.Base_redirect("view", keep_items = dict(portal_status_message = portal_status_message))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>text_content, form_id, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThread_addReply</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
post = context.PostModule_createHTMLPost(
title = title,
source_reference = context.getReference(),
data = text_content,
follow_up = context.getRelativeUrl(),
predecessor = None
)
attached_file = None
web_site_relative_url = None
if attached_file not in ("undefined", None):
pass # TODO attached file
else:
post.publish()
after_ingest_document_tag = 'after-ingest-%s' % post.getId()
post.activate(
after_tag=after_ingest_document_tag
).Post_ingestAndCreateEvent(
web_site_relative_url=web_site_relative_url)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>title, text_content</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThread_createPost</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -72,6 +72,7 @@
<value>
<list>
<string>listbox</string>
<string>my_listbox</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>gadget_url</string>
<string>renderjs_extra</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>height</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string>Content of the web page</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewWebFieldLibrary</string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>40</int> </value>
</item>
<item>
<key> <string>renderjs_extra</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Post List</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: field.restrictedTraverse(\'gadget_postlist.html\').absolute_url()</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [ ( \'query\', context.getPortalObject().portal_catalog.getSQLCatalog().buildQuery({"portal_type":[\'Web Message\'], "source_reference":context.getId()}).asSearchTextExpression(context.getPortalObject().portal_catalog.getSQLCatalog()) ), (\'view\', "view"), (\'jio_key\', context.getRelativeUrl()), (\'portal_type\', context.getPortalType()), (\'maximize\', \'listbox\' not in field.id)]</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>DiscussionThread_addReply</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>my_text_content</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThread_viewAddReplyDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>DiscussionThread_viewAddReplyDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Reply</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -9,12 +9,15 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>default</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_translated_validation_state_title</string> </value>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -39,10 +42,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -58,10 +57,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -69,17 +64,21 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_translated_simulation_state_title</string> </value>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewCRMFieldLibrary</string> </value>
<value> <string>Base_viewWebFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>title</string> </key>
<value> <string>Content</string> </value>
</item>
</dictionary>
</value>
......
from Products.ERP5Type.Message import translateString
portal = context.getPortalObject()
messenger_thread = context.getFollowUpValue()
web_site_value = portal.restrictedTraverse(web_site_relative_url) if web_site_relative_url else None
data = str(context.getData())
is_html = context.getPortalType() == 'HTML Post'
if is_html: # sanitize HTML
data = portal.portal_transforms.convertToData(
'text/x-html-safe',
data,
context=context,
mimetype=context.getContentType())
# TODO: check resource, in support_request seems to be important
resource = None
source_value = context.ERP5Site_getAuthenticatedMemberPersonValue()
web_message = portal.event_module.newContent(
portal_type = 'Web Message',
title = context.getTitle(),
content_type = 'text/html' if is_html else 'text/plain',
text_content = data,
follow_up_value = messenger_thread,
aggregate_value_list = [context] + context.getSuccessorValueList(
portal_type = portal.getPortalDocumentTypeList()),
resource = resource,
source_value = source_value,
start_date = context.getCreationDate(),
source_reference = context.getSourceReference())
web_message.stop()
context.archive(
comment=translateString('Ingested as ${web_message_reference}',
mapping={'web_message_reference': web_message.getReference()}))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>web_site_relative_url=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Post_ingestAndCreateEvent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Post list gadget</title>
<link rel="http://www.renderjs.org/rel/interface" href="interface_editor.html">
<link rel="http://www.renderjs.org/rel/interface" href="interface_erp5_form_content_provider.html">
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_postlist.js"></script>
<!-- templates -->
<script id="template-document-list" type="text/x-handlebars-template">
{{#if comments }}
{{#each comments }}
<li>By <strong>{{#if user }}
{{ user }}
{{else }}
Manager
{{/if }}
</strong> -
<time datetime="{{ date }}" title="{{ date_formatted }}">{{ date_relative }}</time>
<br/>
{{{ value.text_content }}}
{{#if attachment_link }}
<br/>
<strong>Attachment: </strong>
<a href="{{attachment_link}}">{{ attachment_name }}</a>
{{/if}}
<hr id="post_item">
</li>
{{/each }}
{{else }}
<p><em>No posts yet.</em></p><hr id="post_item">
{{/if }}
</script>
</head>
<body>
<div class="ui-body-c">
<form>
<p style="background-color:#0E81C2;color:white;margin:1em 0;padding:0.5em">Comments:</p>
<ol id="post_list"></ol>
</form>
</div>
</body>
</html>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>gadget_postlist.html</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*jslint nomen: true, indent: 2 */
/*global window, rJS, RSVP, document, moment, jIO, Handlebars, console*/
(function (window, rJS, RSVP, document, moment, jIO, Handlebars, console) {
"use strict";
var gadget_klass = rJS(window),
comment_list_template = Handlebars.compile(
gadget_klass.__template_element.getElementById("template-document-list").innerHTML
);
rJS(window)
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareMethod('render', function (options) {
var gadget = this;
gadget.options = options;
return gadget.getSetting('hateoas_url')
.push(function (hateoas_url) {
gadget.hateoas_url = hateoas_url;
})
.push(function () {
var state_dict = {
id: options.jio_key,
view: options.view,
editable: options.editable,
query: options.query,
erp5_form: options.erp5_form || {}
};
return gadget.changeState(state_dict);
});
})
.onStateChange(function () {
var gadget = this;
return gadget.jio_allDocs({
"query": gadget.state.query,
"select_list": ["text_content", "modification_date", "source_title"],
"sort_on": [["modification_date", "ascending"]]
})
.push(function (results) {
var post_list = results.data.rows;
function getPostWithLinkAndLocalDate(post) {
post.date = post.value.modification_date;
post.date_formatted = moment(post.date).format('LLLL');
post.date_relative = moment(post.date).fromNow();
if (post.attachment_link === null) {
return post;
}
if (post.attachment_link.indexOf("image_module") !== -1) {
return gadget.getImageUrl(post.attachment_link).push(
function (attachment_link) {
post.attachment_link = attachment_link;
return post;
}
);
}
return gadget.getDocumentUrl(post.attachment_link).push(
function (attachment_link) {
post.attachment_link = attachment_link;
return post;
}
);
}
var queue_list = [], i = 0;
for (i = 0; i < post_list.length; i += 1) {
post_list[i].user = post_list[i].value.source_title;
// TODO: attachments
post_list[i].attachment_link = null;
post_list[i].attachment_name = null;
queue_list.push(getPostWithLinkAndLocalDate(post_list[i]));
}
return RSVP.all(queue_list);
})
.push(function (comment_list) {
console.log("comment_list results:");
console.log(comment_list);
var comments = gadget.element.querySelector("#post_list");
comments.innerHTML = comment_list_template({comments: comment_list});
});
})
.onLoop(function () {
// update relative time
var elements = this.element.querySelectorAll("li>time");
[].forEach.call(elements, function (element) {
element.textContent = moment(element.getAttribute('datetime')).fromNow();
});
}, 5000)
/*.onEvent('submit', function () {
return this.submitPostComment();
})*/;
}(window, rJS, RSVP, document, moment, jIO, Handlebars, console));
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>gadget_postlist.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
2019-02-14 Ivan
* first changes for new discussion tool and refactoring in officejs for form rendering
2010-03-18 Ivan
* use default DMS publication workflow
......
......@@ -2,4 +2,7 @@ erp5_base
erp5_rss_style
erp5_knowledge_pad
erp5_jquery
erp5_dms
\ No newline at end of file
erp5_dms
erp5_post
erp5_officejs
erp5_officejs_connector
\ No newline at end of file
This business template provides discussions for any ERP5 document.
\ No newline at end of file
This business template provides discussions for any ERP5 document. It will gradually become a messenger platform for discussion and communication on ERP5
\ No newline at end of file
......@@ -2,8 +2,10 @@ Discussion Post | view
Discussion Post | view_edit
Discussion Post | web_view
Discussion Thread Module | newThread
Discussion Thread Module | new_thread
Discussion Thread Module | view
Discussion Thread | add_discussion_post
Discussion Thread | reply
Discussion Thread | view
Discussion Thread | web_view
Preference | forum_style_preferences
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_jio_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jio_view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ERP5Form_viewAsJio</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -47,6 +47,7 @@ When handling form, we can expect field values to be stored in REQUEST.form in t
- python-object parsed from raw values under <field.id>
"""
from ZTUtils import make_query
import json
from base64 import urlsafe_b64encode, urlsafe_b64decode
......@@ -66,13 +67,14 @@ from collections import OrderedDict
MARKER = []
COUNT_LIMIT = 1000
appcache = True if context.REQUEST.get('appcache', None) is not None else False
if REQUEST is None:
REQUEST = context.REQUEST
if response is None:
response = REQUEST.RESPONSE
def isFieldType(field, type_name):
if field.meta_type == 'ProxyField':
field = field.getRecursiveTemplateField()
......@@ -389,6 +391,30 @@ def getFieldDefault(form, field, key, value=None):
return "%s" % value
return value
def getFieldRawProperties(field, meta_type=None, key=None, key_prefix=None):
""" Return the raw properties of the field """
if meta_type is None:
meta_type = field.meta_type
if key is None:
key = field.generate_field_key(key_prefix=key_prefix)
if meta_type == "ProxyField":
meta_type = field.getRecursiveTemplateField().meta_type
result = {
"type": meta_type,
"key": key,
"values": {},
"tales": {},
"overrides": field.overrides,
"message_values": field.message_values
}
for key in field.values.keys():
# sometimes, field.values returns a key as string and also as a tuple
if type(key) is str:
result["values"][key] = field.values[key]
for key in field.tales.keys():
if field.tales[key]:
result["tales"][key] = str(field.tales[key])
return result
def renderField(traversed_document, field, form, value=MARKER, meta_type=None, key=None, key_prefix=None, selection_params=None, request_field=True):
"""Extract important field's attributes into `result` dictionary."""
......@@ -830,7 +856,7 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
action_to_call = "Base_callDialogMethod"
else:
action_to_call = form.action
if (action_to_call == 'Base_edit') and (not portal.portal_membership.checkPermission('Modify portal content', traversed_document)):
if (not appcache) and (action_to_call == 'Base_edit') and (not portal.portal_membership.checkPermission('Modify portal content', traversed_document)):
# prevent allowing editing if user doesn't have permission
include_action = False
......@@ -893,7 +919,6 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
view='view'
)
}
use_relation_form_page_template = (form.pt == "relation_form")
if use_relation_form_page_template:
# Provide the list of possible listboxes
......@@ -1132,7 +1157,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
query=None, select_list=None, limit=None, form=None,
relative_url=None, restricted=None, list_method=None,
default_param_json=None, form_relative_url=None, extra_param_json=None):
if relative_url:
try:
traversed_document = site_root.restrictedTraverse(str(relative_url))
......@@ -1188,7 +1212,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
'status': statusLevelToString(portal_status_level)
}
if (restricted == 1) and (portal.portal_membership.isAnonymousUser()):
if (not appcache) and (restricted == 1) and (portal.portal_membership.isAnonymousUser()):
login_relative_url = site_root.getLayoutProperty("configuration_login", default="")
if (login_relative_url):
response.setHeader(
......@@ -1233,6 +1257,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
for k, v in byteify(extra_param_json.items()):
REQUEST.set(k, v)
# Add a link to the portal type if possible
if not is_portal:
# traversed_document should always have its Portal Type in ERP5 Portal Types
......@@ -1408,7 +1433,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# XXX Custom slapos code
##############
if is_site_root:
result_dict['default_view'] = 'view'
REQUEST.set("X-HATEOAS-CACHE", 1)
......@@ -1452,19 +1477,19 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
'method': 'POST',
'name': 'Bulk'
}
# Handle also other kind of users: instance, computer, master
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
if person is not None and portal.portal_membership.checkPermission('View', person):
result_dict['_links']['me'] = {
"href": default_document_uri_template % {
"root_url": site_root.absolute_url(),
"relative_url": person.getRelativeUrl(),
"relative_url": person.getRelativeUrl(),
"script_id": script.id
},
# '_relative_url': person.getRelativeUrl()
#'_relative_url': person.getRelativeUrl()
}
else:
traversed_document_portal_type = traversed_document.getPortalType()
if traversed_document_portal_type in ("ERP5 Form", "ERP5 Report"):
......@@ -1474,6 +1499,18 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
response.setHeader("Vary", "Cookie,Authorization,Accept-Encoding")
response.setHeader("Last-Modified", DateTime().rfc822())
REQUEST.set("X-HATEOAS-CACHE", 1)
fields_raw_properties = {}
# check if it's the first call to calculateHateoas so nothing was rendered yet
if REQUEST != None and response != None:
for group in traversed_document.Form_getGroupTitleAndId():
if 'hidden' in group['gid']:
continue
for field in traversed_document.get_fields_in_group(group['goid']):
fields_raw_properties[field.id] = getFieldRawProperties(field, key_prefix=None)
if fields_raw_properties:
result_dict['fields_raw_properties'] = fields_raw_properties
elif relative_url == 'portal_workflow':
result_dict['_links']['action_worklist'] = {
"href": url_template_dict['worklist_template'] % {
......@@ -2071,9 +2108,20 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
else:
raise NotImplementedError("Unsupported mode %s" % mode)
return result_dict
# if form has my_form_definition field, set it with fields_raw_properties and form_definition
# my_form_definition will be used for rendering in JS side
if "_embedded" in result_dict:
if "_view" in result_dict["_embedded"]:
if "my_form_definition" in result_dict["_embedded"]["_view"]:
default_form_definition = result_dict["_embedded"]["_view"]["_embedded"]["form_definition"].copy()
default_form_definition["group_list"] = result_dict["group_list"]
default_form_definition["_actions"] = result_dict["_embedded"]["_view"]["_actions"]
if result_dict["fields_raw_properties"]:
default_form_definition["fields_raw_properties"] = result_dict["fields_raw_properties"].copy()
result_dict.pop('fields_raw_properties', None)
result_dict["_embedded"]["_view"]["my_form_definition"]["default"] = default_form_definition
return result_dict
mime_type = 'application/hal+json'
portal = context.getPortalObject()
......@@ -2091,6 +2139,7 @@ else:
context.Base_prepareCorsResponse(RESPONSE=response)
# Check if traversed_document is the site_root
if relative_url:
temp_traversed_document = site_root.restrictedTraverse(relative_url, None)
......@@ -2104,6 +2153,7 @@ temp_is_site_root = (temp_traversed_document.getPath() == site_root.getPath())
temp_is_portal = (temp_traversed_document.getPath() == portal.getPath())
response.setHeader('Content-Type', mime_type)
hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_root,
traversed_document=temp_traversed_document,
relative_url=relative_url,
......@@ -2113,6 +2163,13 @@ hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_r
default_param_json=default_param_json,
form_relative_url=form_relative_url,
extra_param_json=extra_param_json)
# [HARDCODED] expresion string:${object_url} must be evaluated before return
try:
if "_embedded" in hateoas.keys() and "_view" in hateoas["_embedded"].keys() and "my_action" in hateoas["_embedded"]["_view"].keys():
if hateoas["_embedded"]["_view"]["my_action"]["default"] == 'string:${object_url}/HTMLPost_viewAsJio' or hateoas["_embedded"]["_view"]["my_action"]["default"] == 'string:${object_url}/HTMLPost_view':
hateoas["_embedded"]["_view"]["my_action"]["default"] = 'portal_skins/erp5_officejs_jio_connector/HTMLPost_viewAsJio'
except:
pass
if hateoas == "":
return hateoas
else:
......
ERP5 Form | jio_view
portal_actions | clone_document
portal_actions | create_a_document
portal_actions | delete_document
portal_actions | delete_document_list
portal_actions | mass_workflow_jio
portal_actions | mass_workflow_jio
\ No newline at end of file
......@@ -5,7 +5,7 @@ var repair = false;
"use strict";
function createStorage(gadget) {
return jIO.createJIO({
var jio_options = {
type: "replicate",
parallel_operation_attachment_amount: 10,
parallel_operation_amount: 1,
......@@ -41,7 +41,8 @@ var repair = false;
version: gadget.props.version_url,
take_installer: true
}
});
};
return jIO.createJIO(jio_options);
}
function waitForServiceWorkerActive(registration) {
......
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>967.24634.17714.15001</string> </value>
<value> <string>974.21860.23292.10171</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1543506463.01</float>
<float>1552651381.39</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -225,7 +225,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>967.6016.61211.59613</string> </value>
<value> <string>974.39977.38000.44305</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -243,7 +243,7 @@
</tuple>
<state>
<tuple>
<float>1524754712.51</float>
<float>1553613284.01</float>
<string>UTC</string>
</tuple>
</state>
......
{
"short_name": "Discussion Tool",
"name": "OfficeJS Discussion Tool",
"description": "App to support communication",
"icons": [{
"src": "officejs_logo_text_editor.png",
"sizes": "128x128",
"type": "image/png"
}],
"start_url": "../../",
"display": "standalone"
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<title>OfficeJS Router Gadget</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_officejs_router.js" type="text/javascript"></script>
</head>
<body>
<script data-renderjs-configuration="portal_type" type="text/x-renderjs-configuration">HTML Post</script>
<script data-renderjs-configuration="document_title" type="text/x-renderjs-configuration">Discussion Post</script>
<script data-renderjs-configuration="document_title_plural" type="text/x-renderjs-configuration">Discussion Posts</script>
<script data-renderjs-configuration="parent_relative_url" type="text/x-renderjs-configuration">post_module</script>
<script data-renderjs-configuration="erp5_attachment_synchro" type="text/x-renderjs-configuration"></script>
<script data-renderjs-configuration="dropbox_app_key" type="text/x-renderjs-configuration">n692ixxhyg9zhqs</script>
<div data-gadget-url="gadget_erp5_router.html" data-gadget-scope="erp5_router"></div>
</body>
</html>
\ 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 Add Post Document</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_erp5_page_ojs_add_post.js"></script>
</head>
<body>
</body>
</html>
/*global window, rJS, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Blob) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_post", "jio_post")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function () {
var gadget = this, doc_id;
return RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getSetting('portal_type'),
gadget.getSetting('parent_relative_url')
]);
})
.push(function (result) {
var doc = {
title: "Untitled Document",
portal_type: result[0],
parent_relative_url: result[1]
};
return gadget.jio_post(doc);
})
.push(function (id) {
return gadget.redirect({
command: 'display',
options: {
jio_key: id,
editable: true
}
});
});
});
}(window, rJS, RSVP, Blob));
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Posts List</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_erp5_page_ojs_post_list.js"></script>
</head>
<body>
<div data-gadget-url="gadget_erp5_pt_form_list.html" data-gadget-scope="form_list"></div>
</body>
</html>
/*global window, rJS, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("getSetting", "getSetting")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("generateJsonRenderForm", function (gadget) {
//hardcoded form_definition (this should come from erp5 form)
var form_definition = {
_debug: "traverse",
pt: "form_view",
title: "Post",
group_list: [[
"bottom",
[["my_listbox"]]
]],
//this field_info is totally made up, but somewhere in the definition there must be
//information about the fields. So, foreach field: key->info
field_info_dict: {
"my_listbox": {
"column_list": [['title', 'Title'], ['modification_date', 'Modification Date']],
"show_anchor": 0,
"default_params": {},
"editable": 1,
"editable_column_list": [],
"key": "field_listbox",
"lines": 30,
"list_method": "portal_catalog",
// is this correct? the query should come from the form definition, right?
"query": "urn:jio:allDocs?query=portal_type%3A%22HTML Post%22",
"portal_type": [],
"search_column_list": [['title', 'Title'], ['modification_date', 'Modification Date']],
"sort_column_list": [['title', 'Title'], ['modification_date', 'Modification Date']],
"sort": [['modification_date', 'descending']],
"title": "Posts",
"type": "ListBox"
}
},
action: "Base_edit",
update_action: "",
_links: { "type": { name: "" } }
},
form_json = {
erp5_document: {
"_embedded": {"_view": {}},
"_links": {}
},
form_definition: form_definition
};
for (var i = 0; i < form_definition.group_list.length; i++) {
var fields = form_definition.group_list[i][1];
for (var j = 0; j < fields.length; j++) {
var my_element = fields[j][0], element_id;
if (my_element.startsWith("my_")) {
element_id = my_element.replace("my_", "");
}
var field_info = form_definition.field_info_dict[my_element];
if (gadget.state.hasOwnProperty("doc") && gadget.state.doc.hasOwnProperty(element_id)) {
field_info["default"] = gadget.state.doc[element_id];
}
form_json.erp5_document._embedded._view[my_element] = field_info;
form_json.erp5_document._links = form_definition._links;
}
}
return form_json;
})
.allowPublicAcquisition('notifySubmit', function () {
return this.triggerSubmit();
})
.declareMethod("triggerSubmit", function () {
var argument_list = arguments;
return this.getDeclaredGadget('form_list')
.push(function (gadget) {
return gadget.triggerSubmit.apply(gadget, argument_list);
});
})
.declareMethod("render", function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getDeclaredGadget('form_list'),
gadget.generateJsonRenderForm(gadget)
]);
})
.push(function (result) {
return result[0].render(result[1]);
})
.push(function () {
return RSVP.all([
gadget.getUrlFor({command: "change", options: {"page": "ojs_add_post"}}),
gadget.getSetting('document_title_plural'),
gadget.getSetting('upload_dict', false)
]);
})
.push(function (result) {
var header = {
page_title: result[1],
filter_action: true,
add_url: result[0]
};
if (result[3]) {
header.upload_url = result[2];
}
return gadget.updateHeader(header);
});
});
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -87,13 +87,14 @@
};
AppCacheStorage.prototype.repair = function () {
var storage = this;
var storage = this, url = "";
return new RSVP.Queue()
.push(function () {
url = new URL(storage._manifest, new URL(storage._version,
storage._origin_url));
return jIO.util.ajax({
type: "GET",
url: new URL(storage._manifest, new URL(storage._version,
storage._origin_url))
url: url
});
})
.push(function (response) {
......@@ -123,7 +124,7 @@
})
.push(undefined, function (error) {
if (!error.message) {
error.message = "Can't get manifest";
error.message = "Can't get manifest. URL: " + url;
}
throw error;
});
......
......@@ -223,7 +223,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>vincent</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -237,7 +237,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.50005.13436.62685</string> </value>
<value> <string>974.38565.24349.65194</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -255,7 +255,7 @@
</tuple>
<state>
<tuple>
<float>1515753347.5</float>
<float>1553525326.06</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -11,7 +11,7 @@
<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_jio.js" type="text/javascript"></script>
......
......@@ -222,7 +222,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>vincent</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>962.42958.18622.47018</string> </value>
<value> <string>974.23054.45008.28006</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1507552322.86</float>
<float>1552654559.7</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -7,6 +7,7 @@
<!-- 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_controller.js" type="text/javascript"></script>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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