MT#5435 option to show table summaries

showing any supported aggregation method

Change-Id: If439731261cb148105f4c1fb9608839610935e75
changes/69/969/5
Gerhard Jungwirth 11 years ago
parent 21941e3924
commit 1c7fb3a781

@ -70,7 +70,7 @@ __PACKAGE__->config(
'View::JSON' => {
#Set the stash keys to be exposed to a JSON response
#(sEcho iTotalRecords iTotalDisplayRecords aaData) for datatables
expose_stash => [ qw(sEcho iTotalRecords iTotalDisplayRecords aaData) ],
expose_stash => [ qw(sEcho iTotalRecords iTotalDisplayRecords aaData dt_custom_footer) ],
},
'View::TT' => {
INCLUDE_PATH => [

@ -2048,14 +2048,14 @@ sub master :Chained('base') :PathPart('details') :CaptureArgs(0) {
{ name => "destination_user", search => 1, title => $c->loc('Callee') },
{ name => "call_status", search => 1, title => $c->loc('Status') },
{ name => "start_time", search_from_epoch => 1, search_to_epoch => 1, title => $c->loc('Start Time') },
{ name => "duration", search => 1, title => $c->loc('Duration') },
{ name => "duration", search => 1, title => $c->loc('Duration'), show_total => 'sum' },
];
push @{ $call_cols }, (
{ name => "call_id", search => 1, title => $c->loc('Call-ID') },
) if($c->user->roles eq "admin" || $c->user->roles eq "reseller");
push @{ $call_cols }, (
{ name => "source_customer_cost", search => 1, title => $c->loc('Source Cust Cost (cents)') },
{ name => "source_customer_cost", search => 1, title => $c->loc('Source Cust Cost (cents)'), show_total => 'sum' },
) ;
$c->stash->{calls_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, $call_cols);
@ -3043,7 +3043,7 @@ sub ajax_calls :Chained('master') :PathPart('calls/ajax') :Args(0) {
$data{destination_user} = uri_unescape($result->destination_user);
}
return %data;
}
},
);
$c->detach( $c->view("JSON") );

@ -13,6 +13,8 @@ sub process {
my $use_rs_cb = ('CODE' eq (ref $rs));
my $aaData = [];
my $displayRecords = 0;
my $aggregate_cols = {};
my $aggregations = {};
# check if we need to join more tables
@ -20,6 +22,9 @@ sub process {
set_columns($c, $cols);
unless ($use_rs_cb) {
for my $col(@{ $cols }) {
if ($col->{show_total}) {
$aggregate_cols->{$col->{accessor}} = $col->{show_total};
}
my @parts = split /\./, $col->{name};
if($col->{literal_sql}) {
$rs = $rs->search_rs(undef, {
@ -92,6 +97,10 @@ sub process {
}
}
$displayRecords = $use_rs_cb ? 0 : $rs->count;
for my $sum_col (keys %{ $aggregate_cols }) {
my $aggregation_method = $aggregate_cols->{$sum_col};
$aggregations->{$sum_col} = $rs->get_column($sum_col)->$aggregation_method;
}
# show specific row on top (e.g. if we come back from a newly created entry)
my $topId = $c->request->params->{iIdOnTop};
@ -157,6 +166,9 @@ sub process {
}
}
if (keys %{ $aggregations }) {
$c->stash(dt_custom_footer => $aggregations);
}
$c->stash(
aaData => $aaData,
iTotalRecords => $totalRecords,
@ -262,6 +274,17 @@ NGCP::Panel::Utils::Datatables
=head1 DESCRIPTION
=head2 Format of Columns
Array with the following fields (preprocessed by set_columns):
name: String
search: Boolean
search_from_epoch: Boolean
search_to_epoch: Boolean
title: String (Should be localized)
show_total: String (if set, something like sum,max,...)
=head1 METHODS
=head2 C<process>

@ -206,6 +206,21 @@ table.ngcp-datatable .header {
cursor: pointer;
}
/* tfoot styles from application header styles */
table.ngcp-datatable tfoot td {
color: #FFF;
border-right: 1px solid #3E662C;
border-left: 1px solid #77B75A;
box-shadow: 0px 1px 0px #95C77D inset;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}
table.ngcp-datatable tfoot tr {
background-color: #568D3D;
background-image: linear-gradient(to bottom, #5F9B43, #497734);
background-repeat: repeat-x;
}
table.ngcp-datatable .header:after {
content: "";
float: right;

@ -32,6 +32,7 @@ $.extend( $.fn.dataTableExt.oStdClasses, {
$(document).ready(function() {
var date_search_rendered = 0;
var [% helper.id_from_name %]_tmp_footer;
var [% helper.id_from_name %]_table = $('#[% helper.id_from_name %]_table')
.dataTable( {
"sDom": "<'row-fluid ngcp_dt_top_elements'lf<r>>t<'row-fluid'<'pull-left'i><'pull-right'p>>",
@ -128,6 +129,31 @@ $(document).ready(function() {
"sClass": "ngcp-actions-column"
}
],
"fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
oSettings.jqXHR = $.ajax( {
"dataType": 'json',
"url": sSource,
"data": aoData,
"success": function(data, textStatus, jqXHR) {
if (data.dt_custom_footer) {
[% helper.id_from_name %]_tmp_footer = data.dt_custom_footer;
}
fnCallback(data, textStatus, jqXHR);
}
} );
},
[% IF helper.show_footer -%]
"fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) {
if ([% helper.id_from_name %]_tmp_footer) {
nFoot.getElementsByTagName('td')[0].innerHTML = '[% c.loc("Total") %]';
for (var col in [% helper.id_from_name %]_tmp_footer) {
if ([% helper.id_from_name %]_tmp_footer.hasOwnProperty(col)) {
nFoot.getElementsByClassName('footer-'+col)[0].innerHTML = [% helper.id_from_name %]_tmp_footer[col];
}
}
}
},
[% END -%]
"fnDrawCallback": function( oSettings ) {
$('.sw_actions').css('visibility','hidden');
$('.sw_action_row').hover(
@ -231,6 +257,16 @@ $(document).ready(function() {
<th class="ngcp-actions-column"></th>
</tr>
</thead>
[% IF helper.show_footer -%]
<tfoot>
<tr>
[% FOREACH f IN helper.column_fields -%]
<td class="footer-[% f %]"></td>
[% END -%]
<td></td>
</tr>
</tfoot>
[% END -%]
<tbody>
<tr class="sw_action_row">
<td colspan="[% helper.column_titles.size + 1 %]">[% c.loc('Loading...') %]</td>
@ -252,5 +288,8 @@ $(document).ready(function() {
modal_script(m.close_target = helper.close_target);
-%]
[% END -%]
[% # cleanup
helper.show_footer = 0;
-%]
[% # vim: set tabstop=4 syntax=html expandtab: -%]

@ -177,6 +177,7 @@
helper.column_sort = 'start_time';
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/subscriber/ajax_calls', [c.req.captures.0]);
helper.show_footer = 1;
IF (c.user.roles == "admin" || c.user.roles == "reseller") && c.config.features.callflow;
helper.dt_buttons = [

Loading…
Cancel
Save