Merge branch 'feature/widgets' into feature/multi_choice

pull/6827/head
Philipp Tessenow 14 years ago
commit 95773340d8
  1. BIN
      assets/images/arrow_B_down.gif
  2. BIN
      assets/images/arrow_B_left.gif
  3. BIN
      assets/images/arrow_B_right.gif
  4. BIN
      assets/images/arrow_B_up.gif
  5. BIN
      assets/images/arrow_D_down.gif
  6. BIN
      assets/images/arrow_D_left.gif
  7. BIN
      assets/images/arrow_D_right.gif
  8. BIN
      assets/images/arrow_D_up.gif
  9. BIN
      assets/images/button_hover.png
  10. BIN
      assets/images/button_inactive.png
  11. BIN
      assets/images/button_normal.png
  12. BIN
      assets/images/group_by_arrow_both.png
  13. BIN
      assets/images/group_by_arrow_both_hover_left.png
  14. BIN
      assets/images/group_by_arrow_both_hover_right.png
  15. BIN
      assets/images/group_by_arrow_both_remove.png
  16. BIN
      assets/images/group_by_arrow_left.png
  17. BIN
      assets/images/group_by_arrow_left_hover.png
  18. BIN
      assets/images/group_by_arrow_left_remove.png
  19. BIN
      assets/images/group_by_arrow_right.png
  20. BIN
      assets/images/group_by_arrow_right_hover.png
  21. 53
      assets/javascripts/reporting.js
  22. 28
      assets/javascripts/reporting/controls.js
  23. 4
      assets/javascripts/reporting/filters.js
  24. 195
      assets/javascripts/reporting/group_bys.js
  25. 57
      assets/javascripts/reporting/restore_query.js
  26. 151
      assets/javascripts/select_list_move_optgroup.js
  27. 100
      assets/stylesheets/reporting.css
  28. 4
      lib/report.rb
  29. 132
      lib/widget/group_bys.rb
  30. 114
      lib/widget/old_group_bys.rb

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -28,7 +28,7 @@ window.Reporting = {
}
if ($("flash_" + type) !== null) {
$("flash_" + type).remove();
};
}
var flash = document.createElement('div');
flash.setAttribute('id', 'flash_' + type);
flash.setAttribute('onclick', '$(this).remove();');
@ -62,54 +62,3 @@ Reporting.require("filters");
Reporting.require("group_bys");
Reporting.require("restore_query");
Reporting.require("controls");
//
// function hide_category(tr_field) {
// var label = $(tr_field.getAttribute("data-label"));
// if (label !== null) {
// label.hide();
// }
// }
//
// function restore_select_values(select, values) {
// var i, j;
// if (values.length > 1) {
// make_select_accept_multiple_values(select);
// } else {
// make_select_accept_single_value(select);
// }
// for (i = 0; i < values.length; i += 1) {
// for (j = 0; j < select.options.length; j += 1) {
// if (select.options[j].value === values[i].toString()) {
// try {
// select.options[j].selected = true;
// break;
// } catch(e) {
// window.setTimeout('$("' + select.id + '").childElements()[' + j + '].selected = true;', 1);
// }
// }
// }
// }
// }
//
// function defineElementGetter() {
// if (document.getElementsByClassName === undefined) {
// document.getElementsByClassName = function (className)
// {
// var hasClassName, allElements, results, element, elementClass, i;
// hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
// allElements = document.getElementsByTagName("*");
// results = [];
// for (i = 0; (element = allElements[i]) !== null; i += 1) {
// elementClass = element.className;
// if (elementClass && elementClass.indexOf(className) !== -1 && hasClassName.test(elementClass)) {
// results.push(element);
// }
// }
// return results;
// };
// }
// }
//
// // defineElementGetter();

@ -70,22 +70,36 @@ Reporting.Controls = {
failureCallback = Reporting.Controls.default_failure_callback;
}
Reporting.clearFlash();
selectAllOptions('group_by_rows');
selectAllOptions('group_by_columns');
var updater = new Ajax.Request(
new Ajax.Request(
targetUrl,
{ asynchronous: true,
evalScripts: true,
postBody: Form.serialize('query_form'),
postBody: Reporting.Controls.serialize_settings_form(),
onSuccess: callback,
onFailure: failureCallback});
onFailure: failureCallback });
},
serialize_settings_form: function() {
var ret_str, grouping_str;
ret_str = Form.serialize('query_form');
grouping_str = $w('rows columns').inject('', function(grouping, type) {
return grouping + $('group_by_' + type).select('.group_by_element').map(function(group_by) {
return 'groups[' + type + '][]=' + group_by.readAttribute('data-group-by');
}).inject('', function(all_group_str, group_str) {
return all_group_str + '&' + group_str;
});
});
if (grouping_str.length > 0) {
ret_str += grouping_str;
}
return ret_str;
},
attach_settings_callback: function (element, callback) {
failureCallback = function (response) {
$('result-table').update("");
Reporting.Controls.default_failure_callback(response);
}
};
element.observe("click", function (e) {
Reporting.Controls.send_settings_data(this.getAttribute("data-target"), callback, failureCallback);
e.preventDefault();
@ -104,7 +118,7 @@ Reporting.Controls = {
},
default_failure_callback: function (response) {
if ((response.status + "")[0] === "4") {
if (response.status >= 400 && response.status < 500) {
Reporting.flash(response.responseText);
} else {
Reporting.flash("There was an error getting the results. The administrator has been informed.");

@ -243,7 +243,7 @@ Reporting.Filters = {
// Param: select [optional] - the select-box of the filter which should activate it's dependents
activate_dependents: function (selectBox, callbackWhenFinished) {
var dependents, active_filters, source;
if (selectBox === undefined || selectBox.type == 'change') {
if (selectBox === undefined || selectBox.type.toLowerCase() == 'change') {
selectBox = this;
}
if (callbackWhenFinished === undefined) {
@ -303,7 +303,7 @@ Reporting.Filters = {
{
asynchronous: true,
evalScripts: true,
postBody: Form.serialize('query_form'),
postBody: Reporting.Controls.serialize_settings_form(),
onSuccess: function (response) {
Reporting.clearFlash();
if (response.responseJSON !== undefined) {

@ -2,60 +2,179 @@
/*global window, $, $$, Reporting, Effect, Ajax, selectAllOptions, moveOptions, moveOptionUp, moveOptionDown */
Reporting.GroupBys = {
attach_move_button: function (direction) {
var btn = $$(".buttons.group_by.move.move" + direction)[0];
group_by_container_ids: function() {
return $w('group_by_columns group_by_rows');
},
var axis;
if (direction === "Up" || direction === "Down") {
axis = "columns";
} else if (direction === "Left" || direction === "Right") {
axis = "rows";
}
sortable_options: function() {
return {
tag: 'span',
only: "drag_element",
overlap: 'horizontal',
constraint:'horizontal',
containment: Reporting.GroupBys.group_by_container_ids(),
dropOnEmpty: true,
hoverclass: 'drag_container_accept',
onUpdate: Reporting.GroupBys.ordering_changed
};
},
var selected_container = $(btn.form).select("#group_by_" + axis)[0];
var group_by_container = btn.form.group_by_container;
ordering_changed: function(container) {
container.select('.group_by_element').each(function(group_by) {
Reporting.GroupBys.update_arrow(group_by);
});
},
var source_container, target_container;
if (direction === "Down" || direction === "Right") {
source_container = selected_container;
target_container = group_by_container;
} else if (direction === "Up" || direction === "Left") {
target_container = selected_container;
source_container = group_by_container;
recreate_sortables: function() {
Reporting.GroupBys.group_by_container_ids().each(function(id) {
Sortable.create(id, Reporting.GroupBys.sortable_options());
});
},
initialize_drag_and_drop_areas: function() {
Reporting.GroupBys.recreate_sortables();
},
create_group_by: function(field) {
var group_by = new Element('span', {
'class': 'in_row drag_element group_by_element',
'data-group-by': field
});
group_by.identify(); // give it a unique id
return group_by;
},
group_by_hover_effect: function(event, do_hover) {
var group_by = $(Event.element(event));
// we possibly hit a tag inside the group_by, so go search the group_by then
if (!group_by.hasClassName('group_by_element')) {
group_by = group_by.up('.group_by_element');
}
if (group_by !== null) {
Reporting.GroupBys.group_by_hover(group_by, do_hover);
}
},
btn.observe("click", function () {
moveOptions(source_container, target_container);
// on mouse_over of a group_by or it's label, change the color of the group_by
// also change the color of the arrows
init_group_by_hover_effects: function(elements) {
elements.each(function(element) {
['mouseover', 'mouseout'].each(function(event_type) {
element.observe(event_type, function(event) {
Reporting.GroupBys.group_by_hover_effect(event, event_type == 'mouseover');
});
});
});
},
attach_sort_button: function (direction, axis) {
var btn = $$(".buttons.group_by.sort.sort" + direction + ".sort-" + axis)[0];
var box = $(btn.form).select("#group_by_" + axis)[0];
btn.observe("click", function () {
if (direction === "Up") {
moveOptionUp(box);
} else {
moveOptionDown(box);
}
create_label: function(group_by, text) {
return new Element('label', {
'class': 'in_row group_by_label',
'for': group_by.identify(),
'id': group_by.identify() + '_label'
}).update(text);
},
adding_group_by_enabled: function(field, state) {
$w('add_group_by_columns add_group_by_rows').each(function(container_id) {
Reporting.Filters.select_option_enabled($(container_id), field, state);
});
},
clear: function () {
['group_by_columns', 'group_by_rows'].each(function (type) {
selectAllOptions(type);
moveOptions(type, 'group_by_container');
arrow_removal_hover: function(arrow, status) {
if (status) {
$(arrow).addClassName('arrow_removal_hover');
}
else {
$(arrow).removeClassName('arrow_removal_hover');
}
},
group_by_hover: function(group_by, state) {
var arrow, previous_groups_arrow;
arrow = $(group_by.identify() + '_arrow');
previous_groups_arrow = $(group_by.previous().identify() + '_arrow');
if (Reporting.GroupBys.is_last(group_by)) {
state ? arrow.addClassName('hover') : arrow.removeClassName('hover');
} else {
state ? arrow.addClassName('hover_left') : arrow.removeClassName('hover_left');
}
if (!Reporting.GroupBys.is_first(group_by)) {
state ? previous_groups_arrow.addClassName('hover_right') : previous_groups_arrow.removeClassName('hover_right');
}
},
remove_group_by: function(group_by) {
var previous_group = group_by.previous();
Reporting.GroupBys.adding_group_by_enabled(group_by.readAttribute('data-group-by'), true);
group_by.remove();
if (previous_group !== null && previous_group.hasClassName('group_by_element')) {
Reporting.GroupBys.update_arrow(previous_group);
}
},
init_arrow: function(group_by) {
var arrow = new Element('span', {
'class': 'arrow in_row arrow_left',
'id': group_by.identify() + '_arrow'
});
//initialize callbacks for hover-effects and removal of group_by
arrow.observe('mouseover', function() { Reporting.GroupBys.arrow_removal_hover(arrow, true) });
arrow.observe('mouseout', function() { Reporting.GroupBys.arrow_removal_hover(arrow, false) });
arrow.observe('mousedown', function() { Reporting.GroupBys.remove_group_by(arrow.up('.group_by_element')) });
return arrow;
},
// returns true if the given group is the first group in its container
is_first: function(group_by) {
return (($(group_by).previous() == null) || (!($(group_by).previous().className.include('group_by'))));
},
// returns true if the given group is the last group in its container
is_last: function(group_by) {
return (($(group_by).next() == null) || (!($(group_by).next().className.include('group_by'))));
},
update_arrow: function(group_by) {
if (Reporting.GroupBys.is_last(group_by)) {
$(group_by.identify() + "_arrow").className = "arrow in_row arrow_left";
} else {
$(group_by.identify() + "_arrow").className = "arrow in_row arrow_both";
}
},
add_group_by_from_select: function(select) {
var field, caption, container, selected_option;
field = $(select).getValue();
container = select.up('.drag_container');
selected_option = select.select("[value='" + field + "']").first();
caption = selected_option.readAttribute('data-label');
Reporting.GroupBys.add_group_by(field, caption, container);
select.select("[value='']").first().selected = true;
},
add_group_by: function(field, caption, container) {
var group_by, label;
group_by = Reporting.GroupBys.create_group_by(field);
container.appendChild(group_by);
label = Reporting.GroupBys.create_label(group_by, caption);
Reporting.GroupBys.init_group_by_hover_effects([group_by, label]);
group_by.appendChild(label);
group_by.appendChild(Reporting.GroupBys.init_arrow(group_by));
if (!(Reporting.GroupBys.is_first(group_by))) {
Reporting.GroupBys.update_arrow(group_by.previous());
}
Reporting.GroupBys.adding_group_by_enabled(field, false);
Reporting.GroupBys.recreate_sortables();
}
};
Reporting.onload(function () {
["Left", "Right", "Up", "Down"].each(function (dir) {
Reporting.GroupBys.attach_move_button(dir);
Reporting.GroupBys.initialize_drag_and_drop_areas();
$('add_group_by_rows').observe("change", function () {
Reporting.GroupBys.add_group_by_from_select(this);
});
["Up", "Down"].each(function (dir) {
["rows", "columns"].each(function (axis) {
Reporting.GroupBys.attach_sort_button(dir, axis);
});
$('add_group_by_columns').observe("change", function () {
Reporting.GroupBys.add_group_by_from_select(this);
});
});

@ -27,27 +27,6 @@ Reporting.RestoreQuery = {
}
},
show_group_by: function (group_by, target) {
$('group_by_container').select("");
var source, group_option, i;
source = $("group_by_container");
group_option = null;
// find group_by option-tag in target select-box
for (i = 0; i < source.options.length; i += 1) {
if (source.options[i].value === group_by) {
group_option = source.options[i];
source.options[i] = null;
break;
}
}
// die if the appropriate option-tag can not be found
if (group_option === null) {
return;
}
// move the option-tag to the taget select-box while keepings its data
target.options[target.length] = group_option;
},
// This is called the first time the report loads.
// Params:
// elements: Array of visible filter-select-boxes that have dependents
@ -59,7 +38,7 @@ Reporting.RestoreQuery = {
// Filters which are <<inactive>> are probably dependents themselfes, so remove and forget them for now.
// This is OK as they get reloaded later
dependent_filters.each(function(select) {
Reporting.Filters.remove_filter(select.up('tr').getAttribute("data-filter-name"));
Reporting.Filters.remove_filter(select.up('tr').readAttribute("data-filter-name"));
});
// For each dependent filter we reload its dependent chain
filters_to_load.each(function(selectBox) {
@ -70,9 +49,9 @@ Reporting.RestoreQuery = {
});
sources.each(function(source) {
if (source.hasAttribute('data-initially-selected')) {
selected_values = source.getAttribute('data-initially-selected').replace(/'/g, '"').evalJSON(true);
selected_values = source.readAttribute('data-initially-selected').replace(/'/g, '"').evalJSON(true);
Reporting.Filters.select_values(source, selected_values);
Reporting.Filters.value_changed(source.up('tr').getAttribute("data-filter-name"));
Reporting.Filters.value_changed(source.up('tr').readAttribute("data-filter-name"));
}
});
if (sources.reject( function (select) { return select.value == '<<inactive>>' }).size() == 0) {
@ -85,20 +64,6 @@ Reporting.RestoreQuery = {
});
},
restore_group_bys: function () {
// Activate recent group_bys on loading
$('group_by_container').select("option")
.select(function (group_by) {
return $(group_by).hasAttribute("data-selected-axis");
}).sortBy(function (group_by) {
return $(group_by).getAttribute("data-selected-index");
}).each(function (group_by) {
var axis = $(group_by).getAttribute("data-selected-axis");
var name = $(group_by).getAttribute("value");
Reporting.RestoreQuery.show_group_by(name, $('group_by_' + axis + 's'));
});
},
restore_filters: function () {
// FIXME: rm_xxx values for filters have to be set after re-displaying them
$$("tr[data-selected=true]").each(function (e) {
@ -111,6 +76,22 @@ Reporting.RestoreQuery = {
Reporting.RestoreQuery.initialize_load_dependent_filters($$('.filters-select[data-dependents]').findAll(function(select) {
return select.up('tr').visible()
}));
},
restore_group_bys: function () {
Reporting.GroupBys.group_by_container_ids().each(function(id) {
var container, selected_groups;
container = $(id);
if (container.hasAttribute('data-initially-selected')) {
selected_groups = container.readAttribute('data-initially-selected').replace(/'/g, '"').evalJSON(true);
selected_groups.each(function(group_and_label) {
var group, label;
group = group_and_label[0];
label = group_and_label[1];
Reporting.GroupBys.add_group_by(group, label, container);
});
}
});
}
};

@ -1,151 +0,0 @@
var NS4 = (navigator.appName === "Netscape" && parseInt(navigator.appVersion, 10) < 5);
function createOption(theText, theValue, theCategory) {
var newOpt = document.createElement('option');
newOpt.text = theText;
newOpt.value = theValue;
newOpt.setAttribute("data-category", theCategory);
return newOpt;
}
function addOption(theSel, newOpt)
{
var theCategory, opt_groups, i;
theCategory = newOpt.getAttribute("data-category");
theSel = $(theSel);
if (theCategory && (theSel.childElements().length > 0) && theSel.down(0).tagName === "OPTGROUP") { // add the opt to the given category
opt_groups = theSel.childElements();
for (i = 0; i < opt_groups.length; i += 1) {
if (opt_groups[i].getAttribute("data-category") === theCategory) {
opt_groups[i].appendChild(newOpt);
break;
}
}
}
else { // no category given, just add the opt to the end of the select list
theSel.appendChild(newOpt);
}
}
function swapOptions(theSel, index1, index2)
{
theSel = $(theSel);
var text, value, category;
text = theSel.options[index1].text;
value = theSel.options[index1].value;
category = theSel.options[index1].getAttribute("data-category");
theSel.options[index1].text = theSel.options[index2].text;
theSel.options[index1].value = theSel.options[index2].value;
theSel.options[index1].setAttribute("data-category", theSel.options[index2].getAttribute("data-category"));
theSel.options[index2].text = text;
theSel.options[index2].value = value;
theSel.options[index2].setAttribute("data-category", category);
}
function deleteOption(theSel, theIndex)
{
theSel = $(theSel);
var selLength = theSel.length;
if (selLength > 0)
{
theSel.options[theIndex] = null;
}
}
// Returns true if the given select-box has optgroups.
// We assume that a possibly present optgroup is the first child element of the select-box.
function has_optgroups(theSel) {
theSel = $(theSel);
return (theSel.childElements().length > 0) && (theSel.down(0).tagName === "OPTGROUP");
}
// Compares two option elements (return -1 if a < b, if not return 1).
// If those elements have a 'data-sort_by' attribute, we compare that attribute.
// If this is not the case we just compare their labels.
function compareOptions(a, b) {
var a_cmp, b_cmp;
a_cmp = a.getAttribute("data-sort_by") ? a.getAttribute("data-sort_by") : a.text.toLowerCase();
b_cmp = b.getAttribute("data-sort_by") ? b.getAttribute("data-sort_by") : b.text.toLowerCase();
return (a_cmp < b_cmp) ? -1 : 1;
}
// Sorts all elements of the given select-box.
// If that select-box contains optgroups, the options are sorted for each optgroup separately.
function sortOptions(theSel) {
theSel = $(theSel);
if (has_optgroups(theSel)) {
// handle each optgroup separately
theSel.childElements().each(function (group) {
var sorted_elements;
// get all elements of this optgroup and sort them
sorted_elements = $A(group.childElements()).sort(compareOptions);
// make optgroup empty
$A(group.childElements()).each(function (o) {
$(o).remove();
});
// insert sorted elements into opgroup
sorted_elements.each(function (o) {
$(group).insert({'bottom' : o});
});
});
}
else {
// there is no optgroup, so just sort the options
$A(theSel.options).sort(compareOptions).each(function (o, i) {
theSel.options[i] = o;
});
}
}
function moveOptions(theSelFrom, theSelTo)
{
var selLength, selectedText, selectedValues, selectedCategories, selectedCount, i;
theSelFrom = $(theSelFrom);
theSelTo = $(theSelTo);
selLength = theSelFrom.length;
selectedText = [];
selectedValues = [];
selectedCategories = [];
selectedCount = 0;
for (i = selLength - 1; i >= 0; i -= 1) {
if (theSelFrom.options[i].selected)
{
addOption(theSelTo, theSelFrom.options[i].cloneNode(true));
deleteOption(theSelFrom, i);
}
}
if (has_optgroups(theSelTo)) {
sortOptions(theSelTo);
}
if (NS4) {
history.go(0);
}
}
function moveOptionUp(theSel) {
theSel = $(theSel);
var index = theSel.selectedIndex;
if (index > 0) {
swapOptions(theSel, index - 1, index);
theSel.selectedIndex = index - 1;
}
}
function moveOptionDown(theSel) {
theSel = $(theSel);
var index = theSel.selectedIndex;
if (index < theSel.length - 1) {
swapOptions(theSel, index, index + 1);
theSel.selectedIndex = index + 1;
}
}
function selectAllOptions(select)
{
select = $(select);
for (var i = 0; i < select.options.length; i += 1) {
select.options[i].selected = true;
}
}

@ -117,65 +117,6 @@
border: none;
}
.group_by {
background-color: transparent;
background-position: 50%;
background-repeat: no-repeat;
border: 1px solid #900;
height: 10px;
width: 10px;
margin: 1px;
}
.group_by:hover {
background-color: #EEE;
}
.move {
height: 25px;
width: 25px;
}
.sort {
height: 15px;
width: 15px;
}
.moveUp {
margin-top: 0px;
margin-bottom: 0px;
background-image: url(../images/arrow_D_up.gif);
}
.moveDown {
margin-top: 0px;
margin-bottom: 0px;
background-image: url(../images/arrow_D_down.gif);
}
.moveLeft {
margin-left: 0px;
margin-right: 0px;
background-image: url(../images/arrow_D_left.gif);
}
.moveRight {
margin-left: 0px;
margin-right: 0px;
background-image: url(../images/arrow_D_right.gif);
}
.sortUp {
margin-left: 0px;
margin-right: 0px;
background-image: url(../images/arrow_B_up.gif);
}
.sortDown {
margin-left: 0px;
margin-right: 0px;
background-image: url(../images/arrow_B_down.gif);
}
.remove-box {
height: 20px;
width: 20px;
@ -264,10 +205,7 @@ fieldset#filter-settings table td > label {
position: relative;
}
.drag_element {
/*cursor: move;*/
}
/* ----- group by --- */
.in_row {
float: left;
display: block;
@ -285,6 +223,16 @@ fieldset#filter-settings table td > label {
color: #fff;
}
.group_by_element {
background-color: #3F9ED7;
background-position: 50%;
background-repeat: no-repeat;
}
.group_by_element:hover {
background-color: #398AD3;
}
.arrow {
background-repeat: no-repeat;
height: 19px !important;
@ -295,31 +243,31 @@ fieldset#filter-settings table td > label {
}
.arrow_both {
background-image: url(../images/arrow_both.png);
background-image: url(../images/group_by_arrow_both.png);
}
.arrow_both_hover_left {
background-image: url(../images/arrow_both_hover_left.png);
.arrow_both.arrow_removal_hover {
background-image: url(../images/group_by_arrow_both_remove.png) !important;
}
.arrow_both_remove {
background-image: url(../images/arrow_both_remove.png);
.arrow_both.hover_left {
background-image: url(../images/group_by_arrow_both_hover_left.png);
}
.arrow_both_hover_right {
background-image: url(../images/arrow_both_hover_right.png);
.arrow_both.hover_right {
background-image: url(../images/group_by_arrow_both_hover_right.png);
}
.arrow_left {
background-image: url(../images/arrow_left.png);
background-image: url(../images/group_by_arrow_left.png);
}
.arrow_left_remove {
background-image: url(../images/arrow_left_remove.png);
.arrow_left.arrow_removal_hover {
background-image: url(../images/group_by_arrow_left_remove.png) !important;
}
.arrow_left_hover {
background-image: url(../images/arrow_left_hover.png);
.arrow_left.hover {
background-image: url(../images/group_by_arrow_left_hover.png);
}
.drag_container {
@ -344,6 +292,8 @@ fieldset#filter-settings table td > label {
/*border: 1px solid #BBBBBB;*/
}
/* -- end group-by -- */
td .drill_down, th .drill_down {
font-size: 8px;
display: block;

@ -107,8 +107,8 @@ class Report < ActiveRecord::Base
@table = self.class::Table.new(self)
end
def group_bys
chain.select { |c| c.group_by? }
def group_bys(type=nil)
chain.select { |c| c.group_by? && (type.nil? || c.type == type) }
end
def filters

@ -1,114 +1,46 @@
class Widget::GroupBys < Widget::Base
extend ProactiveAutoloader
def render_row_1_with_columns
content_tag :tr do
tr = content_tag :td, " ", :colspan => "2"
tr += content_tag :td, :align => "center", :valign => "right" do
render_up_down_buttons("columns")
end
tr += content_tag :td, :valign => "middle" do
content_tag(:h3, "Columns") + selected_group_bys("columns")
def render_options(group_by_ary)
group_by_ary.sort_by do |group_by|
l(group_by.label)
end.collect do |group_by|
next unless group_by.selectable?
content_tag :option, :value => group_by.underscore_name, :'data-label' => "#{l(group_by.label)}" do
l(group_by.label)
end
end
end.join.html_safe
end
def render_row_2_with_up_down
content_tag :tr do
tr = content_tag :td, " "
tr += content_tag :td, :valign => "bottom", :style => "padding-bottom: 0;" do
content_tag :h3, "Rows"
end
tr += content_tag :td, " "
tr += content_tag :td, :align => "left", :valign => "left" do
render_move_buttons("columns", "Up", "Down")
end
def render_group(type, initially_selected)
initially_selected = initially_selected.map do |group_by|
[group_by.class.underscore_name, l(group_by.class.label)]
end
end
def render_row_3_with_rows_and_group_bys
content_tag :tr do
tr = content_tag :td, :align => "center", :valign => "top" do
render_up_down_buttons("rows")
end
tr += content_tag :td ,:style => "padding-left: 0pt;", :valign => "top" do
selected_group_bys("rows")
end
tr += content_tag :td, :align => "center", :valign => "top" do
render_move_buttons("rows", "Left", "Right", true)
end
tr += content_tag :td do
render_grouped_group_bys
end
content_tag :div,
:id => "group_by_#{type}",
:class => 'drag_target drag_container',
:'data-initially-selected' => initially_selected.to_json.gsub('"', "'") do
content_tag :select, :id => "add_group_by_#{type}", :class => 'select-small' do
content = tag :option, :value => ''
content += engine::GroupBy.all_grouped.sort_by do |label, group_by_ary|
l(label)
end.collect do |label, group_by_ary|
content_tag :optgroup, :label => l(label) do
render_options group_by_ary
end
end.join.html_safe
content
end.html_safe
end
end
#TODO: replace me with a drag&drop group_by selector
def render
content_tag :div do
content_tag :table, :style => "border-collapse: collapse; border: 0pt none;",
:id => "group_by_table" do
content_tag :tbody do
render_row_1_with_columns +
render_row_2_with_up_down +
render_row_3_with_rows_and_group_bys
end
end
end
end
def selected_group_bys(axis)
content_tag :select, "", :style => "width: 180px;", :size => "4",
:name => "groups[#{axis}][]", :multiple => "multiple",
:id => "group_by_#{axis}"
end
def render_up_down_buttons(axis)
render_sort_button(axis, "Up") + tag(:br) + render_sort_button(axis, "Down")
end
def render_sort_button(axis, dir)
tag :input, :type => "button", :class => "buttons group_by sort sort#{dir} sort-#{axis}"
end
def render_move_buttons(axis, to, from, br = false)
canvas = render_move_option_button(axis, to)
canvas += tag(:br) if br
canvas + render_move_option_button(axis, from)
end
def render_move_option_button(axis, dir)
tag :input, :type => "button", :class => "buttons group_by move move#{dir}"
end
def render_grouped_group_bys
content_tag :select, :style => "width: 180px;", :size => "9", :multiple => "multiple", :id => "group_by_container" do
engine::GroupBy.all_grouped.sort_by do |label, group_by_ary|
l(label)
end.collect do |label, group_by_ary|
content_tag :optgroup, :label => l(label), :"data-category" => label.to_s do
render_group_bys_for(group_by_ary, label)
end
end.join.html_safe
end
end
def render_group_bys_for(group_by_ary, label)
group_by_ary.sort_by do |g|
l(g.label)
end.collect do |group_by|
next unless group_by.selectable?
render_group_by(group_by, :value => group_by.underscore_name, :"data-category" => label.to_s)
end.compact.join.html_safe
end
def render_group_by(group_by, option_tag_options)
if grby = @query.group_bys.detect {|g| g.class == group_by }
option_tag_options[:"data-selected-axis"] = grby.type.to_s
option_tag_options[:"data-selected-index"] = @query.group_bys.index(grby)
end
content_tag :option, option_tag_options do
l(group_by.label)
content_tag :div, :id => 'group_by_area' do
out = l(:label_columns)
out += render_group 'columns', @query.group_bys(:column)
out += l(:label_rows)
out += render_group 'rows', @query.group_bys(:row)
out.html_safe
end
end
end

@ -0,0 +1,114 @@
class Widget::OldGroupBys < Widget::Base
extend ProactiveAutoloader
def render_row_1_with_columns
content_tag :tr do
tr = content_tag :td, " ", :colspan => "2"
tr += content_tag :td, :align => "center", :valign => "right" do
render_up_down_buttons("columns")
end
tr += content_tag :td, :valign => "middle" do
content_tag(:h3, "Columns") + selected_group_bys("columns")
end
end
end
def render_row_2_with_up_down
content_tag :tr do
tr = content_tag :td, " "
tr += content_tag :td, :valign => "bottom", :style => "padding-bottom: 0;" do
content_tag :h3, "Rows"
end
tr += content_tag :td, " "
tr += content_tag :td, :align => "left", :valign => "left" do
render_move_buttons("columns", "Up", "Down")
end
end
end
def render_row_3_with_rows_and_group_bys
content_tag :tr do
tr = content_tag :td, :align => "center", :valign => "top" do
render_up_down_buttons("rows")
end
tr += content_tag :td ,:style => "padding-left: 0pt;", :valign => "top" do
selected_group_bys("rows")
end
tr += content_tag :td, :align => "center", :valign => "top" do
render_move_buttons("rows", "Left", "Right", true)
end
tr += content_tag :td do
render_grouped_group_bys
end
end
end
#TODO: replace me with a drag&drop group_by selector
def render
content_tag :div do
content_tag :table, :style => "border-collapse: collapse; border: 0pt none;",
:id => "group_by_table" do
content_tag :tbody do
render_row_1_with_columns +
render_row_2_with_up_down +
render_row_3_with_rows_and_group_bys
end
end
end
end
def selected_group_bys(axis)
content_tag :select, "", :style => "width: 180px;", :size => "4",
:name => "groups[#{axis}][]", :multiple => "multiple",
:id => "group_by_#{axis}"
end
def render_up_down_buttons(axis)
render_sort_button(axis, "Up") + tag(:br) + render_sort_button(axis, "Down")
end
def render_sort_button(axis, dir)
tag :input, :type => "button", :class => "buttons group_by sort sort#{dir} sort-#{axis}"
end
def render_move_buttons(axis, to, from, br = false)
canvas = render_move_option_button(axis, to)
canvas += tag(:br) if br
canvas + render_move_option_button(axis, from)
end
def render_move_option_button(axis, dir)
tag :input, :type => "button", :class => "buttons group_by move move#{dir}"
end
def render_grouped_group_bys
content_tag :select, :style => "width: 180px;", :size => "9", :multiple => "multiple", :id => "group_by_container" do
engine::GroupBy.all_grouped.sort_by do |label, group_by_ary|
l(label)
end.collect do |label, group_by_ary|
content_tag :optgroup, :label => l(label), :"data-category" => label.to_s do
render_group_bys_for(group_by_ary, label)
end
end.join.html_safe
end
end
def render_group_bys_for(group_by_ary, label)
group_by_ary.sort_by do |g|
l(g.label)
end.collect do |group_by|
next unless group_by.selectable?
render_group_by(group_by, :value => group_by.underscore_name, :"data-category" => label.to_s)
end.compact.join.html_safe
end
def render_group_by(group_by, option_tag_options)
if grby = @query.group_bys.detect {|g| g.class == group_by }
option_tag_options[:"data-selected-axis"] = grby.type.to_s
option_tag_options[:"data-selected-index"] = @query.group_bys.index(grby)
end
content_tag :option, option_tag_options do
l(group_by.label)
end
end
end
Loading…
Cancel
Save