[Rt-commit] rt branch, 5.0/self-service-homepage-dashboard, created. rt-5.0.0-23-g72a7e4285b
Dianne Skoll
dianne at bestpractical.com
Thu Sep 17 09:51:13 EDT 2020
The branch, 5.0/self-service-homepage-dashboard has been created
at 72a7e4285b755f361b98e6947335c5f2eec95609 (commit)
- Log -----------------------------------------------------------------
commit e8ba9cb0acc38fbeb59e27ccb7250630a458b16f
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.
diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index a7301b3436..884f9bc34c 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -2070,8 +2070,6 @@ Set(
=back
-
-
=head2 Ticket search
=over 4
@@ -2948,6 +2946,41 @@ on self service pages.
Set($SelfServiceShowGroupTickets, 0);
+=item C<$SelfServicePageComponents>
+
+C<$SelfServicePageComponents> is an arrayref of allowed components on
+the SelfService page, if you have set $SelfServiceUseDashboard to true.
+If this is not set at all, then $HomepageComponents is used instead.
+
+=cut
+
+Set(
+ $SelfServicePageComponents,
+ [
+ qw(QuickCreate QueueList MyAdminQueues MySupportQueues MyReminders RefreshHomepage Dashboards SavedSearches FindUser MyAssets FindAsset FindGroup SelfServiceTopArticles ) # loc_qw
+ ]
+);
+
+=item C<$SelfServiceUseDashboard>
+
+C<$SelfServiceUseDashboard> is a flag indicating whether or not to use
+a dashboard for the Self Service home page. If it is set to false,
+then the normal Open Tickets / Closed Tickets menu is shown rather
+than a dashboard.
+
+=cut
+
+Set($SelfServiceUseDashboard, 0);
+
+=item C<$SelfServiceArticleClass>
+
+C<$SelfServiceArticleClass> limits the articles shown to self-service
+users to the specified class.
+
+=cut
+
+Set($SelfServiceArticleClass, "SelfService");
+
=back
=head2 Articles
diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 400dd5ac22..59ce078f1c 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -1591,6 +1591,9 @@ our %META;
SearchResultsAutoRedirect => {
Widget => '/Widgets/Form/Boolean',
},
+ SelfServiceUseDashboard => {
+ Widget => '/Widgets/Form/Boolean',
+ },
ShowBccHeader => {
Widget => '/Widgets/Form/Boolean',
},
diff --git a/lib/RT/Dashboard/SelfService.pm b/lib/RT/Dashboard/SelfService.pm
new file mode 100644
index 0000000000..e20ffb76fa
--- /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..65ce0ee7ce 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;
@@ -1600,8 +1620,13 @@ sub BuildSelfServiceNav {
} elsif ( $queue_id ) {
$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/' );
+
+ my $menu_label = loc('Tickets');
+ if (RT->Config->Get('SelfServiceUseDashboard')) {
+ $menu_label = loc('Self-Service');
+ }
+ my $tickets = $top->child( tickets => title => $menu_label, 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..3969dd4280 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/Articles/Article/Edit.html b/share/html/Articles/Article/Edit.html
index b51e0eda55..007350bace 100644
--- a/share/html/Articles/Article/Edit.html
+++ b/share/html/Articles/Article/Edit.html
@@ -122,6 +122,14 @@ if ( $ARGS{SetEnabled} ) {
$ARGS{Disabled} = $ARGS{Enabled} ? 0 : 1;
}
+my $sortorder_ok = 1;
+if ($ARGS{SortOrder}) {
+ if ($ARGS{SortOrder} !~ /^-?\d+$/) {
+ push @results, (0, loc('Sort Order must be an integer'));
+ $sortorder_ok = 0;
+ }
+}
+
if ( !$id ) {
$title = loc('Create a new article');
foreach my $arg ( sort keys %ARGS ) {
@@ -148,25 +156,30 @@ elsif ( $id eq 'new' ) {
split( /\s+/, $ARGS{'new-RefersTo'} );
}
- my %cfs = ProcessObjectCustomFieldUpdatesForCreate(
- ARGSRef => \%ARGS,
- ContextObject => $ClassObj,
- );
-
- my $msg;
- ( $id, $msg ) = $ArticleObj->Create(
- Summary => $ARGS{'Summary'},
- Name => $ARGS{'Name'},
- Class => $ARGS{'Class'},
- Topics => $ARGS{'Topics'},
- Disabled => $ARGS{'Disabled'},
- %create_args,
- %cfs
- );
- push( @results, $msg );
- if ($id) {
+ my %cfs;
+ if ($sortorder_ok) {
+ %cfs = ProcessObjectCustomFieldUpdatesForCreate(
+ ARGSRef => \%ARGS,
+ ContextObject => $ClassObj,
+ );
+ my $msg;
+ ( $id, $msg ) = $ArticleObj->Create(
+ Summary => $ARGS{'Summary'},
+ SortOrder => $ARGS{'SortOrder'},
+ Name => $ARGS{'Name'},
+ Class => $ARGS{'Class'},
+ Topics => $ARGS{'Topics'},
+ Disabled => $ARGS{'Disabled'},
+ %create_args,
+ %cfs
+ );
+ push( @results, $msg );
+ } else {
+ $id = 0;
+ }
+ if ($id) {
$ArticleObj->Load($id);
$title = loc( 'Modify article #[_1]', $ArticleObj->Id );
@@ -199,11 +212,13 @@ else {
my @attribs = qw(Name Summary Class Disabled);
- @results = UpdateRecordObject(
- AttributesRef => \@attribs,
- Object => $ArticleObj,
- ARGSRef => \%ARGS
- );
+ if ($sortorder_ok) {
+ @results = UpdateRecordObject(
+ AttributesRef => \@attribs,
+ Object => $ArticleObj,
+ ARGSRef => \%ARGS
+ );
+ }
my @cf_results = ProcessObjectCustomFieldUpdates(
Object => $ArticleObj,
diff --git a/share/html/Dashboards/Elements/ShowPortlet/component b/share/html/Dashboards/Elements/ShowPortlet/component
index cead432fb2..b3258fe706 100644
--- a/share/html/Dashboards/Elements/ShowPortlet/component
+++ b/share/html/Dashboards/Elements/ShowPortlet/component
@@ -56,7 +56,14 @@ $HasResults
my $full_path = $Portlet->{path};
(my $path = $full_path) =~ s{^/Elements/}{};
-my $allowed = grep { $_ eq $path } @{RT->Config->Get('HomepageComponents')};
+my $allowed;
+
+if ($m->request_path =~ m{/SelfService}) {
+ $allowed = grep { $_ eq $path } @{RT->Config->Get('SelfServicePageComponents') || RT->Config->Get('HomepageComponents')};
+} else {
+ $allowed = grep { $_ eq $path } @{RT->Config->Get('HomepageComponents')};
+}
+
</%init>
% if (!$allowed) {
% $m->out( $m->interp->apply_escapes( loc("Invalid portlet [_1]", $path), "h" ) );
diff --git a/share/html/Dashboards/Queries.html b/share/html/Dashboards/Queries.html
index 379e7b1976..c0b47d1ed2 100644
--- a/share/html/Dashboards/Queries.html
+++ b/share/html/Dashboards/Queries.html
@@ -61,19 +61,38 @@
<%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;
-my @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('HomepageComponents')};
+my @components;
+
+if ($self_service_dashboard) {
+ @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('SelfServicePageComponents') || RT->Config->Get('HomepageComponents')};
+} else {
+ @components = map { type => "component", name => $_, label => loc($_) }, @{RT->Config->Get('HomepageComponents')};
+}
$item_for{ $_->{type} }{ $_->{name} } = $_ for @components;
@@ -214,17 +233,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/Elements/SelfServiceTopArticles
similarity index 73%
copy from share/html/SelfService/index.html
copy to share/html/Elements/SelfServiceTopArticles
index 78d6b95a7b..79c3a50081 100644
--- a/share/html/SelfService/index.html
+++ b/share/html/Elements/SelfServiceTopArticles
@@ -45,30 +45,12 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
-% $m->callback(CallbackName => 'BeforeMyRequests', ARGSRef => \%ARGS, Page => $Page);
-
-<& /SelfService/Elements/MyRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My open tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
-
-% $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);
+<& /Elements/TopArticles,
+ title => $title,
+ display_path => 'SelfService/Article',
+ classname => (RT->Config->Get('SelfServiceArticleClass') || 'SelfService') &>
<%ARGS>
-$Page => 1
+$title => undef
</%ARGS>
diff --git a/share/html/SelfService/index.html b/share/html/Elements/TopArticles
similarity index 58%
copy from share/html/SelfService/index.html
copy to share/html/Elements/TopArticles
index 78d6b95a7b..824e7d7cbb 100644
--- a/share/html/SelfService/index.html
+++ b/share/html/Elements/TopArticles
@@ -45,30 +45,54 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
-% $m->callback(CallbackName => 'BeforeMyRequests', ARGSRef => \%ARGS, Page => $Page);
+<&| /Widgets/TitleBox, title => $title &>
-<& /SelfService/Elements/MyRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My open tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
+% while (my $article = $articles->Next) {
+ <div class="form-row">
+ <span class="value col-auto">
+ <a href="<% RT->Config->Get('WebPath') %>/<% $display_path %>/Display.html?id=<%$article->Id%>"><%$article->Name || loc('(no name)')%>: <%$article->Summary%></a>
+ </span>
+ </div>
+% }
+</&>
-% $m->callback(CallbackName => 'AfterMyRequests', ARGSRef => \%ARGS, Page => $Page);
+<%INIT>
+$title = loc('Articles');
+# Figure out which class of articles applies, if a classname was given
+my $class;
-<& /SelfService/Elements/MyGroupRequests,
- %ARGS,
- status => '__Active__',
- title => loc('My group\'s tickets'),
- BaseURL => RT->Config->Get('WebPath') ."/SelfService/?",
- Page => $Page,
-&>
+if ($classname) {
+ $class = RT::Class->new( $session{'CurrentUser'} );
+ my ($ok, $msg) = $class->LoadByCols( Name => RT->Config->Get('SelfServiceArticleClass') );
+ if (!$ok || !$class->Id) {
+ # Could not find the class... bail?
+ return;
+ }
+}
-% $m->callback(CallbackName => 'AfterMyGroupRequests', ARGSRef => \%ARGS, Page => $Page);
+# Get the articles
+my $articles = RT::Articles->new( $session{'CurrentUser'} );
+
+$articles->RowsPerPage($rows);
+
+if ($class) {
+ $articles->Search(Class => $class->Id,
+ OrderBy => ['SortOrder', 'LastUpdated'],
+ Order => ['ASC', 'DESC' ]);
+} else {
+ $articles->Search(OrderBy => ['SortOrder', 'LastUpdated'],
+ Order => ['ASC', 'DESC' ]);
+}
+
+</%INIT>
<%ARGS>
-$Page => 1
+$title => undef
+$rows => 10
+# Unfortunately, the directory hierarchy under SelfService
+# is just "Article" instead of "Articles/Article", so we have
+# to make to path for displaying an article a parameter.
+$display_path => 'Articles/Article'
+$classname => undef
</%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..0ddf61c486 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>
commit 72a7e4285b755f361b98e6947335c5f2eec95609
Author: Dianne Skoll <dianne at bestpractical.com>
Date: Wed Sep 9 12:16:46 2020 -0400
Add UI for editing and displaying the SortOrder associated with an article.
diff --git a/lib/RT/Article.pm b/lib/RT/Article.pm
index af1e628784..ba7375efca 100644
--- a/lib/RT/Article.pm
+++ b/lib/RT/Article.pm
@@ -777,7 +777,7 @@ sub _CoreAccessible {
Summary =>
{read => 1, write => 1, type => 'varchar(255)', default => ''},
SortOrder =>
- {read => 1, write => 1, type => 'int(11)', default => '0'},
+ {read => 1, write => 1, type => 'int(11)', default => '0', is_numeric => 1},
Class =>
{read => 1, write => 1, type => 'int(11)', default => '0'},
Parent =>
diff --git a/share/html/Articles/Article/Display.html b/share/html/Articles/Article/Display.html
index 6f841d430a..aee001f5c5 100644
--- a/share/html/Articles/Article/Display.html
+++ b/share/html/Articles/Article/Display.html
@@ -58,6 +58,15 @@
</div>
</div>
+ <div class="form-row">
+ <div class="label col-3">
+ <&|/l&>Sort Order</&>:
+ </div>
+ <div class="value col-9">
+ <span class="current-value"><%$article->SortOrder%></span>
+ </div>
+ </div>
+
<div class="form-row">
<div class="label col-3">
<&|/l&>Class</&>:
diff --git a/share/html/Articles/Article/Edit.html b/share/html/Articles/Article/Edit.html
index 007350bace..4116610c29 100644
--- a/share/html/Articles/Article/Edit.html
+++ b/share/html/Articles/Article/Edit.html
@@ -163,6 +163,20 @@ elsif ( $id eq 'new' ) {
ContextObject => $ClassObj,
);
+ my $msg;
+ ( $id, $msg ) = $ArticleObj->Create(
+ Summary => $ARGS{'Summary'},
+ SortOrder => $ARGS{'SortOrder'},
+ Name => $ARGS{'Name'},
+ Class => $ARGS{'Class'},
+ Topics => $ARGS{'Topics'},
+ Disabled => $ARGS{'Disabled'},
+ %create_args,
+ %cfs
+ );
+ push( @results, $msg );
+ }
+ if ($id) {
my $msg;
( $id, $msg ) = $ArticleObj->Create(
Summary => $ARGS{'Summary'},
@@ -210,7 +224,7 @@ else {
Why => loc("Unable to load article") );
}
- my @attribs = qw(Name Summary Class Disabled);
+ my @attribs = qw(Name Summary Class Disabled SortOrder);
if ($sortorder_ok) {
@results = UpdateRecordObject(
diff --git a/share/html/Articles/Article/Elements/EditBasics b/share/html/Articles/Article/Elements/EditBasics
index 73c5a7f5a1..a898a9cbd1 100644
--- a/share/html/Articles/Article/Elements/EditBasics
+++ b/share/html/Articles/Article/Elements/EditBasics
@@ -61,6 +61,14 @@
<input class="form-control" type="text" name="Summary" value="<%($ARGS{'id'} eq 'new' ? '' : $ArticleObj->Summary) || $ARGS{'Summary'} ||'' |h%>" size="50" />
</div>
</div>
+<div class="form-row">
+ <div class="label col-3">
+ <&|/l&>Sort Order</&>:
+ </div>
+ <div class="value col-9">
+ <input class="form-control" type="text" name="SortOrder" value="<%($ARGS{'id'} eq 'new' ? '0' : $ArticleObj->SortOrder) || $ARGS{'SortOrder'} || '0' |h%>" size="50" />
+ </div>
+</div>
<div class="form-row">
<div class="label col-3">
<&|/l&>Class</&>:
-----------------------------------------------------------------------
More information about the rt-commit
mailing list