User Reports via config, without requiring HTML or Perl
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
2.024001 -
|
2.024002 - 2014-02-27
|
||||||
|
|
||||||
|
[NEW FEATURES]
|
||||||
|
|
||||||
|
* User Reports via config, without requiring HTML or Perl
|
||||||
|
|
||||||
|
2.024001 - 2014-02-25
|
||||||
|
|
||||||
[BUG FIXES]
|
[BUG FIXES]
|
||||||
|
|
||||||
|
|||||||
13
Netdisco/lib/App/Netdisco/DB/Result/Virtual/GenericReport.pm
Normal file
13
Netdisco/lib/App/Netdisco/DB/Result/Virtual/GenericReport.pm
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package App::Netdisco::DB::Result::Virtual::GenericReport;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use base 'DBIx::Class::Core';
|
||||||
|
|
||||||
|
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||||
|
__PACKAGE__->table("generic_report");
|
||||||
|
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||||
|
__PACKAGE__->result_source_instance->view_definition(q{});
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -222,6 +222,50 @@ Value: List of Modules. Default: Empty List.
|
|||||||
List of additional L<App::Netdisco::Web::Plugin> names to load. See also the
|
List of additional L<App::Netdisco::Web::Plugin> names to load. See also the
|
||||||
C<web_plugins> setting.
|
C<web_plugins> setting.
|
||||||
|
|
||||||
|
=head3 C<reports>
|
||||||
|
|
||||||
|
Value: Dictionary of Reports Hashes. Default: None.
|
||||||
|
|
||||||
|
Use this configuration to add reports to Netdisco without writing any Perl
|
||||||
|
code or HTML templates. For example:
|
||||||
|
|
||||||
|
reports:
|
||||||
|
power_inventory:
|
||||||
|
category: Device
|
||||||
|
label: 'Power Supply Inventory'
|
||||||
|
columns:
|
||||||
|
- {name: 'Name'}
|
||||||
|
- {ps1_type: 'PS1 Type'}
|
||||||
|
- {ps1_status: 'PS1 Status'}
|
||||||
|
query: |
|
||||||
|
SELECT d.name, d.ps1_type, d.ps1_status
|
||||||
|
FROM device d
|
||||||
|
ORDER BY name
|
||||||
|
|
||||||
|
Each key of the C<reports> configuration is an alias for the report, and
|
||||||
|
becomes part of the web path. Within the tree you must provide each of the
|
||||||
|
keys shown:
|
||||||
|
|
||||||
|
=head4 C<category>
|
||||||
|
|
||||||
|
Section of the Reports menu where this report will appear. See
|
||||||
|
L<WritingPlugins|App::Netdisco::Manual::WritingPlugins> for the full list.
|
||||||
|
|
||||||
|
=head4 C<label>
|
||||||
|
|
||||||
|
Title for the Report.
|
||||||
|
|
||||||
|
=head4 C<columns>
|
||||||
|
|
||||||
|
List of single-key Hashes which map database column (field) name to table
|
||||||
|
heading.
|
||||||
|
|
||||||
|
=head4 C<query>
|
||||||
|
|
||||||
|
SQL which returns the data. Make sure that the columns are named the same as
|
||||||
|
the keys of the C<columns> configuration. Note the way the SQL is specified in
|
||||||
|
the example above, using the pipe symbol and then indenting the query text.
|
||||||
|
|
||||||
=head3 C<jobqueue_refresh>
|
=head3 C<jobqueue_refresh>
|
||||||
|
|
||||||
Value: Integer Number. Default: 5.
|
Value: Integer Number. Default: 5.
|
||||||
|
|||||||
@@ -118,7 +118,11 @@ the name of the registration helper sub:
|
|||||||
=head1 Reports
|
=head1 Reports
|
||||||
|
|
||||||
Report components contain pre-canned searches which the user community have
|
Report components contain pre-canned searches which the user community have
|
||||||
found to be useful. The implementation is very similar to one of the Search
|
found to be useful. Before you go further, it might be the case that you can
|
||||||
|
generate the report without any Perl or HTML: see the L<Reports
|
||||||
|
Configuration|App::Netdisco::Manual::Configuration/reports> for details.
|
||||||
|
|
||||||
|
Otherwise, the typical implementation is very similar to one of the Search
|
||||||
and Device page Tabs, so please read that documentation above, first.
|
and Device page Tabs, so please read that documentation above, first.
|
||||||
|
|
||||||
Report plugins usually live in the C<App::Netdisco::Web::Plugin::Report>
|
Report plugins usually live in the C<App::Netdisco::Web::Plugin::Report>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use App::Netdisco::Web::TypeAhead;
|
|||||||
use App::Netdisco::Web::PortControl;
|
use App::Netdisco::Web::PortControl;
|
||||||
use App::Netdisco::Web::Statistics;
|
use App::Netdisco::Web::Statistics;
|
||||||
use App::Netdisco::Web::Password;
|
use App::Netdisco::Web::Password;
|
||||||
|
use App::Netdisco::Web::GenericReport;
|
||||||
|
|
||||||
sub _load_web_plugins {
|
sub _load_web_plugins {
|
||||||
my $plugin_list = shift;
|
my $plugin_list = shift;
|
||||||
|
|||||||
50
Netdisco/lib/App/Netdisco/Web/GenericReport.pm
Normal file
50
Netdisco/lib/App/Netdisco/Web/GenericReport.pm
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package App::Netdisco::Web::GenericReport;
|
||||||
|
|
||||||
|
use Dancer ':syntax';
|
||||||
|
use Dancer::Plugin::Ajax;
|
||||||
|
use Dancer::Plugin::DBIC;
|
||||||
|
use Dancer::Plugin::Auth::Extensible;
|
||||||
|
|
||||||
|
use App::Netdisco::Web::Plugin;
|
||||||
|
|
||||||
|
foreach my $r (keys %{setting('reports')}) {
|
||||||
|
my $report = setting('reports')->{$r};
|
||||||
|
|
||||||
|
register_report({
|
||||||
|
tag => $r,
|
||||||
|
label => $report->{label},
|
||||||
|
category => $report->{category},
|
||||||
|
provides_csv => true,
|
||||||
|
});
|
||||||
|
|
||||||
|
get "/ajax/content/report/$r" => require_login sub {
|
||||||
|
my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source;
|
||||||
|
|
||||||
|
# this should be done by creating a new Virtual Result class on the fly
|
||||||
|
# (package...) and then calling DBIC register_class on it.
|
||||||
|
$rs->view_definition($report->{query});
|
||||||
|
$rs->remove_columns($rs->columns);
|
||||||
|
$rs->add_columns(map {keys %{$_}} @{$report->{columns}});
|
||||||
|
|
||||||
|
my $set = schema('netdisco')->resultset('Virtual::GenericReport');
|
||||||
|
return unless $set->count;
|
||||||
|
|
||||||
|
if (request->is_ajax) {
|
||||||
|
template 'ajax/report/generic_report.tt',
|
||||||
|
{ results => $set,
|
||||||
|
headings => [map {values %{$_}} @{$report->{columns}}],
|
||||||
|
columns => [$rs->columns] },
|
||||||
|
{ layout => undef };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||||
|
template 'ajax/report/generic_report_csv.tt',
|
||||||
|
{ results => $set,
|
||||||
|
headings => [map {values %{$_}} @{$report->{columns}}],
|
||||||
|
columns => [$rs->columns] },
|
||||||
|
{ layout => undef };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
true;
|
||||||
@@ -55,7 +55,7 @@ safe_password_store: true
|
|||||||
# when: '20 23 * * *'
|
# when: '20 23 * * *'
|
||||||
|
|
||||||
# increase the performance of parallel DNS resolution for node
|
# increase the performance of parallel DNS resolution for node
|
||||||
# names (the default is max_outstanding: 10)
|
# names (the default is max_outstanding: 50)
|
||||||
# ````````````````````````````````````````````````````````````
|
# ````````````````````````````````````````````````````````````
|
||||||
#dns:
|
#dns:
|
||||||
# max_outstanding: 100
|
# max_outstanding: 100
|
||||||
|
|||||||
18
Netdisco/share/views/ajax/report/generic_report.tt
Normal file
18
Netdisco/share/views/ajax/report/generic_report.tt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<table class="table table-bordered table-condensed table-striped nd_floatinghead">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
[% FOREACH hdr IN headings %]
|
||||||
|
<th>[% hdr | html_entity %]</th>
|
||||||
|
[% END %]
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</tbody>
|
||||||
|
[% WHILE (row = results.next) %]
|
||||||
|
<tr>
|
||||||
|
[% FOREACH col IN columns %]
|
||||||
|
<td>[% row.get_column(col) | html_entity %]</td>
|
||||||
|
[% END %]
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
11
Netdisco/share/views/ajax/report/generic_report_csv.tt
Normal file
11
Netdisco/share/views/ajax/report/generic_report_csv.tt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[% USE CSV %]
|
||||||
|
[% CSV.dump(headings) %]
|
||||||
|
|
||||||
|
[% FOREACH row IN results.all %]
|
||||||
|
[% mylist = [] %]
|
||||||
|
[% FOREACH col IN columns %]
|
||||||
|
[% mylist.push(row.get_column(col)) %]
|
||||||
|
[% END %]
|
||||||
|
[% CSV.dump(mylist) %]
|
||||||
|
|
||||||
|
[% END %]
|
||||||
Reference in New Issue
Block a user