[Rt-commit] rt branch 5.0/dynamic-reports created. rt-5.0.4-7-g26b373e23c

BPS Git Server git at git.bestpractical.com
Mon May 15 20:09:20 UTC 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/dynamic-reports has been created
        at  26b373e23c3104ec8f00a4f1e621162b7c52d22d (commit)

- Log -----------------------------------------------------------------
commit 26b373e23c3104ec8f00a4f1e621162b7c52d22d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon May 15 22:09:53 2023 +0300

    Add RT::Interface::Web::ReportsRegistry package
    
    Allows plugin authors to register reports that can be added to
    the Reports menu in the UI.

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 444eb1c24e..0e474cd0d3 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -79,6 +79,7 @@ use Plack::Util;
 use HTTP::Status qw();
 use Regexp::Common;
 use RT::Shortener;
+use RT::Interface::Web::ReportsRegistry;
 
 our @SHORTENER_SEARCH_FIELDS
     = qw/Class ObjectType BaseQuery Query Format RowsPerPage Order OrderBy ExtraQueryParams ResultPage/;
@@ -5028,39 +5029,13 @@ sub UpdateDashboard {
 
 =head2 ListOfReports
 
-Returns the list of reports registered with RT.
+Returns the list of reports registered with RT. Alias for
+L<RT::Interface::Web::ReportsRegistry|Reports>.
 
 =cut
 
 sub ListOfReports {
-
-    # TODO: Make this a dynamic list generated by loading files in the Reports
-    # directory
-
-    my $list_of_reports = [
-        {
-            id          => 'resolvedbyowner',
-            title       => 'Resolved by owner', # loc
-            path        => '/Reports/ResolvedByOwner.html',
-        },
-        {
-            id          => 'resolvedindaterange',
-            title       => 'Resolved in date range', # loc
-            path        => '/Reports/ResolvedByDates.html',
-        },
-        {
-            id          => 'createdindaterange',
-            title       => 'Created in a date range', # loc
-            path        => '/Reports/CreatedByDates.html',
-        },
-        {
-            id          => 'user_time',
-            title       => 'User time worked',
-            path        => '/Reports/TimeWorkedReport.html',
-        },
-    ];
-
-    return $list_of_reports;
+    return RT::Interface::Web::ReportsRegistry->Reports();
 }
 
 =head2 ProcessCustomDateRanges ARGSRef => ARGSREF, UserPreference => 0|1
diff --git a/lib/RT/Interface/Web/ReportsRegistry.pm b/lib/RT/Interface/Web/ReportsRegistry.pm
new file mode 100644
index 0000000000..ba4394ae0d
--- /dev/null
+++ b/lib/RT/Interface/Web/ReportsRegistry.pm
@@ -0,0 +1,144 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC
+#                                          <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+use strict;
+use warnings;
+use 5.010;
+
+package RT::Interface::Web::ReportsRegistry;
+
+=head1 NAME
+
+    RT::Interface::Web::ReportsRegistry - helper functions for reports
+
+=cut
+
+our $registry = {
+    resolvedbyowner => {
+        id    => 'resolvedbyowner',
+        title => 'Resolved by owner',               # loc
+        path  => '/Reports/ResolvedByOwner.html',
+    },
+    resolvedindaterange => {
+        id    => 'resolvedindaterange',
+        title => 'Resolved in date range',          # loc
+        path  => '/Reports/ResolvedByDates.html',
+    },
+    createdindaterange => {
+        id    => 'createdindaterange',
+        title => 'Created in a date range',         # loc
+        path  => '/Reports/CreatedByDates.html',
+    },
+    user_time => {
+        id    => 'user_time',
+        title => 'User time worked',
+        path  => '/Reports/TimeWorkedReport.html',
+    },
+};
+
+=head2 Reports
+
+Returns a list (array ref) of all registered reports. Reports are sorted by title.
+Every element is a hash ref with the following keys:
+
+=over 4
+
+=item id - unique string identifier
+
+=item title - human-readable title
+
+=item path - path to the report relative to the root
+
+=back
+
+=cut
+
+sub Reports {
+    my @res
+        = sort { lc( $a->{title} ) cmp lc( $b->{title} ) } values %$registry;
+    return \@res;
+}
+
+=head2 Register
+
+Registers a report that can be added to the Reports menu.
+
+    use RT::Interface::Web::ReportsRegistry;
+    RT::Interface::Web::ReportsRegistry->Register(
+        id    => 'my_super_report',
+        title => 'Super report',
+        path  => 'MySuperReport.html',
+    );
+
+All reports are expected to be in the /Reports/ directory.
+
+B<Note> that using existing id will overwrite the record in the registry.
+
+=cut
+
+sub Register {
+    my $self = shift;
+    my %args = (
+        id    => undef,
+        title => undef,
+        path  => undef,
+        @_
+    );
+    die "id is required" unless $args{id};
+
+    $registry->{ $args{id} } = {
+        id    => $args{id},
+        title => $args{title},
+        path  => '/Reports/' . $args{path},
+    };
+}
+
+require RT::Base;
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/t/web/reports_registry.t b/t/web/reports_registry.t
new file mode 100644
index 0000000000..bf435c94ce
--- /dev/null
+++ b/t/web/reports_registry.t
@@ -0,0 +1,62 @@
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+
+use RT::Interface::Web::ReportsRegistry;
+
+# make sure all reports are registered
+{
+    my $reports = RT::Interface::Web::ReportsRegistry->Reports;
+    my @paths   = sort { $a cmp $b } map { $_->{path} } @$reports;
+
+    my $reports_dir = 'share/html/Reports';
+    opendir my $dh, $reports_dir or die "Can't open dir $reports_dir: $!";
+    my @expected = sort { $a cmp $b }
+        map {"/Reports/$_"}
+        grep { -f "$reports_dir/$_" && !/index/ } readdir $dh;
+    closedir $dh;
+
+    is_deeply( \@paths, \@expected, 'all reports are registered' );
+}
+
+# register a report, second time should overwrite the record
+{
+    my $report = {
+        id    => 'my_super_report',
+        title => 'Super report',
+        path  => 'MySuperReport.html',
+    };
+    RT::Interface::Web::ReportsRegistry->Register(%$report);
+
+    my $expected = {
+        id    => 'my_super_report',
+        title => 'Super report',
+        path  => '/Reports/MySuperReport.html',
+    };
+    my $got = get_report_by_id( $report->{id} );
+    is_deeply( $got, $expected, 'report is registered' );
+
+    # overwrite the record
+    $report->{title} = 'Super-duper report';
+    RT::Interface::Web::ReportsRegistry->Register(%$report);
+
+    $got = get_report_by_id( $report->{id} );
+    $expected->{title} = 'Super-duper report';
+    is_deeply( $got, $expected, 'report is overwritten' );
+}
+
+# check ListOfReports in RT::Interface::Web
+{
+    require RT::Interface::Web;
+    my $reports1 = RT::Interface::Web::ReportsRegistry->Reports;
+    my $reports2 = HTML::Mason::Commands::ListOfReports();
+    is_deeply( $reports1, $reports2,
+        'ReportsRegistry->Reports == ListOfReports' );
+}
+
+sub get_report_by_id {
+    my $id      = shift;
+    my $reports = RT::Interface::Web::ReportsRegistry->Reports;
+    return ( grep { $_->{id} eq $id } @$reports )[0];
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list