Commit 45641950 authored by Tomáš Peterka's avatar Tomáš Peterka

Functional stats line in ListBox

parent a26aa2dd
......@@ -676,8 +676,8 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
"lines": field.get_value('lines'),
"default_params": ensure_serializable(default_params),
"list_method": list_method_name,
"stat_method": field.get_value('stat_method').getMethodName() if field.get_value('stat_method') != "" else "",
"count_method": field.get_value('count_method').getMethodName() if field.get_value('count_method') != "" else "",
"show_stat": field.get_value('stat_method') != "" or len(field.get_value('stat_columns')) > 0,
"show_count": field.get_value('count_method') != "",
"query": url_template_dict["jio_search_template"] % {
"query": make_query({
"query": sql_catalog.buildQuery(
......@@ -1430,8 +1430,11 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
editable_field_dict = {}
listbox_form = None
listbox_field_id = None
source_field_meta_type = source_field.meta_type if source_field is not None else ""
if source_field_meta_type == "ProxyField":
source_field_meta_type = source_field.getRecursiveTemplateField().meta_type
if source_field is not None and source_field.meta_type == "ListBox":
if source_field is not None and source_field_meta_type == "ListBox":
listbox_field_id = source_field.id
# XXX Proxy field are not correctly handled in traversed_document of web site
listbox_form = getattr(traversed_document, source_field.aq_parent.id)
......@@ -1454,7 +1457,13 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
start, num_items = 0, len(search_result_iterable)
contents_list = [] # resolved fields from the search result
result_dict.update({
'_query': query,
'_local_roles': local_roles,
'_limit': limit,
'_select_list': select_list,
'_embedded': {}
})
# now fill in `contents_list` with actual information
# beware that search_result_iterable can hide anything inside!
for result_index, search_result in enumerate(search_result_iterable):
......@@ -1514,44 +1523,59 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# given search_result. This name can unfortunately mean almost anything from
# a key name to Python Script with variable number of input parameters.
contents_item[select] = resolve_field(search_result, select, property_getter, property_hasser)
# endfor select
contents_list.append(contents_item)
result_dict.update({
'_query': query,
'_local_roles': local_roles,
'_limit': limit,
'_select_list': select_list,
'_embedded': {
result_dict['_embedded'].update({
'contents': contents_list
}
})
# Compute statistics if the search issuer was ListBox
# or in future if the stats (SUM) are required by JIO call
source_field_meta_type = source_field.meta_type if source_field is not None else ""
if source_field_meta_type == "ProxyField":
source_field_meta_type = source_field.getRecursiveTemplateField().meta_type
context.log('source_field "{!s}", source_field_meta_type {!s}'.format(source_field, source_field_meta_type))
if source_field is not None and source_field_meta_type == "ListBox":
contents_stat_list = []
if source_field is not None and source_field.meta_type == "ListBox":
# in case the search was issued by listbox we can provide results of
# stat_method and count_method back to the caller
# XXX: we should check whether they asked for it
stat_method = source_field.get_value('stat_method')
stat_columns = source_field.get_value('stat_columns')
context.log('stat_method "{!s}", stat_columns {!s}'.format(stat_method, stat_columns))
# Selection is unfortunatelly required fot stat methods
selection_name = source_field.get_value('selection_name')
selection = None
if selection_name:
selection_tool = context.getPortalObject().portal_selections
selection = selection_tool.getSelectionFor(selection_name, REQUEST)
contents_stat = {}
if len(stat_columns) > 0:
# prefer stat per columns as it is in ListBox
# always called on current context
for stat_name, stat_script in stat_columns:
contents_stat[stat_name] = getattr(traversed_document, stat_script)(**catalog_kw)
contents_stat[stat_name] = getattr(traversed_document, stat_script)(
selection=selection,
selection_name=selection_name,
**catalog_kw)
contents_stat_list.append(contents_stat)
elif stat_method != "" and stat_method.getMethodName() != list_method_name:
# global stat_method is second - should return dictionary or list of dictionaries
# where all "fields" should be accessible by its "select" name
elif stat_method != "" and stat_method.getMethodName() != list_method:
# general stat_method is second - should return dictionary or list of dictionaries
# where all "fields" should be accessible by their "select" name
contents_stat_list = getattr(traversed_document, stat_method.getMethodName())(**catalog_kw)
for contents_stat in contents_stat_list:
for key, value in contents_stat.items():
if key in editable_field_dict:
contents_stat[key] = renderField(
traversed_document, editable_field_dict[key], listbox_form, value, key=editable_field_dict[key].id + '__sum')
context.log('contents_stat_list {!s}'.format(contents_stat_list))
if len(contents_stat_list) > 0:
result_dict['_embedded'].update({
'contents': contents_list
'sum': contents_stat_list
})
# We should cleanup the selection if it exists in catalog params BUT
......
......@@ -179,12 +179,14 @@
)
.push(function (catalog_json) {
var data = catalog_json._embedded.contents,
count = data.length,
summary = catalog_json._embedded.sum,
count = catalog_json._embedded.count,
length = data.length,
k,
uri,
item,
result = [];
for (k = 0; k < count; k += 1) {
for (k = 0; k < length; k += 1) {
item = data[k];
uri = new URI(item._links.self.href);
delete item._links;
......@@ -198,7 +200,9 @@
data: {
rows: result,
total_rows: result.length
}
},
sum: summary,
count: count
};
});
})
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>947.45414.13002.10052</string> </value>
<value> <string>963.50499.50100.12458</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1449753994.81</float>
<float>1511939345.58</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -118,55 +118,37 @@
</table>
</script>
<script id="listbox-tfoot-sum-template" type="text/x-handlebars-template">
<script id="listbox-tfoot-template" type="text/x-handlebars-template">
<table>
<tfoot class="ui-bar-inherit tfoot summary">
<tfoot class="ui-bar-inherit tfoot">
{{#each row_list}}
<tr>
{{#if ../show_anchor}}
<td></td>
{{/if}}
{{#each cell_list}}
<td>
{{#if type}}
{{#if editable}}
<div class="editable_div" data-column="{{column}}" data-line="{{line}}"></div>
{{else}}
<a href="{{href}}" class="ui-link">
<div class="editable_div" data-column="{{column}}" data-line="{{line}}"></div>
</a>
{{/if}}
{{else}}
<a href="{{href}}" class="ui-link">{{text}}</a>
{{text}}
{{/if}}
</td>
{{/each}}
</tr>
{{/each}}
<th colspan="{{colspan}}">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-corner-all ui-paging-menu">
<div class="ui-controlgroup-controls">
<a class="{{previous_classname}}" data-i18n="Previous" href="{{previous_url}}">Previous</a>
<a class="{{next_classname}}" data-i18n="Next" href="{{next_url}}">Next</a>
<span class="ui-btn ui-disabled" data-i18n="{{record}}">{{record}}</span>
</div>
</div>
</th>
</tfoot>
</table>
</script>
<script id="listbox-tfoot-count-template" type="text/x-handlebars-template">
<table>
<tfoot class="ui-bar-inherit tfoot">
<th colspan="{{colspan}}">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-corner-all ui-paging-menu">
<script id="listbox-nav-template" type="text/x-handlebars-template">
<nav class="ui-bar-inherit ui-controlgroup ui-controlgroup-horizontal ui-corner-all ui-paging-menu">
<div class="ui-controlgroup-controls">
<a class="{{previous_classname}}" data-i18n="Previous" href="{{previous_url}}">Previous</a>
<a class="{{next_classname}}" data-i18n="Next" href="{{next_url}}">Next</a>
<span class="ui-btn ui-disabled" data-i18n="{{record}}">{{record}}</span>
</div>
</div>
</th>
</tfoot>
</table>
</nav>
</script>
<script id="listbox-template" type="text/x-handlebars-template">
......@@ -188,6 +170,7 @@
<tbody></tbody>
<tfoot class="ui-bar-inherit tfoot"></tfoot>
</table>
<nav></nav>
</div>
</script>
......
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.47536.5989.57173</string> </value>
<value> <string>963.50750.47688.32426</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1511764805.38</float>
<float>1511952124.83</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -19,15 +19,15 @@
.innerHTML,
listbox_show_tbody_template = Handlebars.compile(listbox_show_tbody_source),
listbox_tfoot_sum_source = gadget_klass.__template_element
.getElementById("listbox-tfoot-sum-template")
listbox_tfoot_source = gadget_klass.__template_element
.getElementById("listbox-tfoot-template")
.innerHTML,
listbox_tfoot_sum_template = Handlebars.compile(listbox_tfoot_sum_source),
listbox_tfoot_template = Handlebars.compile(listbox_tfoot_source),
listbox_tfoot_count_source = gadget_klass.__template_element
.getElementById("listbox-tfoot-count-template")
listbox_nav_source = gadget_klass.__template_element
.getElementById("listbox-nav-template")
.innerHTML,
listbox_tfoot_count_template = Handlebars.compile(listbox_tfoot_count_source),
listbox_nav_template = Handlebars.compile(listbox_nav_source),
listbox_source = gadget_klass.__template_element
.getElementById("listbox-template")
......@@ -43,7 +43,7 @@
disabled_class = 'ui-disabled';
function renderEditableField(gadget, element, column_list) {
function renderEditableField(gadget, element, column_list, field_table) {
var i,
promise_list = [],
uid_value_dict = {},
......@@ -79,8 +79,9 @@
gadget.props.listbox_uid_dict.value.push(uid_value);
}
}
promise_list.push(renderSubCell(element_list[i],
gadget.state.allDocs_result.data.rows[line].value[column_list[column][0]] || ""));
promise_list.push(renderSubCell(
element_list[i],
field_table[line].cell_list[column] || ""));
}
return RSVP.all(promise_list);
}
......@@ -90,9 +91,9 @@
First, it removes all similar containers from within the table! Currently it is tricky
to have multiple tbody/thead/tfoot elements! Feel free to refactor.
Example call: renderListboxTbody(gadget, compiled_template, row_list, "tbody");
Example call: renderTablePart(gadget, compiled_template, row_list, "tbody");
**/
function renderListboxTbody(gadget, template, row_list, container_name) {
function renderTablePart(gadget, template, row_list, container_name) {
var container,
column_list = JSON.parse(gadget.state.column_list_json);
......@@ -106,28 +107,36 @@
.push(function (my_html) {
container = document.createElement(container_name);
container.innerHTML = my_html;
return renderEditableField(gadget, container, column_list);
return renderEditableField(gadget, container, column_list, row_list);
})
.push(function () {
var table = gadget.element.querySelector("table"),
old_container = table.querySelector(container_name);
table.removeChild(old_container);
if (old_container) {
table.replaceChild(container, old_container);
} else {
table.appendChild(container);
}
return table;
});
}
function renderListboxTfoot(gadget, foot_count, foot_sum) {
return gadget.translateHtml(listbox_tfoot_count_template(
function renderListboxTfoot(gadget, nav, foot_sum) {
return renderTablePart(gadget, listbox_tfoot_template, foot_sum, "tfoot")
.push(function () {
return gadget.translateHtml(listbox_nav_template(
{
"colspan": foot_count.colspan,
"previous_classname": foot_count.previous_classname,
"previous_url": foot_count.previous_url,
"record": foot_count.record,
"next_classname": foot_count.next_classname,
"next_url": foot_count.next_url
"previous_classname": nav.previous_classname,
"previous_url": nav.previous_url,
"record": nav.record,
"next_classname": nav.next_classname,
"next_url": nav.next_url
}
));
}).push(function (listbox_nav_html) {
gadget.element.querySelector('nav').innerHTML = listbox_nav_html;
});
}
/** Clojure to ease finding in lists of lists by the first item **/
......@@ -254,6 +263,9 @@
sort_list_json: JSON.stringify(result_list[1] || field_json.sort.map(jioize_sort)),
show_anchor: field_json.show_anchor,
show_stat: field_json.show_stat,
show_count: field_json.show_count,
line_icon: field_json.line_icon,
query: field_json.query,
query_string: query_string,
......@@ -412,6 +424,8 @@
});
}
/* Function `fetchLineContent` calls changeState({"allDocs_result": JIO.allDocs()})
so this if gets re-evaluated later with allDocs_result defined. */
if (gadget.state.allDocs_result === undefined) {
// Trigger line content calculation
result_queue
......@@ -427,7 +441,6 @@
} else if ((modification_dict.hasOwnProperty('show_line_selector')) ||
(modification_dict.hasOwnProperty('allDocs_result'))) {
// Render the listbox content
result_queue
.push(function () {
......@@ -437,7 +450,7 @@
counter;
column_list = JSON.parse(gadget.state.column_list_json);
// for actual allDocs_result structure see ref:gadget_erp5_jio.js
if (lines === 0) {
lines = allDocs_result.data.total_rows;
counter = allDocs_result.data.total_rows;
......@@ -478,14 +491,17 @@
cell_list = [];
for (j = 0; j < column_list.length; j += 1) {
value = allDocs_result.data.rows[i].value[column_list[j][0]] || "";
cell_list.push({
"type": value.type,
"editable": value.editable && gadget.state.editable,
"href": tmp_url,
"text": value,
"line": i,
"column": j
});
if (typeof value === "string") {
value = {
'editable': 0,
'default': value
};
}
value.href = tmp_url;
value.editable = value.editable && gadget.state.editable;
value.line = i;
value.column = j;
cell_list.push(value);
}
row_list.push({
"value": allDocs_result.data.rows[i].value.uid,
......@@ -501,7 +517,7 @@
listbox_tbody_template = listbox_hidden_tbody_template;
}
return renderListboxTbody(gadget, listbox_tbody_template, row_list, "tbody");
return renderTablePart(gadget, listbox_tbody_template, row_list, "tbody", "tbody");
})
.push(function () {
var prev_param = {},
......@@ -525,13 +541,27 @@
})
.push(function (url_list) {
var tfoot_count = {
var summary = gadget.state.allDocs_result.sum || [], // render summary footer if available
tfoot_sum = summary.map(function (row, row_index) {
return {
"value": 'summary' + row_index,
"cell_list": column_list.map(function (col_name, col_index) {
var field_json = row[col_name[0]] || "";
if (typeof field_json == "string") {
field_json = {'default': 'value', 'editable': 0};
}
field_json.column = col_index;
field_json.line = row_index;
return field_json;
})
};
}),
tfoot_count = {
"previous_url": url_list[0],
"next_url": url_list[1],
"previous_classname": "ui-btn ui-icon-carat-l ui-btn-icon-left responsive ui-first-child",
"next_classname": "ui-btn ui-icon-carat-r ui-btn-icon-right responsive ui-last-child"
},
tfoot_sum = {};
};
tfoot_count.colspan = column_list.length + gadget.state.show_anchor +
(gadget.state.line_icon ? 1 : 0);
......@@ -553,7 +583,6 @@
return renderListboxTfoot(gadget, tfoot_count, tfoot_sum);
})
.push(function (my_html) {
gadget.element.querySelector(".tfoot").innerHTML = my_html;
var loading_element_classList = gadget.element.querySelector(".listboxloader").classList;
loading_element_classList.remove.apply(loading_element_classList, loading_class_list);
});
......@@ -594,7 +623,8 @@
var gadget = this,
select_list = [],
limit_options,
limit_options = [],
aggregation_option_list = [],
column_list = JSON.parse(gadget.state.column_list_json),
i;
......@@ -609,6 +639,12 @@
limit_options = [gadget.state.begin_from, gadget.state.lines + 1];
}
if (gadget.state.show_stat === true) {
aggregation_option_list.push("sum");
}
if (gadget.state.show_count === true) {
aggregation_option_list.push("count");
}
return gadget.jio_allDocs({
// XXX Not jIO compatible, but until a better api is found...
......@@ -617,6 +653,7 @@
"limit": limit_options,
"select_list": select_list,
"sort_on": JSON.parse(gadget.state.sort_list_json)
// "aggregation": aggregation_option_list
})
.push(function (result) {
return gadget.changeState({
......
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.47634.31999.4898</string> </value>
<value> <string>963.50757.35572.58794</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1511765129.91</float>
<float>1511952430.52</float>
<string>UTC</string>
</tuple>
</state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment