From 305373232182f5c4d9d9b09548054cfb98c2699a Mon Sep 17 00:00:00 2001 From: Jason Crome Date: Tue, 14 Feb 2023 16:54:38 -0500 Subject: [PATCH] Create UI for adjusting dashboard column width Users with accessibility concerns can either tab onto the slider and move it with the arrow keys, or tab into one of the width text boxes and enter the number of columns manually. This only appears on the dashboard configuration page, and assumes that dashboards will be two columns wide. --- lib/RT/Dashboard.pm | 18 ++++- lib/RT/Interface/Web.pm | 8 +- share/html/Dashboards/Queries.html | 11 ++- share/html/Dashboards/Render.html | 8 +- share/html/Elements/MyRT | 8 +- share/html/Widgets/SearchSelection | 81 +++++++++++++++++++ .../static/css/elevator-light/dashboards.css | 24 ++++++ 7 files changed, 147 insertions(+), 11 deletions(-) diff --git a/lib/RT/Dashboard.pm b/lib/RT/Dashboard.pm index 897cb9cade0..c8bd1319627 100644 --- a/lib/RT/Dashboard.pm +++ b/lib/RT/Dashboard.pm @@ -104,7 +104,10 @@ sub SaveAttribute { return $object->AddAttribute( 'Name' => 'Dashboard', 'Description' => $args->{'Name'}, - 'Content' => {Panes => $args->{'Panes'}}, + 'Content' => { + Panes => $args->{'Panes'}, + Width => $args->{'Width'}, + }, ); } @@ -116,6 +119,7 @@ sub UpdateAttribute { if (defined $args->{'Panes'}) { ($status, $msg) = $self->{'Attribute'}->SetSubValues( Panes => $args->{'Panes'}, + Width => $args->{'Width'}, ); } @@ -178,6 +182,18 @@ sub Portlets { return map { @$_ } values %{ $self->Panes }; } +=head2 Width + +Returns a hashref of column widths + +=cut + +sub Width { + my $self = shift; + return unless ref($self->{'Attribute'}) eq 'RT::Attribute'; + return $self->{'Attribute'}->SubValue('Width') || {}; +} + =head2 Dashboards Returns a list of loaded sub-dashboards diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm index 048527213ad..7718e619183 100644 --- a/lib/RT/Interface/Web.pm +++ b/lib/RT/Interface/Web.pm @@ -4967,7 +4967,11 @@ sub UpdateDashboard { "panes" => { "body" => [], "sidebar" => [] - } + }, + "width" => { + body => $args->{body_width}, + sidebar => $args->{sidebar_width}, + }, }; foreach my $arg (qw{ body sidebar }) { @@ -5044,7 +5048,7 @@ sub UpdateDashboard { $content->{$pane_name} = \@pane; } - return ( $ok, $msg ) = $Dashboard->Update( Panes => $content ); + return ( $ok, $msg ) = $Dashboard->Update( Panes => $content, Width => $data->{ width } ); } =head2 ListOfReports diff --git a/share/html/Dashboards/Queries.html b/share/html/Dashboards/Queries.html index 3986c60991f..98d5245fb72 100644 --- a/share/html/Dashboards/Queries.html +++ b/share/html/Dashboards/Queries.html @@ -51,10 +51,13 @@
<& /Widgets/SearchSelection, - pane_name => \%pane_name, - sections => \@sections, - selected => \%selected, - filters => \@filters, + pane_name => \%pane_name, + sections => \@sections, + selected => \%selected, + filters => \@filters, + dashboard_setup => 1, + body_width => $Dashboard->Width->{ body }, + sidebar_width => $Dashboard->Width->{ sidebar }, &> <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
diff --git a/share/html/Dashboards/Render.html b/share/html/Dashboards/Render.html index 76f2b72dc03..371124161d8 100644 --- a/share/html/Dashboards/Render.html +++ b/share/html/Dashboards/Render.html @@ -74,12 +74,12 @@ % my $body = $show_cb->('body'); % my $sidebar = $show_cb->('sidebar'); -
+
<% $body |n %>
% if ( $sidebar =~ /\S/ ) { -
+
<% $sidebar |n %>
% } @@ -150,6 +150,10 @@ Abort(loc("Could not load dashboard [_1]", $id), Code => HTTP::Status::HTTP_NOT_FOUND); } +# Pick reasonable defaults +my $body_width = $Dashboard->Width->{body} // 8; +my $sidebar_width = $Dashboard->Width->{sidebar} // 4; + my $path = '/Dashboards/' . $Dashboard->id . '/' . $Dashboard->Name; unless ( $skip_create ) { push @results, ProcessQuickCreate( Path => $path, ARGSRef => \%ARGS ); diff --git a/share/html/Elements/MyRT b/share/html/Elements/MyRT index 4cc8eb92ba4..d066b0fe065 100644 --- a/share/html/Elements/MyRT +++ b/share/html/Elements/MyRT @@ -48,12 +48,12 @@ % $m->callback( ARGSRef => \%ARGS, CallbackName => 'BeforeTable' );
-
+
% $show_cb->($_) foreach @$body;
% if ( $sidebar ) { -
+
% $show_cb->($_) foreach @$sidebar;
% } @@ -61,6 +61,8 @@
% $m->callback( ARGSRef => \%ARGS, CallbackName => 'AfterTable' ); <%INIT> +my $body_width = 8; +my $sidebar_width = 4; my %allowed_components = map {$_ => 1} @{RT->Config->Get('HomepageComponents')}; @@ -95,6 +97,8 @@ unless ( $Portlets ) { } } $Portlets = $dashboard->Panes; + $body_width = $dashboard->Width->{body} // 8; + $sidebar_width = $dashboard->Width->{sidebar} // 4; } $m->callback( CallbackName => 'MassagePortlets', Portlets => $Portlets ); diff --git a/share/html/Widgets/SearchSelection b/share/html/Widgets/SearchSelection index 266ecab2b0c..4edf0bf5109 100644 --- a/share/html/Widgets/SearchSelection +++ b/share/html/Widgets/SearchSelection @@ -85,7 +85,58 @@
+% if ($dashboard_setup) { + +% }
% for my $pane (sort keys %pane_name) { @@ -100,6 +151,22 @@
+% if ( $dashboard_setup ) { +
+
+
+
+
+ <% loc("[_1] Width:", ucfirst $pane) %> +
+ +
+ <% loc('/ 12 Columns') %> +
+
+
+
+% }
% } @@ -109,6 +176,19 @@ <%INIT> use utf8; + +# Defaults needed here so the editor controls can setup properly for dashboards +# without column widths that are explicitly set. +my ( $body_width, $sidebar_width ); +if ( $dashboard_setup ) { + $body_width = $ARGS{ body_width } // 8; + $sidebar_width = $ARGS{ sidebar_width } // 4; +} else { + # This is some other use of this widget; not for setting up a dashboard + $body_width = 12; + $sidebar_width = 0; +} + $m->callback( CallbackName => 'Default', sections => \@sections, @@ -121,4 +201,5 @@ $m->callback( @filters @sections %selected +$dashboard_setup => 0 diff --git a/share/static/css/elevator-light/dashboards.css b/share/static/css/elevator-light/dashboards.css index 731c36cd038..00c5821c7ce 100644 --- a/share/static/css/elevator-light/dashboards.css +++ b/share/static/css/elevator-light/dashboards.css @@ -5,3 +5,27 @@ table.dashboard { #body>table.dashboard { margin-top: inherit } + +/* Dashboard sliders */ +.ui-slider-handle { + padding-top: 15px; + padding-bottom: 5px; +} + +.width-slider { + margin-top: 10px; + padding-top: 15px; + padding-bottom 15px; +} + +.selectionbox-js .width-slider-wrapper .input-group > .input-group-prepend > .input-group-text { + margin-top: 15px; + background-color: #fff; + border: none; +} + +.selectionbox-js .width-slider-wrapper .form-group > .input-group > .form-control { + margin-top: 15px; + border-radius: .25rem !important; + width: 50px; +}