Skip to content

Commit

Permalink
Create UI for adjusting dashboard column width
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Jason Crome authored and sunnavy committed Nov 6, 2023
1 parent 464dacd commit 3053732
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 11 deletions.
18 changes: 17 additions & 1 deletion lib/RT/Dashboard.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
},
);
}

Expand All @@ -116,6 +119,7 @@ sub UpdateAttribute {
if (defined $args->{'Panes'}) {
($status, $msg) = $self->{'Attribute'}->SetSubValues(
Panes => $args->{'Panes'},
Width => $args->{'Width'},
);
}

Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions lib/RT/Interface/Web.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4967,7 +4967,11 @@ sub UpdateDashboard {
"panes" => {
"body" => [],
"sidebar" => []
}
},
"width" => {
body => $args->{body_width},
sidebar => $args->{sidebar_width},
},
};

foreach my $arg (qw{ body sidebar }) {
Expand Down Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions share/html/Dashboards/Queries.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@

<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
<& /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') &>
</form>
Expand Down
8 changes: 6 additions & 2 deletions share/html/Dashboards/Render.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@

% my $body = $show_cb->('body');
% my $sidebar = $show_cb->('sidebar');
<div class="col-<% $sidebar =~ /\S/ ? 8 : 12 %>">
<div class="col-<% $sidebar =~ /\S/ ? $body_width : 12 %>">
<% $body |n %>
</div>

% if ( $sidebar =~ /\S/ ) {
<div class="col-4">
<div class="col-<% $sidebar_width %>">
<% $sidebar |n %>
</div>
% }
Expand Down Expand Up @@ -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 );
Expand Down
8 changes: 6 additions & 2 deletions share/html/Elements/MyRT
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,21 @@
% $m->callback( ARGSRef => \%ARGS, CallbackName => 'BeforeTable' );
<div class="myrt row">

<div class="<% 'boxcontainer col-md-' . ( $sidebar ? '8' : '12' ) %>">
<div class="<% 'boxcontainer col-md-' . ( $sidebar ? $body_width : '12' ) %>">
% $show_cb->($_) foreach @$body;
</div>

% if ( $sidebar ) {
<div class="boxcontainer col-md-4">
<div class="boxcontainer col-md-<% $sidebar_width %>">
% $show_cb->($_) foreach @$sidebar;
</div>
% }

</div>
% $m->callback( ARGSRef => \%ARGS, CallbackName => 'AfterTable' );
<%INIT>
my $body_width = 8;
my $sidebar_width = 4;

my %allowed_components = map {$_ => 1} @{RT->Config->Get('HomepageComponents')};

Expand Down Expand Up @@ -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 );
Expand Down
81 changes: 81 additions & 0 deletions share/html/Widgets/SearchSelection
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,58 @@
</div>
</div>
</div>
% if ($dashboard_setup) {
<script type="text/javascript">
jQuery(window).on('load', function() {
var validateWidth = function (cols) {
if(!jQuery.isNumeric(cols)) { return 0; }
if(cols < 0) { cols = 0; }
if(cols > 12) { cols = 12; }
return cols;
}

jQuery("#slider-body-width").slider({
range: 'min',
min: 0,
max: 12,
value: <% $body_width %>,
slide: function(event, ui) {
jQuery("#body-width").val(ui.value);
jQuery("#sidebar-width").val(12 - ui.value);
jQuery("#slider-sidebar-width").slider("value", 12 - ui.value);
}
});
jQuery("#body-width").val(jQuery("#slider-body-width").slider("value"));
jQuery("#body-width").change(function() {
var cols = validateWidth( jQuery(this).val() );
jQuery(this).val(cols);
jQuery("#slider-body-width").slider("value", cols);
jQuery("#sidebar-width").val(12 - cols);
jQuery("#slider-sidebar-width").slider("value", 12 - cols);
});

jQuery("#slider-sidebar-width").slider({
range: 'min',
min: 0,
max: 12,
value: <% $sidebar_width %>,
slide: function(event, ui) {
jQuery("#sidebar-width").val(ui.value);
jQuery("#body-width").val(12 - ui.value);
jQuery("#slider-body-width").slider("value", 12 - ui.value);
}
});
jQuery("#sidebar-width").val(jQuery("#slider-sidebar-width").slider("value"));
jQuery("#sidebar-width").change(function() {
var cols = validateWidth(jQuery(this).val());
jQuery(this).val(cols);
jQuery("#slider-body-width").slider("value", 12 - cols);
jQuery("#body-width").val(12 - cols);
jQuery("#slider-sidebar-width").slider("value", cols);
});
});
</script>
% }
<div class="col-6">
<div class="destinations">
% for my $pane (sort keys %pane_name) {
Expand All @@ -100,6 +151,22 @@
</ul>
</div>
</div>
% if ( $dashboard_setup ) {
<div class="form-row width-slider-wrapper">
<div class="form-group mx-auto">
<div id="slider-<% $pane %>-width" class="width-slider"></div>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><% loc("[_1] Width:", ucfirst $pane) %></span>
</div>
<input type="number" min="0" max="12" step="1" class="form-control" name="<% $pane %>_width" id="<% $pane %>-width" />
<div class="input-group-prepend">
<span class="input-group-text"><% loc('/ 12 Columns') %></span>
</div>
</div>
</div>
</div>
% }
</div>
% }
</div>
Expand All @@ -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,
Expand All @@ -121,4 +201,5 @@ $m->callback(
@filters
@sections
%selected
$dashboard_setup => 0
</%ARGS>
24 changes: 24 additions & 0 deletions share/static/css/elevator-light/dashboards.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 3053732

Please sign in to comment.