[Rt-commit] rt branch, 5.0/self-service-homepage-dashboard, created. rt-5.0.0-10-g302c1daaeb
Dianne Skoll
dianne at bestpractical.com
Thu Sep 3 16:05:23 EDT 2020
The branch, 5.0/self-service-homepage-dashboard has been created
at 302c1daaeba370c9c48ddfa3440cfa279f8d387c (commit)
- Log -----------------------------------------------------------------
commit 302c1daaeba370c9c48ddfa3440cfa279f8d387c
Author: Dianne Skoll <dianne at bestpractical.com>
Date: Thu Sep 3 14:43:11 2020 -0400
Add ability to serve a custom dashboard as the SelfService home page.
You can enable the self-service home page dashboard in RT_SiteConfig.pm with:
Set( $SelfServiceUseDashboard, 1);
Note that you also need to give permissions for Everyone to see system
dashboards.
This code leverages the existing Dashboard infrastructure, but
adds tweaks to save the self-service home page as singleton entry
in the Attributes table, with the name "Selfservicedashboard"
I made as few changes to the core Dashboards code as possible to get
this to work; most of the work is done by RT::Dashboard::SelfService, a
derived class from RT::Dashboard that overrides just enough of the
database code to change the way the dashboard is loaded and stored.
I did have to make some minor changes to the core dashboard files
/Dashboards/Queries.html and lib/RT/Interface/Web.pm to get
them to operate properly with the new class.
/Dashboards/Queries.html is re-used almost as-is; an extra boolean
parameter "self_service_dashboard" indicates that we're working on the
self-service home page dashboard rather than a normal dashboard.
For rendering the self-service page, we first verify that the
self-service dashboard option is enabled, that the dashboard exists,
and that it can be loaded. If all those conditions are met, we pass
it to /Dashboards/Render.html which has similar minor modifications
as /Dashboards/Queries.html to handle the special-case of the self-service
page.
diff --git a/lib/RT/Dashboard/SelfService.pm b/lib/RT/Dashboard/SelfService.pm
new file mode 100644
index 0000000000..ca33c50432
--- /dev/null
+++ b/lib/RT/Dashboard/SelfService.pm
@@ -0,0 +1,101 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2020 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 }}}
+
+=head1 NAME
+
+ RT::Dashboard::SelfService - dashboard for the Self-Service Home Page
+
+=head1 SYNOPSIS
+
+ See RT::Dashboard
+
+=cut
+
+package RT::Dashboard::SelfService;
+
+use strict;
+use warnings;
+
+use base qw/RT::Dashboard/;
+
+=head2 ObjectName
+
+An object of this class is called "selfservicedashboard"
+
+=cut
+
+sub ObjectName { "selfservicedashboard" } # loc
+
+=head2 PostLoadValidate
+
+Ensure that the ID corresponds to an actual dashboard object, since it's all
+attributes under the hood.
+
+=cut
+
+sub PostLoadValidate {
+ my $self = shift;
+ return (0, "Invalid object type") unless $self->{'Attribute'}->Name eq 'Selfservicedashboard';
+ return 1;
+}
+
+sub SaveAttribute {
+ my $self = shift;
+ my $object = shift;
+ my $args = shift;
+
+ return $object->AddAttribute(
+ 'Name' => 'Selfservicedashboard',
+ 'Description' => $args->{'Name'},
+ 'Content' => {Panes => $args->{'Panes'}},
+ );
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index ce7c78f679..de32934bbb 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -4718,7 +4718,8 @@ sub UpdateDashboard {
return ( $ok, $msg ) = $user->SetPreferences( 'HomepageSettings', $data->{panes} );
}
} else {
- my $Dashboard = RT::Dashboard->new( $session{'CurrentUser'} );
+ my $class = $args->{self_service_dashboard} ? 'RT::Dashboard::SelfService' : 'RT::Dashboard';
+ my $Dashboard = $class->new( $session{'CurrentUser'} );
( $ok, $msg ) = $Dashboard->LoadById($id);
# report error at the bottom
diff --git a/lib/RT/Interface/Web/MenuBuilder.pm b/lib/RT/Interface/Web/MenuBuilder.pm
index 17eac59cb7..b6651b6363 100644
--- a/lib/RT/Interface/Web/MenuBuilder.pm
+++ b/lib/RT/Interface/Web/MenuBuilder.pm
@@ -1229,6 +1229,16 @@ sub _BuildAdminMenu {
description => loc('Modify the default "RT at a glance" view'),
path => '/Admin/Global/MyRT.html',
);
+ if (RT->Config->Get('SelfServiceUseDashboard')) {
+ my $self_service = $admin_global->child( selfservice_home =>
+ title => loc('Self-Service Home Page'),
+ description => loc('Edit self-service home page dashboard'),
+ path => '/Admin/Global/SelfServiceHomePage.html');
+ if ( $request_path =~ m{^/Admin/Global/SelfServiceHomePage} ) {
+ $page->child(content => title => loc('Content'), path => '/Admin/Global/SelfServiceHomePage.html');
+ $page->child(show => title => loc('Show'), path => '/SelfService');
+ }
+ }
$admin_global->child( 'dashboards-in-menu' =>
title => loc('Modify Reports menu'),
description => loc('Customize dashboards in menu'),
@@ -1571,6 +1581,7 @@ sub _BuildAdminMenu {
}
}
+#'
sub BuildSelfServiceNav {
my $request_path = shift;
my $top = shift;
@@ -1581,6 +1592,15 @@ sub BuildSelfServiceNav {
my $current_user = $HTML::Mason::Commands::session{CurrentUser};
+ if (RT->Config->Get('SelfServiceUseDashboard')) {
+ if ($request_path =~ m{^/SelfService/index\.html$}) {
+ if ($current_user->HasRight( Right => 'ShowConfigTab',
+ Object => RT->System)) {
+ $page->child(content => title => loc('Content'), path => '/Admin/Global/SelfServiceHomePage.html');
+ $page->child(show => title => loc('Show'), path => '/SelfService');
+ }
+ }
+ }
my $queues = RT::Queues->new( $current_user );
$queues->UnLimit;
@@ -1601,7 +1621,7 @@ sub BuildSelfServiceNav {
$top->child( new => title => loc('New ticket'), path => '/SelfService/Create.html?Queue=' . $queue_id );
}
my $tickets = $top->child( tickets => title => loc('Tickets'), path => '/SelfService/' );
- $tickets->child( open => title => loc('Open tickets'), path => '/SelfService/' );
+ $tickets->child( open => title => loc('Open tickets'), path => '/SelfService/Open.html' );
$tickets->child( closed => title => loc('Closed tickets'), path => '/SelfService/Closed.html' );
$top->child( "assets", title => loc("Assets"), path => "/SelfService/Asset/" )
diff --git a/share/html/SelfService/index.html b/share/html/Admin/Global/SelfServiceHomePage.html
similarity index 55%
copy from share/html/SelfService/index.html
copy to share/html/Admin/Global/SelfServiceHomePage.html
index 78d6b95a7b..17713b339e 100644
--- a/share/html/SelfService/index.html
+++ b/share/html/Admin/Global/SelfServiceHomePage.html
@@ -45,30 +45,51 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
+%#<& /Elements/Header, Title => $title &>
+%#<& /Elements/Tabs &>
+%#<& /Elements/ListActions, actions => \@results &>
-% $m->callback(CallbackName => 'BeforeMyRequests', ARGSRef => \%ARGS, Page => $Page);
+<%INIT>
+# If custom self-service page disabled, redirect to /Admin/Global
+if (!RT->Config->Get('SelfServiceUseDashboard')) {
+ RT::Interface::Web::Redirect(RT->Config->Get('WebURL') . 'Admin/Global');
+}
-<& /SelfService/Elements/MyRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My open tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
+my $title = loc('Self-Service Home Page');
+my @results;
-% $m->callback(CallbackName => 'AfterMyRequests', ARGSRef => \%ARGS, Page => $Page);
+use RT::Dashboard::SelfService;
+my $Dashboard = RT::Dashboard::SelfService->new($session{'CurrentUser'});
-<& /SelfService/Elements/MyGroupRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My group\'s tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
+my $dashboard_id;
-% $m->callback(CallbackName => 'AfterMyGroupRequests', ARGSRef => \%ARGS, Page => $Page);
+# The Self-Service Home Page dashboard is special; its attribute is
+# named "selfservicedashboard" instead of "dashboard". We just
+# need to get an ID to reuse the rest of the dashboard code.
+my $attr = RT::Attribute->new(RT->SystemUser);
+my ($ok, $msg) = $attr->LoadByNameAndObject(Object => $RT::System,
+ Name => 'Selfservicedashboard');
+if (!$ok) {
+ my $blank_dashboard = {
+ Panes => {
+ body => [],
+ sidebar => [],
+ }
+ };
+ # Doesn't exist... try creating an empty one
+ ($ok, $msg) = $Dashboard->Save(
+ Privacy => $RT::System,
+ Description => 'Self-Service Home Page Dashboard',
+ Object => $RT::System,
+ Content => $blank_dashboard);
+ unless ($ok) {
+ RT::Logger->error("Unable to create self-service home page dashboard: $msg");
+ Abort(loc("Could not create self-service home page dashboard"));
+ }
+ $dashboard_id = $Dashboard->id;
+} else {
+ $dashboard_id = $attr->Id;
+}
+$m->comp('/Dashboards/Queries.html', id => $dashboard_id, self_service_dashboard => 1, %ARGS);
-<%ARGS>
-$Page => 1
-</%ARGS>
+</%INIT>
diff --git a/share/html/Dashboards/Queries.html b/share/html/Dashboards/Queries.html
index 379e7b1976..87b5941b28 100644
--- a/share/html/Dashboards/Queries.html
+++ b/share/html/Dashboards/Queries.html
@@ -61,14 +61,27 @@
<%INIT>
my @results;
-use RT::Dashboard;
-my $Dashboard = RT::Dashboard->new($session{'CurrentUser'});
+# Don't permit someone to supply "self_service_dashboard=1" on the URL line
+if ($m->request_path ne '/Admin/Global/SelfServiceHomePage.html') {
+ $self_service_dashboard = 0;
+}
+
+my $class = $self_service_dashboard ? 'RT::Dashboard::SelfService' : 'RT::Dashboard';
+eval "use $class;";
+my $Dashboard = $class->new($session{'CurrentUser'});
my ($ok, $msg) = $Dashboard->LoadById($id);
unless ($ok) {
RT::Logger->error("Unable to load dashboard with $id: $msg");
Abort(loc("Could not load dashboard [_1]", $id), Code => HTTP::Status::HTTP_NOT_FOUND);
}
-my $title = loc("Modify the content of dashboard [_1]", $Dashboard->Name);
+
+my $title;
+
+if ($self_service_dashboard) {
+ $title = loc("Modify the self-service home page");
+} else {
+ $title = loc("Modify the content of dashboard [_1]", $Dashboard->Name);
+}
my @sections;
my %item_for;
@@ -214,17 +227,32 @@ $m->callback(
if ( $ARGS{UpdateSearches} ) {
$ARGS{dashboard_id} = $id;
+ $ARGS{self_service_dashboard} = $self_service_dashboard;
my ($ok, $msg) = UpdateDashboard( \%ARGS, \%item_for );
- push @results, $ok ? loc('Dashboard updated') : $msg;
+ if ($self_service_dashboard) {
+ push @results, $ok ? loc('Self-service home page updated') : $msg;
+ } else {
+ push @results, $ok ? loc('Dashboard updated') : $msg;
+ }
+ my $path;
+ my $args;
+ if ($self_service_dashboard) {
+ $path = '/Admin/Global/SelfServiceHomePage.html';
+ $args = { };
+ } else {
+ $path = '/Dashboards/Queries.html';
+ $args = { id => $id };
+ }
MaybeRedirectForResults(
Actions => \@results,
- Path => "/Dashboards/Queries.html",
- Arguments => { id => $id },
+ Path => $path,
+ Arguments => $args,
);
}
</%INIT>
<%ARGS>
$id => '' unless defined $id
+$self_service_dashboard => 0 unless defined $self_service_dashboard;
</%ARGS>
diff --git a/share/html/Dashboards/Render.html b/share/html/Dashboards/Render.html
index 18aaec7572..350ed44026 100644
--- a/share/html/Dashboards/Render.html
+++ b/share/html/Dashboards/Render.html
@@ -110,13 +110,20 @@
my @results;
my $skip_create = 0;
+# Don't permit someone to supply "self_service_dashboard=1" directly
+# on the URL line
+if ($m->request_path ne '/SelfService/index.html') {
+ $self_service_dashboard = 0;
+}
+
$m->callback(ARGSRef => \%ARGS,
results => \@results,
CallbackName => 'Initial',
skip_create => \$skip_create);
-use RT::Dashboard;
-my $Dashboard = RT::Dashboard->new($session{'CurrentUser'});
+my $class = $self_service_dashboard ? 'RT::Dashboard::SelfService' : 'RT::Dashboard';
+eval "use $class;";
+my $Dashboard = $class->new($session{'CurrentUser'});
my ($ok, $msg) = $Dashboard->LoadById($id);
unless ($ok) {
RT::Logger->error("Unable to load dashboard with $id: $msg");
@@ -146,7 +153,12 @@ unless (defined($rows)) {
$rows = defined($prefs->{'RowsPerPage'}) ? $prefs->{'RowsPerPage'} : 50;
}
-my $title = loc '[_1] Dashboard', $Dashboard->Name;
+my $title;
+if ($self_service_dashboard) {
+ $title = loc('Self-service Dashboard');
+} else {
+ $title = loc '[_1] Dashboard', $Dashboard->Name;
+}
my $show_cb = sub {
my $pane = shift;
@@ -171,5 +183,6 @@ my $Refresh = $Preview
$id => undef
$Preview => 1
$HasResults => undef
+$self_service_dashboard => 0
</%ARGS>
diff --git a/share/html/SelfService/index.html b/share/html/SelfService/Open.html
similarity index 98%
copy from share/html/SelfService/index.html
copy to share/html/SelfService/Open.html
index 78d6b95a7b..83e9f768a5 100644
--- a/share/html/SelfService/index.html
+++ b/share/html/SelfService/Open.html
@@ -46,7 +46,7 @@
%#
%# END BPS TAGGED BLOCK }}}
<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
-
+<& /Elements/PageLayout, show_menu => 0 &>
% $m->callback(CallbackName => 'BeforeMyRequests', ARGSRef => \%ARGS, Page => $Page);
<& /SelfService/Elements/MyRequests,
diff --git a/share/html/SelfService/index.html b/share/html/SelfService/index.html
index 78d6b95a7b..15695239d5 100644
--- a/share/html/SelfService/index.html
+++ b/share/html/SelfService/index.html
@@ -45,30 +45,34 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
+<%INIT>
+use RT::Dashboard::SelfService;
+if (RT->Config->Get('SelfServiceUseDashboard')) {
+ # Check if we have a self-service dashboard
+ my $Dashboard = RT::Dashboard::SelfService->new($session{'CurrentUser'});
-% $m->callback(CallbackName => 'BeforeMyRequests', ARGSRef => \%ARGS, Page => $Page);
+ my $dashboard_id;
-<& /SelfService/Elements/MyRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My open tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
+ # The Self-Service Home Page dashboard is special; its attribute is
+ # named "selfservicedashboard" instead of "dashboard". We just
+ # need to get an ID to reuse the rest of the dashboard code.
+ my $attr = RT::Attribute->new(RT->SystemUser);
+ my ($ok, $msg) = $attr->LoadByNameAndObject(Object => $RT::System,
+ Name => 'Selfservicedashboard');
+ if ($ok && $attr->Id) {
+ # Try to load the dashboard
+ my ($ok, $msg) = $Dashboard->LoadById($attr->Id);
+ if ($ok) {
+ $m->comp('/Dashboards/Render.html', id => $attr->Id, self_service_dashboard => 1);
+ return;
+ }
+ }
+}
-% $m->callback(CallbackName => 'AfterMyRequests', ARGSRef => \%ARGS, Page => $Page);
-
-<& /SelfService/Elements/MyGroupRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My group\'s tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
-
-% $m->callback(CallbackName => 'AfterMyGroupRequests', ARGSRef => \%ARGS, Page => $Page);
+# Default to old-style "My Open Tickets"
+$m->comp('/SelfService/Open.html', Page => $Page);
+</%INIT>
<%ARGS>
$Page => 1
</%ARGS>
-----------------------------------------------------------------------
More information about the rt-commit
mailing list