Commit 18696b5a authored by Noah Brackenbury's avatar Noah Brackenbury

Merge branch 'master' of https://lab.nexedi.com/nexedi/erp5 into business_bot

parents 51f2b8c1 2572999b
...@@ -7,6 +7,7 @@ import datetime ...@@ -7,6 +7,7 @@ import datetime
import time import time
from email.Utils import formatdate from email.Utils import formatdate
import re import re
from zExceptions import Unauthorized
if REQUEST is None: if REQUEST is None:
REQUEST = context.REQUEST REQUEST = context.REQUEST
...@@ -209,10 +210,16 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -209,10 +210,16 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
accessor_name = 'get%sValueList' % \ accessor_name = 'get%sValueList' % \
''.join([part.capitalize() for part in base_category.split('_')]) ''.join([part.capitalize() for part in base_category.split('_')])
jump_reference_list = getattr(traversed_document, accessor_name)( try:
portal_type=[x[0] for x in field.get_value('portal_type')], jump_reference_list = getattr(traversed_document, accessor_name)(
filter=kw portal_type=[x[0] for x in field.get_value('portal_type')],
) or [] filter=kw
) or []
except Unauthorized:
jump_reference_list = []
result.update({
"editable": False
})
query = url_template_dict["jio_search_template"] % { query = url_template_dict["jio_search_template"] % {
"query": make_query({"query": sql_catalog.buildQuery( "query": make_query({"query": sql_catalog.buildQuery(
{"portal_type": portal_type_list} {"portal_type": portal_type_list}
...@@ -910,7 +917,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -910,7 +917,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# Handle also other kind of users: instance, computer, master # Handle also other kind of users: instance, computer, master
person = portal.portal_membership.getAuthenticatedMember().getUserValue() person = portal.portal_membership.getAuthenticatedMember().getUserValue()
if person is not None: if person is not None and portal.portal_membership.checkPermission('View', person):
result_dict['_links']['me'] = { result_dict['_links']['me'] = {
"href": default_document_uri_template % { "href": default_document_uri_template % {
"root_url": site_root.absolute_url(), "root_url": site_root.absolute_url(),
...@@ -954,84 +961,52 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -954,84 +961,52 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
elif mode == 'search': elif mode == 'search':
################################################# #################################################
# Portal catalog search # Portal catalog search
#
# Possible call arguments example:
# form_relative_url: portal_skins/erp5_web/WebSite_view/listbox
# list_method: objectValues (Script providing listing)
# default_param_json: <base64 encoded JSON> (Additional search params)
# query: <str> (term for fulltext search)
# select_list: ['int_index', 'id', 'title', ...] (column names to select)
# limit: [15, 16] (begin_index, num_records)
# local_roles: TODO
################################################# #################################################
if REQUEST.other['method'] != "GET": if REQUEST.other['method'] != "GET":
response.setStatus(405) response.setStatus(405)
return "" return ""
# hardcoded responses for site and portal objects (which are not Documents!)
if query == "__root__": if query == "__root__":
# XXX Hardcoded behaviour to get root object with jIO
sql_list = [site_root] sql_list = [site_root]
elif query == "__portal__": elif query == "__portal__":
# XXX Hardcoded behaviour to get portal object with jIO
sql_list = [portal] sql_list = [portal]
# document = site_root
# document_result = {
# # '_relative_url': site_root.getRelativeUrl(),
# '_links': {
# 'self': {
# "href": default_document_uri_template % {
# "root_url": site_root.absolute_url(),
# "relative_url": document.getRelativeUrl(),
# "script_id": script.id
# },
# },
# }
# }
# for select in select_list:
# document_result[select] = document.getProperty(select, d=None)
# result_dict['_embedded'] = {"contents": [document_result]}
else: else:
# raise NotImplementedError("Unsupported query: %s" % query) catalog_kw = {
"local_roles": local_roles,
"limit": limit,
# # XXX "sort_on": () # default is empty tuple
# length = len('/%s/' % portal.getId()) }
# # context.log(portal.portal_catalog(full_text=query, limit=limit, src__=1)) if default_param_json is not None:
# context.log(query) catalog_kw.update(byteify(json.loads(urlsafe_b64decode(default_param_json))))
catalog_kw = {} if query:
if (default_param_json is not None): catalog_kw["full_text"] = query
catalog_kw = byteify(json.loads(urlsafe_b64decode(default_param_json))) if sort_on is not None:
if isinstance(sort_on, list):
catalog_kw['sort_on'] = tuple((byteify(sort_col), byteify(sort_order))
for sort_col, sort_order in map(json.loads, sort_on))
else:
sort_col, sort_order = json.loads(sort_on)
catalog_kw['sort_on'] = ((byteify(sort_col), byteify(sort_order)), )
if (list_method is None): if (list_method is None):
callable_list_method = portal.portal_catalog callable_list_method = portal.portal_catalog
else: else:
callable_list_method = getattr(traversed_document, list_method) callable_list_method = getattr(traversed_document, list_method)
tmp_sort_on = () sql_list = callable_list_method(**catalog_kw)
if sort_on is not None:
if isinstance(sort_on, list):
for grain in sort_on:
tmp_sort_on += (tuple([x for x in byteify(json.loads(grain))]),)
else:
#only one single criteria
tmp_sort_on = (tuple([x for x in byteify(json.loads(sort_on))]),)
result_list = [] # returned "content" of the search
if query:
sql_list = callable_list_method(full_text=query, limit=limit, sort_on=tmp_sort_on, local_roles=local_roles, **catalog_kw)
else:
sql_list = callable_list_method(limit=limit, sort_on=tmp_sort_on, local_roles=local_roles, **catalog_kw)
result_list = []
# if (select_list is None):
# # Only include links
# for sql_document in sql_list:
# document = sql_document.getObject()
# result_list.append({
# "href": default_document_uri_template % {
# "root_url": site_root.absolute_url(),
# "relative_url": document.getRelativeUrl(),
# "script_id": script.id
# },
# })
# result_dict['_links']['contents'] = result_list
#
# else:
# Cast to list if only one element is provided # Cast to list if only one element is provided
editable_field_dict = {} editable_field_dict = {}
if select_list is None: if select_list is None:
...@@ -1051,7 +1026,21 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1051,7 +1026,21 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if listbox_form.has_field("%s_%s" % (listbox_field_id, tmp), include_disabled=1): if listbox_form.has_field("%s_%s" % (listbox_field_id, tmp), include_disabled=1):
editable_field_dict[select] = listbox_form.get_field("%s_%s" % (listbox_field_id, tmp), include_disabled=1) editable_field_dict[select] = listbox_form.get_field("%s_%s" % (listbox_field_id, tmp), include_disabled=1)
for sql_document in sql_list: # handle the case when list-scripts are ignoring `limit` - paginate for them
if limit is not None and isinstance(limit, (tuple, list)):
start, num_items = map(int, limit)
if len(sql_list) <= num_items:
# the limit was most likely taken into account thus we don't need to slice
start, num_items = 0, len(sql_list)
else:
start, num_items = 0, len(sql_list)
for document_index, sql_document in enumerate(sql_list):
if document_index < start:
continue
if document_index >= start + num_items:
break
try: try:
document = sql_document.getObject() document = sql_document.getObject()
except AttributeError: except AttributeError:
...@@ -1059,7 +1048,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1059,7 +1048,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
document = sql_document document = sql_document
document_uid = sql_document.uid document_uid = sql_document.uid
document_result = { document_result = {
# '_relative_url': sql_document.path[length:],
'_links': { '_links': {
'self': { 'self': {
"href": default_document_uri_template % { "href": default_document_uri_template % {
...@@ -1085,10 +1073,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1085,10 +1073,9 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
else: else:
tmp_value = getProtectedProperty(document, select) tmp_value = getProtectedProperty(document, select)
property_value = renderField(traversed_document, editable_field_dict[select], form, property_value = renderField(
tmp_value, traversed_document, editable_field_dict[select], form, tmp_value,
key='field_%s_%s' % (editable_field_dict[select].id, key='field_%s_%s' % (editable_field_dict[select].id, document_uid))
document_uid))
REQUEST.other.pop('cell', None) REQUEST.other.pop('cell', None)
else: else:
property_value = getProtectedProperty(document, select) property_value = getProtectedProperty(document, select)
......
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
</item> </item>
<item> <item>
<key> <string>content_md5</string> </key> <key> <string>content_md5</string> </key>
<value> <string>654b376d060d3d312d97d43dc78e650d</string> </value> <value> <string>60763d62938eede7168df370bec46d5e</string> </value>
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
...@@ -98,11 +98,11 @@ ...@@ -98,11 +98,11 @@
</item> </item>
<item> <item>
<key> <string>filename</string> </key> <key> <string>filename</string> </key>
<value> <string>OfficeJS_Logo.png</string> </value> <value> <string>NXD-Media.Logo.png</string> </value>
</item> </item>
<item> <item>
<key> <string>height</string> </key> <key> <string>height</string> </key>
<value> <int>84</int> </value> <value> <int>200</int> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
</item> </item>
<item> <item>
<key> <string>width</string> </key> <key> <string>width</string> </key>
<value> <int>90</int> </value> <value> <int>200</int> </value>
</item> </item>
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
...@@ -279,7 +279,7 @@ ...@@ -279,7 +279,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.40537.63113.39850</string> </value> <value> <string>961.59574.17758.15342</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -297,7 +297,7 @@ ...@@ -297,7 +297,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1503564339.61</float> <float>1504703564.03</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -23,5 +23,5 @@ header{ ...@@ -23,5 +23,5 @@ header{
padding: 0.6em; padding: 0.6em;
} }
.main { .main {
padding-top: 19%; padding-top: 11%;
} }
\ No newline at end of file
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.57798.64228.15018</string> </value> <value> <string>961.59581.63.28398</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -262,7 +262,7 @@ ...@@ -262,7 +262,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1504603901.9</float> <float>1504704932.66</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -24,13 +24,16 @@ ...@@ -24,13 +24,16 @@
<!-- Initialize --> <!-- Initialize -->
<tr> <tr>
<td>open</td> <td>open</td>
<td>${base_url}/web_site_module/ooffice_spreadsheet/</td> <td>${base_url}/web_site_module/ooffice_spreadsheet?ignore_layout:int=1&editable_mode:int=1</td>
<td></td> <td></td>
</tr> </tr>
<!-- Initialize -->
<tr> <tr>
<td>open</td> <td>runScript</td>
<td>${base_url}/web_site_module/ooffice_text?ignore_layout:int=1&editable_mode:int=1</td> <td>
window.indexedDB.deleteDatabase('jio:officejs_code_source');
window.indexedDB.deleteDatabase('jio:officejs-hash');
window.indexedDB.deleteDatabase('jio:setting')
</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
...@@ -60,11 +63,6 @@ ...@@ -60,11 +63,6 @@
<td>${base_url}/web_site_module/${test_url}/</td> <td>${base_url}/web_site_module/${test_url}/</td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>runScript</td>
<td>window.indexedDB.deleteDatabase('jio:setting')</td>
<td></td>
</tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>link=Local is Enough</td> <td>link=Local is Enough</td>
...@@ -159,6 +157,6 @@ ...@@ -159,6 +157,6 @@
<!-- Stop Generic --> <!-- Stop Generic -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>identifier=id_main</td> <td>identifier=ws-canvas</td>
<td></td> <td></td>
</tr> </tr>
\ No newline at end of file
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<!-- Initialize --> <!-- Initialize -->
<tr> <tr>
<td>open</td> <td>open</td>
<td>${base_url}/web_site_module/ooffice_text?ignore_layout:int=1&editable_mode:int=1</td> <td>${base_url}/web_site_module/ooffice_spreadsheet?ignore_layout:int=1&editable_mode:int=1</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
<!-- Stop Generic --> <!-- Stop Generic -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>identifier=id_main</td> <td>identifier=ws-canvas</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
......
...@@ -164,7 +164,6 @@ body { ...@@ -164,7 +164,6 @@ body {
display: block; display: block;
color: #1F1F1F; color: #1F1F1F;
word-wrap: break-word; word-wrap: break-word;
word-break: break-word;
} }
body, body,
button, button,
...@@ -1337,6 +1336,7 @@ div[data-gadget-scope='erp5_searchfield'] button { ...@@ -1337,6 +1336,7 @@ div[data-gadget-scope='erp5_searchfield'] button {
.document_table table tbody tr th:first-child ~ td { .document_table table tbody tr th:first-child ~ td {
font-size: 0.8em; font-size: 0.8em;
display: inline; display: inline;
word-break: break-word;
} }
.document_table table tbody tr td:first-child ~ th a, .document_table table tbody tr td:first-child ~ th a,
.document_table table tbody tr th:first-child ~ th a, .document_table table tbody tr th:first-child ~ th a,
...@@ -1414,10 +1414,15 @@ div[data-gadget-scope='notification'] button { ...@@ -1414,10 +1414,15 @@ div[data-gadget-scope='notification'] button {
text-align: left; text-align: left;
width: 180pt; width: 180pt;
padding: 12pt; padding: 12pt;
background-color: #FF6600;
color: #f8fff3; color: #f8fff3;
border-radius: 0.325em; border-radius: 0.325em;
} }
div[data-gadget-scope='notification'] button.success {
background-color: #37A419;
}
div[data-gadget-scope='notification'] button.error {
background-color: #FF6600;
}
/********************************************** /**********************************************
* JQM * JQM
**********************************************/ **********************************************/
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.52328.26727.8140</string> </value> <value> <string>961.60979.41143.53009</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1504269035.79</float> <float>1504787937.42</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -8,12 +8,21 @@ ...@@ -8,12 +8,21 @@
<!-- renderjs --> <!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.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>
<!-- custom script --> <!-- custom script -->
<script src="gadget_erp5_notification.js" type="text/javascript"></script> <script src="gadget_erp5_notification.js" type="text/javascript"></script>
</head> </head>
<body> <body>
<button type="submit"></button>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>956.4305.51031.8243</string> </value> <value> <string>961.59386.3771.60654</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1482165353.33</float> <float>1504692216.38</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, Node, rJS */ /*global window, Node, rJS, Handlebars */
(function (window, Node, rJS) { (function (window, Node, rJS, Handlebars) {
"use strict"; "use strict";
rJS(window) 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 // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod('notify', function (message) { gadget_klass
if (typeof message === "string") { .declareMethod('notify', function (options) {
// alertify.log(message); if (options) {
return this.changeState({ return this.changeState({
visible: true, visible: true,
message: message message: options.message,
status: options.status
}); });
} }
return this.changeState({ return this.changeState({
...@@ -40,8 +51,15 @@ ...@@ -40,8 +51,15 @@
} }
if (modification_dict.hasOwnProperty('message')) { if (modification_dict.hasOwnProperty('message')) {
var button = this.element.querySelector('button'); if (this.state.status === 'success') {
button.textContent = this.state.message; this.element.innerHTML = success_button_template({
message: this.state.message
});
} else {
this.element.innerHTML = error_button_template({
message: this.state.message
});
}
} }
}) })
...@@ -53,4 +71,4 @@ ...@@ -53,4 +71,4 @@
} }
}, false, false); }, false, false);
}(window, Node, rJS)); }(window, Node, rJS, Handlebars));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>956.5681.7605.23227</string> </value> <value> <string>961.59536.21138.61354</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1482241180.82</float> <float>1504769866.21</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -262,7 +262,10 @@ ...@@ -262,7 +262,10 @@
message = JSON.parse(responseText).portal_status_message; message = JSON.parse(responseText).portal_status_message;
} catch (ignore) { } catch (ignore) {
} }
list.push(form_gadget.notifySubmitted(message)); list.push(form_gadget.notifySubmitted({
"message": message,
"status": "success"
}));
if (redirect_to_parent) { if (redirect_to_parent) {
list.push(form_gadget.redirect({command: 'history_previous'})); list.push(form_gadget.redirect({command: 'history_previous'}));
...@@ -312,7 +315,10 @@ ...@@ -312,7 +315,10 @@
return form_gadget.translate(error_text); return form_gadget.translate(error_text);
}) })
.push(function (message) { .push(function (message) {
return form_gadget.notifyChange(message + '.'); return form_gadget.notifyChange({
"message": message + '.',
"status": "error"
});
}); });
// if server validation of form data failed (indicated by response code 400) // if server validation of form data failed (indicated by response code 400)
// we parse out field errors and display them to the user // we parse out field errors and display them to the user
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.16461.13159.33399</string> </value> <value> <string>961.59533.60499.59221</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1502116641.07</float> <float>1504701037.67</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -137,27 +137,27 @@ ...@@ -137,27 +137,27 @@
}) })
.push(function (validity) { .push(function (validity) {
if (validity) { if (validity) {
return erp5_form.getContent() return form_gadget.notifySubmitting()
// try to send the form data over the network to jIO storage .push(function () {
// try to send the form data over the network to jIO storage
return erp5_form.getContent();
})
.push(function (data) { .push(function (data) {
data[form_id.key] = form_id['default']; data[form_id.key] = form_id['default'];
return RSVP.all([ return form_gadget.jio_putAttachment(
form_gadget.notifySubmitting(), form_gadget.state.jio_key,
form_gadget.jio_putAttachment( action.href,
form_gadget.state.jio_key, data
action.href, );
data
)
]);
}) })
// handle response from the server // handle response from the server
.push(function (result_list) { .push(function (result) {
if (result_list[1].target.responseType === "blob") { if (result.target.responseType === "blob") {
return jIO.util.readBlobAsText(result_list[1].target.response); return jIO.util.readBlobAsText(result.target.response);
} }
return {target: {result: result_list[1].target.response}}; return {target: {result: result.target.response}};
}) })
.push(function (event) { .push(function (event) {
var message; var message;
...@@ -165,7 +165,10 @@ ...@@ -165,7 +165,10 @@
message = JSON.parse(event.target.result).portal_status_message; message = JSON.parse(event.target.result).portal_status_message;
} catch (ignore) { } catch (ignore) {
} }
return form_gadget.notifySubmitted(message); return form_gadget.notifySubmitted({
"message": message,
"status": "success"
});
}) })
.push(function () { .push(function () {
return form_gadget.redirect({command: 'reload'}); return form_gadget.redirect({command: 'reload'});
...@@ -189,7 +192,10 @@ ...@@ -189,7 +192,10 @@
return form_gadget.translate(error_text); return form_gadget.translate(error_text);
}) })
.push(function (message) { .push(function (message) {
return form_gadget.notifyChange(message + '.'); return form_gadget.notifyChange({
'message': message + '.',
'status': 'error'
});
}); });
// if server validation of form data failed (indicated by response code 400) // if server validation of form data failed (indicated by response code 400)
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.16418.20259.26675</string> </value> <value> <string>961.59393.42745.39918</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1502116591.57</float> <float>1504701066.63</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -40,7 +40,7 @@ else: ...@@ -40,7 +40,7 @@ else:
person = portal.portal_membership.getAuthenticatedMember().getUserValue() person = portal.portal_membership.getAuthenticatedMember().getUserValue()
url_parameter = "n.me" url_parameter = "n.me"
pattern = '{[&|?]%s}' % url_parameter pattern = '{[&|?]%s}' % url_parameter
if (person is None): if (person is None or not portal.portal_membership.checkPermission('View', person)):
came_from = re.sub(pattern, '', came_from) came_from = re.sub(pattern, '', came_from)
else: else:
prefix = "&" if "&%s" % url_parameter in came_from else "?" prefix = "&" if "&%s" % url_parameter in came_from else "?"
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
@txtgreen: #22CC22; @txtgreen: #22CC22;
@txtsubgrey: #575757; @txtsubgrey: #575757;
@grey: #777777; @grey: #777777;
@backgroundgreen: #37A419;
// Default background for pages and other controls // Default background for pages and other controls
...@@ -233,7 +234,6 @@ body { ...@@ -233,7 +234,6 @@ body {
color: @colorforeground; color: @colorforeground;
word-wrap: break-word; word-wrap: break-word;
word-break: break-word;
} }
body, button, input, textarea, select { body, button, input, textarea, select {
...@@ -1551,6 +1551,7 @@ div[data-gadget-scope='erp5_searchfield'] { ...@@ -1551,6 +1551,7 @@ div[data-gadget-scope='erp5_searchfield'] {
font-size: 0.8em; font-size: 0.8em;
// Cells must be next to the other and correctly aligned // Cells must be next to the other and correctly aligned
display: inline; display: inline;
word-break: break-word;
a { a {
pointer-events: none; pointer-events: none;
...@@ -1634,9 +1635,14 @@ div[data-gadget-scope='notification'] { ...@@ -1634,9 +1635,14 @@ div[data-gadget-scope='notification'] {
text-align: left; text-align: left;
width: @panelwidth; width: @panelwidth;
padding: @double-margin-size; padding: @double-margin-size;
background-color: @coloraccent;
color: @colorsubheaderlink; color: @colorsubheaderlink;
border-radius: @border-radius; border-radius: @border-radius;
&.success {
background-color: @backgroundgreen;
}
&.error {
background-color: @coloraccent;
}
} }
} }
......
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<!--
Ensure anything can be paginated even thought the list script does not support it.
Fortunately - `contentValues` which is the base of many listboxes does not give
a damn about limits so it is perfect adept for testing.
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr><td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Reset Successfully.</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>store</td>
<td>${base_url}/web_site_module/renderjs_runner</td>
<td>renderjs_url</td></tr>
<tr><td>store</td>
<td>//div[@data-gadget-url="${renderjs_url}/gadget_erp5_field_listbox.html"]</td>
<td>listbox</td></tr>
<!-- Our listbox displays 3 lines so we want to test pagination twice -->
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?start:int=1&amp;num:int=1&amp;create_line:int=0</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr>
<tr><td>open</td>
<td>${base_url}/foo_module/1/Foo_createObjects?start:int=1&amp;num:int=8&amp;</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr><td>open</td>
<td>${renderjs_url}/#/foo_module/1?editable=1</td><td></td></tr>
<tr><td>waitForElementPresent</td><!-- wait explicitely for the first listbox which holds the modification history -->
<td>${listbox}//a[@data-i18n="Next"]</td><td></td></tr>
<tr><td>assertElementNotPresent</td><!-- "Next" link must be enabled -->
<td>${listbox}//a[@data-i18n="Next" and contains(@class, "ui-disabled")]</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Records 1 - 3</td><td></td></tr>
<tr><td>click</td>
<td>${listbox}//a[@data-i18n="Next"]</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr><td>waitForElementPresent</td>
<td>${listbox}//a[@data-i18n="Next"]</td><td></td></tr>
<tr><td>assertElementNotPresent</td><!-- "Next" link must be enabled -->
<td>${listbox}//a[@data-i18n="Next" and contains(@class, "ui-disabled")]</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Records 4 - 6</td><td></td></tr>
<tr><td>click</td><!-- wait explicitely for the first listbox which holds the modification history -->
<td>${listbox}//a[@data-i18n="Next"]</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr><td>waitForElementPresent</td><!-- wait explicitely for the first listbox which holds the modification history -->
<td>${listbox}//a[@data-i18n="Next"]</td><td></td></tr>
<tr><td>assertElementPresent</td><!-- "Next" link must be disabled because we are at the end -->
<td>${listbox}//a[@data-i18n="Next" and contains(@class, "ui-disabled")]</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Records 7 - 8</td><td></td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testActionFail</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Form View Editable Save Action</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Default Module View</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module/1?editable=true</td>
<td></td>
</tr>
<!-- Wait for gadget to be loaded -->
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-url='${base_url}/web_site_module/renderjs_runner/gadget_erp5_pt_form_view_editable.html']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Actions</td>
<td></td>
</tr>
<!-- Go to the new content dialog -->
<tr>
<td>click</td>
<td>//div[@data-gadget-scope='header']//a[text()='Actions' and contains(@href, '#!change')]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-url='${base_url}/web_site_module/renderjs_runner/gadget_erp5_page_action.html']</td>
<td></td>
</tr>
<!-- Header has a save button -->
<tr>
<td>waitForElementPresent</td>
<td>//a[text()='Do Nothing Action' and contains(@href, '#!change')]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()='Do Nothing Action' and contains(@href, '#!change')]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='notification']//button[@class='error']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -79,6 +79,11 @@ ...@@ -79,6 +79,11 @@
<td></td> <td></td>
</tr> </tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='notification']//button[@class='error']</td>
<td></td>
</tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -76,6 +76,12 @@ ...@@ -76,6 +76,12 @@
<td></td> <td></td>
</tr> </tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='notification']//button[@class='success']</td>
<td></td>
</tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -66,6 +66,12 @@ ...@@ -66,6 +66,12 @@
<td></td> <td></td>
</tr> </tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='notification']//button[@class='success']</td>
<td></td>
</tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testAccessUnauthorizedRelationValue</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr>
<td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_createHasUnauthorizedFoo</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Done</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<!-- Initialize -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[contains(text(), 'hasAccessUnauthorized')]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[contains(text(), 'hasAccessUnauthorized')]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Editable"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Editable"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n="Save"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n="Save"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//label[@for="field_my_successor_title"]</td>
<td></td>
</tr>
<tr>
<td>verifyElementNotPresent</td>
<td>//div[@data-gadget-scope="field_my_successor_title"]//input</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -227,12 +227,18 @@ ...@@ -227,12 +227,18 @@
<td>//input[@value='Login']</td> <td>//input[@value='Login']</td>
<td></td> <td></td>
</tr> </tr>
<!--As the user don't have access to anything(no assignment), he come back to login page --> <!--User can access even has no access to it's person document -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementNotPresent</td>
<td>//input[@name='__ac_name']</td> <td>//input[@name='__ac_name']</td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@data-i18n='Worklist']</td>
<td></td>
</tr>
</tbody></table> </tbody></table>
</body> </body>
</html> </html>
\ No newline at end of file
foo1 = context.foo_module.newContent(portal_type='Foo')
foo2 = context.foo_module.newContent(portal_type='Foo')
foo1.setTitle('hasAccessUnauthorized')
foo1.setSuccessorValue(foo2)
foo1.immediateReindexObject()
foo2.immediateReindexObject()
foo2.activate().manage_permission( 'Access contents information', 'Manager', 0)
return 'Done'
<?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></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Foo_createHasUnauthorizedFoo</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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