[Rt-commit] rt branch, 5.0.0-releng, updated. rt-5.0.0beta2-43-g1dffdb554c

? sunnavy sunnavy at bestpractical.com
Tue Jul 7 18:46:01 EDT 2020


The branch, 5.0.0-releng has been updated
       via  1dffdb554ce34e6fb2746ef42bd8b5f25bdd3faf (commit)
       via  6ad87d14afa5659265cfa299002b95dd475b2928 (commit)
       via  4067f1762134ca8c10e81e3fd54f41aa50d9a9ec (commit)
       via  21915ad0031627b8b5da6af5c3ed7fcb53d74ea4 (commit)
       via  daadbd779efe4a1418301a831c16dae40ba20aec (commit)
       via  8e7a114fb1737830ee8f5da52f87c2948812efa7 (commit)
       via  fc537d909e43c82d4819d8a4fac79a6f2aa88d8d (commit)
      from  ae7a4bd0cce65d704d230622e5421051703b501b (commit)

Summary of changes:
 share/html/Admin/Global/DashboardsInMenu.html | 197 ++++++++++++++---------
 share/html/Admin/Users/DashboardsInMenu.html  | 185 +++++++++++++---------
 share/html/Prefs/DashboardsInMenu.html        | 158 ++++++++++++-------
 share/html/Widgets/SearchSelection            |   2 +
 share/static/css/elevator-light/forms.css     |   6 +-
 t/web/dashboards-in-menu.t                    | 218 +++++++++++++++++++++-----
 6 files changed, 516 insertions(+), 250 deletions(-)

- Log -----------------------------------------------------------------
commit fc537d909e43c82d4819d8a4fac79a6f2aa88d8d
Author: craig kaiser <craig at bestpractical.com>
Date:   Fri Jun 26 14:26:14 2020 -0400

    Convert Prefs/DashboardsInMenu.html to drag and drop UI

diff --git a/share/html/Prefs/DashboardsInMenu.html b/share/html/Prefs/DashboardsInMenu.html
index 67cf8a9640..82ba363deb 100644
--- a/share/html/Prefs/DashboardsInMenu.html
+++ b/share/html/Prefs/DashboardsInMenu.html
@@ -50,14 +50,23 @@
 &>
 <& /Elements/ListActions, actions => \@results &>
 
-<&|/Widgets/TitleBox,
-    title => loc('Dashboards in menu'),
-    bodyclass => ""
-&>
-<& /Widgets/SelectionBox:show, self => $dashboard_pane &>
-</&>
-
-<&|/Widgets/TitleBox, title => loc("Reset dashboards in menu") &>
+<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { dashboard => loc('Dashboards in menu') },
+    sections  => [{
+                    id    => 'dashboards',
+                    label => loc("Dashboards"),
+                    items => \@dashboard_components,
+                }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="dashboard_id" value="DashboardsInMenu">
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
+<&|/Widgets/TitleBox, title => loc("Reset dashboards in menu"), class => "mx-auto max-width-lg" &>
 <div class="mt-3 mb-1 ml-3">
   <form method="post" action="DashboardsInMenu.html">
     <input type="submit" name="ResetDashboards" class="button form-control btn btn-primary" value="<% loc('Reset dashboards to default') %>">
@@ -65,14 +74,23 @@
 </div>
 </&>
 
-<&|/Widgets/TitleBox,
-    title => loc('Reports in menu'),
-    bodyclass => ""
-&>
-<& /Widgets/SelectionBox:show, self => $report_pane &>
-</&>
-
-<&|/Widgets/TitleBox, title => loc("Reset reports in menu") &>
+<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { report => loc('Reports in menu') },
+    sections  => [{
+                  id    => 'reports',
+                  label => loc("Reports"),
+                  items => \@report_components,
+              }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="dashboard_id" value="ReportsInMenu">
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
+<&|/Widgets/TitleBox, title => loc("Reset reports in menu"), class => "mx-auto max-width-lg" &>
 <div class="mt-3 mb-1 ml-3">
   <form method="post" action="DashboardsInMenu.html">
     <input type="submit" name="ResetReports" class="button form-control btn btn-primary" value="<% loc('Reset reports to default') %>">
@@ -102,63 +120,81 @@ if ( $ARGS{ResetReports} ) {
     }
 }
 
-my ($default_dashboards) =
-RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu');
+my @dashboard_components = map {{ type => 'dashboard', id => $_->id, name => $_->Name, label => $_->Name }} $m->comp("/Dashboards/Elements/ListOfDashboards", IncludeSuperuserGroups => 0 );
+my @report_components = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ ListOfReports() };
 
-my $dashboard_pref =
-  $session{CurrentUser}->UserObj->Preferences( 'DashboardsInMenu',
-    $default_dashboards ? $default_dashboards->Content : () );
+if ($ARGS{UpdateSearches}) {
+    if ( $ARGS{'dashboard_id'} eq 'DashboardsInMenu' ) {
+        my @dashboard_ids;
 
-my $current_dashboards = $dashboard_pref->{dashboards} || [];
+        my $dashboard_names = ref $ARGS{'dashboard'} eq 'ARRAY' ? $ARGS{'dashboard'} : [$ARGS{'dashboard'}];
+        foreach my $name ( @{$dashboard_names} ) {
+            next unless $name;
+            $name =~ s/dashboard-//;
 
-my @dashboards = map { [$_->id, $_->Name] } $m->comp("/Dashboards/Elements/ListOfDashboards", IncludeSuperuserGroups => 0 );
+            my $attribute = RT::Attribute->new( $session{'CurrentUser'} );
+
+            my ($ret, $msg) = $attribute->LoadByCols( Name => 'Dashboard', Description => $name );
+            if ( $ret ) {
+                push @dashboard_ids, $attribute->Id;
+            }
+            else {
+                RT::Logger->error( "Could not load dashboard: $msg" );
+                push @results, "Could not load dashboard $name";
+            }
+        }
 
-my ($dashboard_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action => 'DashboardsInMenu.html',
-    panes => ['dashboards_in_menu'],
-    items => \@dashboards,
-    current_portlets => $current_dashboards,
-    OnSave => sub {
-        my ( $conf ) = @_;
-        my ( $ok, $msg ) =
-          $user->SetPreferences( 'DashboardsInMenu', $conf );
+        my ( $ok, $msg ) = $user->SetPreferences( $ARGS{'dashboard_id'}, { 'dashboards' => \@dashboard_ids } );
         push @results, $ok ? loc('Preferences saved for dashboards in menu.') : $msg;
         delete $session{'dashboards_in_menu'};
     }
-);
-
-my ( @reports, %reports );
-for my $report ( @{ ListOfReports() } ) {
-    push @reports, [ $report->{id}, $report->{title} ];
-    $reports{ $report->{id} } = $report;
+    else {
+      my $report_names = ref $ARGS{'report'} eq 'ARRAY' ? $ARGS{'report'} : [$ARGS{'report'}];
+      my @ret;
+      foreach my $report ( @report_components ) {
+          last unless $report_names->[0];
+
+          push @ret, $report if grep { $_ =~ /report-$report->{'name'}/ } @{$report_names};
+      }
+
+      my ( $ok, $msg ) = $user->SetPreferences( $ARGS{'dashboard_id'}, \@ret );
+      push @results, $ok ? loc('Preferences saved for reports in menu.') : $msg;
+      delete $session{'reports_in_menu'};
+    }
 }
 
-my ($default_reports) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('ReportsInMenu');
-my $report_pref
-    = $session{CurrentUser}->UserObj->Preferences( 'ReportsInMenu', $default_reports ? $default_reports->Content : () );
-my $current_reports = [ map { $_->{id} } @{ $report_pref || [] } ];
-
-my ($report_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action           => 'DashboardsInMenu.html',
-    panes            => ['reports_in_menu'],
-    items            => \@reports,
-    current_portlets => $current_reports,
-    OnSave           => sub {
-        my ($conf) = @_;
-        my $user_reports = [];
-        foreach my $id ( @{ $conf->{dashboards} } ) {
-            push @$user_reports, $reports{$id} if $reports{$id};
-        }
-        my ( $ok, $msg ) = $user->SetPreferences( 'ReportsInMenu', $user_reports );
-        push @results, $msg unless $ok;
+my %selected;
 
-        delete $session{'reports_in_menu'};
+my ($default_dashboards) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('DashboardsInMenu');
+my $dashboard_pref = $user->Preferences( 'DashboardsInMenu', $default_dashboards ? $default_dashboards->Content : () );
+
+# prefs returns an array of Dashboard ID's
+my $selected_dashboard_ids = $dashboard_pref->{'dashboards'} || [];
+
+my @selected_dashboards;
+foreach my $id ( @{$selected_dashboard_ids} ) {
+    my $attribute = RT::Attribute->new( RT->SystemUser );
+    my ($ret, $msg) = $attribute->Load( $id );
+    unless ( $ret ) {
+        RT::Logger->error( "Could not load dashboard: $id" );
+        next;
     }
-);
 
-$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) for ( $dashboard_pane, $report_pane );
+    push @selected_dashboards, {
+      id      => $id,
+      name    => $attribute->Description,
+      label   => $attribute->Description,
+      type    => 'dashboard'
+    };
+}
+$selected{'dashboard'} = \@selected_dashboards;
 
+my $report_pref = $user->Preferences('ReportsInMenu');
+unless ($report_pref) {
+    my ($defaults) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('ReportsInMenu');
+    $report_pref = $defaults ? $defaults->Content : [];
+}
+my @report_pref_sanitized = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ $report_pref };
+$selected{'report'} = \@report_pref_sanitized || [];
 </%INIT>
 

commit 8e7a114fb1737830ee8f5da52f87c2948812efa7
Author: craig kaiser <craig at bestpractical.com>
Date:   Mon Jun 29 12:05:31 2020 -0400

    Convert Admin/Users/DashboardsInMenu.html to drag and drop UI

diff --git a/share/html/Admin/Users/DashboardsInMenu.html b/share/html/Admin/Users/DashboardsInMenu.html
index 733da3becb..f3d466af71 100644
--- a/share/html/Admin/Users/DashboardsInMenu.html
+++ b/share/html/Admin/Users/DashboardsInMenu.html
@@ -50,14 +50,24 @@
 
 <& /Elements/ListActions, actions => \@actions &>
 
-<&|/Widgets/TitleBox,
-    title => loc('Dashboards in menu'),
-    bodyclass => ""
-&>
-<& /Widgets/SelectionBox:show, self => $dashboard_pane &>
-</&>
-
-<&|/Widgets/TitleBox, title => loc("Reset dashboards in menu") &>
+<form method="post" action="DashboardsInMenu.html" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { dashboard => loc('Dashboards in menu') },
+    sections  => [{
+                    id    => 'dashboards',
+                    label => loc("Dashboards"),
+                    items => \@dashboard_components,
+                }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="id" value="<% $id %>" />
+  <input type="hidden" name="dashboard_id" value="DashboardsInMenu" />
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
+<&|/Widgets/TitleBox, title => loc("Reset dashboards in menu"), class => "mx-auto max-width-lg" &>
 <div class="mt-3 mb-1 ml-3">
   <form method="post" action="DashboardsInMenu.html">
     <input type="hidden" name="id" value="<% $id %>" />
@@ -66,14 +76,24 @@
 </div>
 </&>
 
-<&|/Widgets/TitleBox,
-    title => loc('Reports in menu'),
-    bodyclass => ""
-&>
-<& /Widgets/SelectionBox:show, self => $report_pane &>
-</&>
-
-<&|/Widgets/TitleBox, title => loc("Reset reports in menu") &>
+<form method="post" action="DashboardsInMenu.html" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { report => loc('Reports in menu') },
+    sections  => [{
+                  id    => 'reports',
+                  label => loc("Reports"),
+                  items => \@report_components,
+              }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="id" value="<% $id %>" />
+  <input type="hidden" name="dashboard_id" value="ReportsInMenu" />
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
+<&|/Widgets/TitleBox, title => loc("Reset reports in menu"), class => "mx-auto max-width-lg" &>
 <div class="mt-3 mb-1 ml-3">
   <form method="post" action="DashboardsInMenu.html">
     <input type="hidden" name="id" value="<% $id %>" />
@@ -84,6 +104,7 @@
 
 <%init>
 my @actions;
+
 my $UserObj = RT::User->new($session{'CurrentUser'});
 $UserObj->Load($id) || Abort("Couldn't load user '" . ($id || '') . "'");
 my $title = loc("Reports menu for the user [_1]", $UserObj->Name);
@@ -103,75 +124,85 @@ if ( $ARGS{ResetReports} ) {
     }
 }
 
-my ($default_dashboards) =
-RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu');
-
-my $user = RT::CurrentUser->new( $session{CurrentUser} );
-$user->Load( $UserObj->id );
-my @dashboards =
-  map { [ $_->id, $_->Name ] }
-  $m->comp( "/Dashboards/Elements/ListOfDashboards", User => $user, IncludeSuperuserGroups => 0 );
-
-
-my $current_pref =
-  $UserObj->Preferences( 'DashboardsInMenu',
-    $default_dashboards ? $default_dashboards->Content : () );
-my $current_portlets =
-    $current_pref && $current_pref->{dashboards}
-  ? $current_pref->{dashboards}
-  : [];
-
-my ($dashboard_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action           => "DashboardsInMenu.html?id=$id",
-    panes            => ['dashboards_in_menu'],
-    items            => \@dashboards,
-    current_portlets => $current_portlets,
-    OnSave => sub {
-        my ($conf) = @_;
-        my ( $ok, $msg ) =
-          $UserObj->SetPreferences( 'DashboardsInMenu', $conf );
-        push @actions,
-          $ok ? loc('Preferences saved for dashboards in menu.') : $msg;
+my @dashboard_components = map {{ type => 'dashboard', id => $_->id, name => $_->Name, label => $_->Name }} $m->comp("/Dashboards/Elements/ListOfDashboards", IncludeSuperuserGroups => 0 );
+my @report_components = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ ListOfReports() };
+
+if ($ARGS{UpdateSearches}) {
+  if ( $ARGS{'dashboard_id'} eq 'DashboardsInMenu' ) {
+      my @dashboard_ids;
+
+      my $dashboard_names = ref $ARGS{'dashboard'} eq 'ARRAY' ? $ARGS{'dashboard'} : [$ARGS{'dashboard'}];
+      foreach my $name ( @{$dashboard_names} ) {
+          next unless $name;
+          $name =~ s/dashboard-//;
+
+          my $attribute = RT::Attribute->new( $session{'CurrentUser'} );
+
+          my ($ret, $msg) = $attribute->LoadByCols( Name => 'Dashboard', Description => $name );
+          if ( $ret ) {
+              push @dashboard_ids, $attribute->Id;
+          }
+          else {
+              RT::Logger->error( "Could not load dashboard: $msg" );
+              push @actions, "Could not load dashboard $name";
+          }
+      }
+
+      my ( $ok, $msg ) = $UserObj->SetPreferences( $ARGS{'dashboard_id'}, { 'dashboards' => \@dashboard_ids } );
+      push @actions, $ok ? loc('Preferences saved for dashboards in menu.') : $msg;
+      delete $session{'dashboards_in_menu'};
+  }
+  else {
+    my $report_names = ref $ARGS{'report'} eq 'ARRAY' ? $ARGS{'report'} : [$ARGS{'report'}];
+    my @ret;
+    foreach my $report ( @report_components ) {
+        last unless $report_names->[0];
+
+        push @ret, $report if grep { $_ =~ /report-$report->{'name'}/ } @{$report_names};
     }
-);
 
-my ( @reports, %reports );
-for my $report ( @{ ListOfReports() } ) {
-    push @reports, [ $report->{id}, $report->{title} ];
-    $reports{ $report->{id} } = $report;
+    my ( $ok, $msg ) = $UserObj->SetPreferences( $ARGS{'dashboard_id'}, \@ret );
+    push @actions, $ok ? loc('Preferences saved for reports in menu.') : $msg;
+    delete $session{'reports_in_menu'};
+  }
 }
 
-my ($default_reports) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('ReportsInMenu');
-my $report_pref = $UserObj->Preferences( 'ReportsInMenu', $default_reports ? $default_reports->Content : () );
-my $current_reports = [ map { $_->{id} } @{ $report_pref || [] } ];
-
-my ($report_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action           => "DashboardsInMenu.html?id=$id",
-    panes            => ['reports_in_menu'],
-    items            => \@reports,
-    current_portlets => $current_reports,
-    OnSave           => sub {
-        my ($conf) = @_;
-        my $user_reports = [];
-        foreach my $id ( @{ $conf->{dashboards} } ) {
-            push @$user_reports, $reports{$id} if $reports{$id};
-        }
-
-        my ( $ok, $msg ) = $UserObj->SetPreferences( 'ReportsInMenu', $user_reports );
-        if ($ok) {
-            push @actions, loc('Preferences saved for dashboards in menu.');
-        }
-        else {
-            push @actions, $msg;
-        }
+my %selected;
+
+my ($default_dashboards) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('DashboardsInMenu');
+my $dashboard_pref
+    = $UserObj->Preferences( 'DashboardsInMenu', $default_dashboards ? $default_dashboards->Content : () );
+
+# prefs returns an array of Dashboard ID's
+my $selected_dashboard_ids = $dashboard_pref->{'dashboards'} || [];
+
+my @selected_dashboards;
+foreach my $id ( @{$selected_dashboard_ids} ) {
+    my $attribute = RT::Attribute->new( RT->SystemUser );
+    my ($ret, $msg) = $attribute->Load( $id );
+    unless ( $ret ) {
+        RT::Logger->error( "Could not load dashboard: $id" );
+        next;
     }
-);
 
-$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) for ( $dashboard_pane, $report_pane );
+    push @selected_dashboards, {
+      id      => $id,
+      name    => $attribute->Description,
+      label   => $attribute->Description,
+      type    => 'dashboard'
+    };
+}
+$selected{'dashboard'} = \@selected_dashboards;
 
+my $report_pref = $UserObj->Preferences('ReportsInMenu');
+unless ($report_pref) {
+    my ($defaults) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('ReportsInMenu');
+    $report_pref = $defaults ? $defaults->Content : {};
+}
+my @report_pref_sanitized = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ $report_pref };
+$selected{'report'} = \@report_pref_sanitized || [];
 </%init>
+
 <%ARGS>
 $id => undef
 </%ARGS>

commit daadbd779efe4a1418301a831c16dae40ba20aec
Author: craig kaiser <craig at bestpractical.com>
Date:   Tue Jun 30 08:11:38 2020 -0400

    Convert Admin/Global/DashboardsInMenu.html to drag and drop UI

diff --git a/share/html/Admin/Global/DashboardsInMenu.html b/share/html/Admin/Global/DashboardsInMenu.html
index 10ba198294..21982c5ec0 100644
--- a/share/html/Admin/Global/DashboardsInMenu.html
+++ b/share/html/Admin/Global/DashboardsInMenu.html
@@ -49,98 +49,147 @@
 <& /Elements/Tabs &>
 
 <& /Elements/ListActions, actions => \@actions &>
-<&|/Widgets/TitleBox, title => loc('Dashboards in menu'), bodyclass => "" &>
-<& /Widgets/SelectionBox:show, self => $dashboard_pane &></&>
 
-<&|/Widgets/TitleBox, title => loc('Reports in menu'), bodyclass => "" &>
-<& /Widgets/SelectionBox:show, self => $report_pane &></&>
+<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { dashboard => loc('Dashboards in menu') },
+    sections  => [{
+                    id    => 'dashboards',
+                    label => loc("Dashboards"),
+                    items => \@dashboard_components,
+                }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="dashboard_id" value="DashboardsInMenu">
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
+<form method="post" name="UpdateSearches" class="mx-auto max-width-lg">
+  <& /Widgets/SearchSelection,
+    pane_name => { report => loc('Reports in menu') },
+    sections  => [{
+                  id    => 'reports',
+                  label => loc("Reports"),
+                  items => \@report_components,
+              }],
+    selected  => \%selected,
+    filters   => [],
+  &>
+  <input type="hidden" name="dashboard_id" value="ReportsInMenu">
+
+  <& /Elements/Submit, Name => "UpdateSearches", Label => loc('Save') &>
+</form>
+
 <%init>
 my @actions;
+my $title = loc("Customize").' '.loc("reports menu");
 my $sys = RT::System->new( $session{'CurrentUser'} );
 
 my $has_right = $session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser');
 
-my ($dashboard_attr) = $sys->Attributes->Named('DashboardsInMenu');
-my $default_dashboards_in_menu =
-    $dashboard_attr && $dashboard_attr->Content->{dashboards}
-  ? $dashboard_attr->Content->{dashboards}
-  : [];
-
-use RT::Dashboards;
-my $dashboards = RT::Dashboards->new( $RT::SystemUser );
-$dashboards->LimitToPrivacy('RT::System-' . $sys->id);
+my @dashboard_components = map {{ type => 'dashboard', id => $_->id, name => $_->Name, label => $_->Name }} $m->comp("/Dashboards/Elements/ListOfDashboards", IncludeSuperuserGroups => 1 );
+my @report_components = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ ListOfReports() };
 
-my @dashboards;
-while ( my $dashboard = $dashboards->Next ) {
-    push @dashboards, [$dashboard->id, $dashboard->Name];
-}
+my ($dashboard_attr) = $sys->Attributes->Named('DashboardsInMenu');
+my ($reports_attr) = RT::System->new( RT->SystemUser )->Attributes->Named('ReportsInMenu');
 
-my ($dashboard_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action => 'DashboardsInMenu.html',
-    panes => ['dashboards_in_menu'],
-    ReadOnly => !$has_right,
-    items => \@dashboards,
-    current_portlets => $default_dashboards_in_menu,
-    OnSave => sub {
-        my ( $conf ) = @_;
-        my ( $status, $msg );
-
-        if (!$has_right) {
-            push @actions, loc( 'Permission Denied' );
-        }
-        elsif ( $dashboard_attr ) {
-            ($status, $msg) = $dashboard_attr->SetContent($conf);
+if ($ARGS{UpdateSearches}) {
+    if ( !$has_right ) {
+        push @actions, loc('Permission Denied');
+    }
+    else {
+        if ( $ARGS{'dashboard_id'} eq 'DashboardsInMenu' ) {
+            my @dashboard_ids;
+
+            my $dashboard_names = ref $ARGS{'dashboard'} eq 'ARRAY' ? $ARGS{'dashboard'} : [$ARGS{'dashboard'}];
+            foreach my $name ( @{$dashboard_names} ) {
+                next unless $name;
+                $name =~ s/dashboard-//;
+
+                my $attribute = RT::Attribute->new( $session{'CurrentUser'} );
+
+                my ($ret, $msg) = $attribute->LoadByCols( Name => 'Dashboard', Description => $name );
+                if ( $ret ) {
+                    push @dashboard_ids, $attribute->Id;
+                }
+                else {
+                    RT::Logger->error( "Could not load dashboard: $msg" );
+                    push @actions, "Could not load dashboard $name";
+                }
+            }
+            my ( $ok, $msg );
+            if ( $dashboard_attr ) {
+                ( $ok, $msg ) = $dashboard_attr->SetContent({ dashboards => \@dashboard_ids });
+            }
+            else {
+                $dashboard_attr = RT::Attribute->new($RT::SystemUser);
+                ( $ok, $msg ) = $dashboard_attr->Create(
+                    Name    => 'DashboardsInMenu',
+                    Object  => $sys,
+                    Content => { 'dashboards' => \@dashboard_ids },
+                );
+            }
+            push @actions, $ok ? loc('Global dashboards in menu saved.') : $msg;
+            delete $session{'dashboards_in_menu'};
         }
         else {
-            $dashboard_attr = RT::Attribute->new($RT::SystemUser);
-            ( $status, $msg ) = $dashboard_attr->Create(
-                Name    => 'DashboardsInMenu',
-                Object  => $sys,
-                Content => $conf,
-            );
+          my $report_names = ref $ARGS{'report'} eq 'ARRAY' ? $ARGS{'report'} : [$ARGS{'report'}];
+          my @ret;
+          foreach my $report ( @report_components ) {
+              last unless $report_names->[0];
+
+              push @ret, $report if grep { $_ =~ /report-$report->{'name'}/ } @{$report_names};
+          }
+          my ( $ok, $msg );
+          if ( $reports_attr ) {
+              ( $ok, $msg ) = $reports_attr->SetContent( \@ret );
+          }
+          else {
+              $reports_attr = RT::Attribute->new($RT::SystemUser);
+              ( $ok, $msg ) = $reports_attr->Create(
+                  Name    => 'ReportsInMenu',
+                  Object  => $sys,
+                  Content => { 'reports' => \@ret },
+              );
+          }
+          push @actions, $ok ? loc('Preferences saved for reports in menu.') : $msg;
+          delete $session{'reports_in_menu'};
         }
-        push @actions, $status ? loc('Global dashboards in menu saved.') : $msg;
     }
-);
-
-my ($reports_attr) = RT::System->new( RT->SystemUser )->Attributes->Named('ReportsInMenu');
-
-my ( @reports, %reports );
-for my $report ( @{ ListOfReports() } ) {
-    push @reports, [ $report->{id}, $report->{title} ];
-    $reports{ $report->{id} } = $report;
 }
 
-my ($report_pane) = $m->comp(
-    '/Admin/Elements/ConfigureDashboardsInMenu',
-    Action           => 'DashboardsInMenu.html',
-    panes            => ['reports_in_menu'],
-    ReadOnly         => !$has_right,
-    items            => \@reports,
-    current_portlets => [ map { $_->{id} } @{ $reports_attr->Content || [] } ],
-    OnSave           => sub {
-        my ($conf) = @_;
-        my ( $status, $msg );
-
-        if ( !$has_right ) {
-            push @actions, loc('Permission Denied');
-        }
-        else {
-            my $system_reports = [];
-            foreach my $id ( @{ $conf->{dashboards} } ) {
-                push @$system_reports, $reports{$id} if $reports{$id};
-            }
+my %selected;
 
-            ( $status, $msg ) = $reports_attr->SetContent($system_reports);
-            push @actions, $msg unless $status;
-        }
-        push @actions, $status ? loc('Global reports in menu saved.') : $msg;
+my $default_dashboards_in_menu =
+    $dashboard_attr && $dashboard_attr->Content
+  ? $dashboard_attr->Content
+  : { dashboards => [] };
+
+# prefs returns an array of Dashboard ID's
+my $selected_dashboard_ids = $default_dashboards_in_menu->{'dashboards'} || [];
+
+my @selected_dashboards;
+foreach my $id ( @{$selected_dashboard_ids} ) {
+    my $attribute = RT::Attribute->new( RT->SystemUser );
+    my ($ret, $msg) = $attribute->Load( $id );
+    unless ( $ret ) {
+        RT::Logger->error( "Could not load dashboard: $id" );
+        next;
     }
-);
 
-$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_ ) for ( $dashboard_pane, $report_pane );
+    push @selected_dashboards, {
+      id      => $id,
+      name    => $attribute->Description,
+      label   => $attribute->Description,
+      type    => 'dashboard'
+    };
+}
+$selected{'dashboard'} = \@selected_dashboards;
 
+my $report_pref = $reports_attr ? $reports_attr->Content : [];
 
+my @report_pref_sanitized = map { {%$_, name => $_->{'title'}, type => 'report', label => $_->{'title'} } } @{ $report_pref };
+$selected{'report'} = \@report_pref_sanitized || [];
 </%init>
-

commit 21915ad0031627b8b5da6af5c3ed7fcb53d74ea4
Author: craig kaiser <craig at bestpractical.com>
Date:   Wed Jul 1 10:20:38 2020 -0400

    Update dashboard tests for drag and drop UI

diff --git a/t/web/dashboards-in-menu.t b/t/web/dashboards-in-menu.t
index ea7d3b1dba..61854a281c 100644
--- a/t/web/dashboards-in-menu.t
+++ b/t/web/dashboards-in-menu.t
@@ -18,18 +18,56 @@ $system_bar->Save(
 
 ok( $m->login(), "logged in" );
 
+my $root = RT::CurrentUser->new( $RT::SystemUser );
+ok( $root->Load('root') );
+
 diag "global setting";
 # in case "RT at a glance" contains dashboards stuff.
 $m->get_ok( $baseurl . "/Search/Simple.html" );
 ok( !$m->find_link( text => 'system foo' ), 'no system foo link' );
 $m->get_ok( $baseurl."/Admin/Global/DashboardsInMenu.html");
 
-my $form_name = 'SelectionBox-dashboards_in_menu';
-$m->form_name($form_name);
+my $args = {
+    UpdateSearches => "Save",
+    dashboard_id   => "DashboardsInMenu",
+    dashboard      => ( "dashboard-".$system_foo->Name )
+};
+
+my $res = $m->post(
+    $baseurl . '/Admin/Global/DashboardsInMenu.html',
+    $args,
+);
+
+my ($dashboard_attr) = RT->System->Attributes->Named('DashboardsInMenu');
+is_deeply( $dashboard_attr->Content, { dashboards => [ $system_foo->Id ] }, "DashboardsInMenu attribute correctly updated" );
+
+is( $res->code, 200, "remove all dashboards from dashboards menu except 'system foo'" );
+$m->content_contains( 'Global dashboards in menu saved.' );
+
+$args = {
+    UpdateSearches => "Save",
+    dashboard_id   => "ReportsInMenu",
+    report         => 'report-Created in a date range'
+};
 
-$m->field('dashboards_in_menu-Available' => [$system_foo->id],);
-$m->click_button(name => 'add');
-$m->content_contains('Global dashboards in menu saved.', 'saved');
+$res = $m->post(
+    $baseurl . '/Admin/Global/DashboardsInMenu.html',
+    $args,
+);
+my ($report_attr) = RT::System->new( RT->SystemUser )->Attributes->Named('ReportsInMenu');
+
+is_deeply( @{$report_attr->Content}, {
+    id     =>  "createdindaterange",
+    path   =>  "/Reports/CreatedByDates.html",
+    title  =>  "Created in a date range",
+    type   => 'report',
+    name   => 'Created in a date range',
+    label  => 'Created in a date range',
+  }, "ReportsInMenu attribute correctly updated"
+);
+
+is( $res->code, 200, "remove all reports from reports menu except 'Created in a date range'" );
+$m->content_contains( 'Preferences saved for reports in menu.' );
 
 $m->logout;
 ok( $m->login(), "relogged in" );
@@ -39,8 +77,6 @@ $m->follow_link_ok( { text => 'system foo' }, 'follow system foo link' );
 $m->title_is( 'system foo Dashboard', 'got system foo dashboard page' );
 
 diag "setting in admin users";
-my $root = RT::CurrentUser->new( $RT::SystemUser );
-ok( $root->Load('root') );
 my $self_foo = RT::Dashboard->new($root);
 $self_foo->Save( Name => 'self foo', Privacy => 'RT::User-' . $root->id );
 my $self_bar = RT::Dashboard->new($root);
@@ -48,39 +84,45 @@ $self_bar->Save( Name => 'self bar', Privacy => 'RT::User-' . $root->id );
 
 ok( !$m->find_link( text => 'self foo' ), 'no self foo link' );
 $m->get_ok( $baseurl."/Admin/Users/DashboardsInMenu.html?id=" . $root->id);
-$m->form_name($form_name);
-$m->field('dashboards_in_menu-Available' => [$self_foo->id]);
-$m->click_button(name => 'add');
-$m->content_contains( 'Preferences saved for dashboards in menu.',
-    'prefs saved' );
-$m->form_name($form_name);
-$m->field('dashboards_in_menu-Selected' => [$system_foo->id]);
-$m->content_contains( 'Preferences saved for dashboards in menu.',
-    'prefs saved' );
-$m->click_button(name => 'remove');
 
-$m->logout;
-ok( $m->login(), "relogged in" );
-$m->get_ok( $baseurl . "/Search/Simple.html" );
-ok( !$m->find_link( text => 'system foo' ), 'no system foo link' );
-$m->follow_link_ok( { text => 'self foo' }, 'follow self foo link' );
-$m->title_is( 'self foo Dashboard', 'got self foo dashboard page' );
+$args = {
+    UpdateSearches => "Save",
+    dashboard_id   => "DashboardsInMenu",
+    dashboard      => [ "dashboard-".$self_foo->Name ]
+};
+
+$res = $m->post(
+    $baseurl . '/Admin/Users/DashboardsInMenu.html?id='.$root->Id,
+    $args,
+);
+
+my $dashboard_prefs = $root->Preferences('DashboardsInMenu');
+is_deeply( $dashboard_prefs, { dashboards => [ $self_foo->Id ] }, "DashboardsInMenu attribute correctly updated for user" );
+
+is( $res->code, 200, "Add dashboard ".$self_foo->Name." to user DashboardsInMenu prefs" );
+$m->content_contains( 'Preferences saved for dashboards in menu.' );
 
 diag "setting in prefs";
 $m->get_ok( $baseurl."/Prefs/DashboardsInMenu.html");
-$m->form_name($form_name);
-$m->field('dashboards_in_menu-Available' => [$self_bar->id]);
-$m->click_button(name => 'add');
-$m->content_contains( 'Preferences saved for dashboards in menu.',
-    'prefs saved' );
-$m->follow_link_ok( { text => 'self bar' }, 'follow self bar link' );
-$m->title_is( 'self bar Dashboard', 'got self bar dashboard page' );
-
-diag "Test deleting dashboard";
-$m->follow_link_ok( { text => 'self foo' }, 'follow self foo link' );
-$m->follow_link_ok( { text => 'Basics' }, 'Click dashboard Basics' );
-$m->form_name('ModifyDashboard');
-$m->click_button(name => 'Delete');
+
+$args = {
+    UpdateSearches => "Save",
+    dashboard_id   => "DashboardsInMenu",
+    dashboard      => "dashboard-".$self_bar->Name
+};
+
+$res = $m->post(
+    $baseurl . '/Prefs/DashboardsInMenu.html',
+    $args,
+);
+
+$root = RT::CurrentUser->new( $RT::SystemUser );
+ok( $root->Load('root') );
+$dashboard_prefs = $root->Preferences('DashboardsInMenu');
+is_deeply( $dashboard_prefs, { dashboards => [ $self_bar->Id ] }, "DashboardsInMenu user pref correctly updated" );
+
+is( $res->code, 200, "Add dashboard ".$self_bar->Name." to user DashboardsInMenu prefs" );
+$m->content_contains( 'Preferences saved for dashboards in menu.' );
 
 diag "Reset dashboard menu";
 $m->get_ok( $baseurl."/Prefs/DashboardsInMenu.html");
@@ -90,6 +132,110 @@ $m->content_contains( 'Preferences saved', 'prefs saved' );
 ok( $m->find_link( text => 'system foo' ), 'got system foo link' );
 ok( !$m->find_link( text => 'self bar' ), 'no self bar link' );
 
+foreach my $test_path ( '/Prefs/DashboardsInMenu.html', '/Admin/Global/DashboardsInMenu.html', '/Admin/Users/DashboardsInMenu.html' ) {
+    diag "Testing $test_path";
+    {
+        my @tests = (
+          {
+              args => {
+                UpdateSearches => "Save",
+                dashboard_id   => "DashboardsInMenu",
+                dashboard      => [  ],
+              },
+              ret => { dashboards => [  ] }
+          },
+          {
+              args => {
+                UpdateSearches => "Save",
+                dashboard_id   => "DashboardsInMenu",
+                dashboard      => [ "dashboard-".$system_foo->Name ],
+              },
+              ret => { dashboards => [ $system_foo->Id ] }
+          },
+          {
+              args => {
+                UpdateSearches => "Save",
+                dashboard_id   => "DashboardsInMenu",
+                dashboard      => [ "dashboard-".$system_foo->Name, "dashboard-".$system_bar->Name ],
+              },
+              ret => { dashboards => [ $system_foo->Id, $system_bar->Id ] }
+          }
+        );
+
+        foreach my $test ( @tests ) {
+            $m->get_ok( $baseurl."$test_path?id=".$root->Id );
+
+            my $res = $m->post(
+                $baseurl."$test_path?id=".$root->Id,
+                $test->{'args'},
+            );
+
+            my $msg;
+            if ( $test_path eq '/Admin/Global/DashboardsInMenu.html' ) {
+                $msg = 'Global dashboards in menu saved.';
+            }
+            else {
+                $msg = 'Preferences saved for dashboards in menu.';
+            }
+
+            is( $res->code, 200, "Update dashboards" );
+            $m->content_contains( $msg );
+
+            my $dashboard_attr;
+            if ( $test_path eq '/Admin/Global/DashboardsInMenu.html' ) {
+                my $sys = RT::System->new( $root );
+                ($dashboard_attr) = $sys->Attributes->Named('DashboardsInMenu');
+                $dashboard_attr = $dashboard_attr->Content;
+            }
+            else {
+                $root = RT::CurrentUser->new( $RT::SystemUser );
+                ok( $root->Load('root') );
+                $dashboard_attr = $root->Preferences( 'DashboardsInMenu' );
+            }
+            is_deeply( $dashboard_attr, $test->{'ret'}, "DashboardsInMenu attribute correctly updated" );
+        }
+
+        @tests = (
+          {
+              args => {
+                UpdateSearches => "Save",
+                dashboard_id   => "ReportsInMenu",
+                report         => [ "report-Created in a date range" ],
+              },
+              ret => [{
+                  id     =>  "createdindaterange",
+                  path   =>  "/Reports/CreatedByDates.html",
+                  title  =>  "Created in a date range",
+                  type   => 'report',
+                  name   => 'Created in a date range',
+                  label  => 'Created in a date range',
+              }]
+          },
+        );
+
+        foreach my $test ( @tests ) {
+            $m->get_ok( $baseurl."$test_path?id=".$root->Id );
+            my $res = $m->post(
+                $baseurl."$test_path?id=".$root->Id,
+                $test->{'args'},
+            );
+
+            my $report_attr;
+            if ( $test_path eq '/Admin/Global/DashboardsInMenu.html' ) {
+                my $sys = RT::System->new( $root );
+                ($report_attr) = $sys->Attributes->Named('ReportsInMenu');
+                $report_attr = $report_attr->Content;
+            }
+            else {
+                $root = RT::CurrentUser->new( $RT::SystemUser );
+                ok( $root->Load('root') );
+                $report_attr = $root->Preferences( 'ReportsInMenu' );
+            }
+            is_deeply( $report_attr, $test->{'ret'} );
+        }
+    }
+}
+
 diag "Delete system dashboard";
 $m->get_ok( $baseurl . "/Dashboards/index.html" );
 $m->follow_link_ok( { text => 'system foo' }, 'follow self foo link' );

commit 4067f1762134ca8c10e81e3fd54f41aa50d9a9ec
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jul 8 03:55:01 2020 +0800

    No need to show filters select if there are no filters available

diff --git a/share/html/Widgets/SearchSelection b/share/html/Widgets/SearchSelection
index 9ec3b16efe..4747f59738 100644
--- a/share/html/Widgets/SearchSelection
+++ b/share/html/Widgets/SearchSelection
@@ -54,6 +54,7 @@
             <div class="col-auto">
               <input type="search" class="field form-control" name="search" placeholder="<&|/l&>Search…</&>" autocomplete="off">
             </div>
+%           if ( @filters ) {
             <div class="col-auto">
               <select class="form-control selectpicker" name="filter">
                   <option value=""><&|/l&>All Types</&></option>
@@ -63,6 +64,7 @@
 % }
               </select>
             </div>
+%           }
           </div>
         </div>
 

commit 6ad87d14afa5659265cfa299002b95dd475b2928
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jul 8 04:40:31 2020 +0800

    Allow selectionboxes to expand automatically to some extent
    
    Previously we hard-coded height, which is inconvenient when there are
    few or a bit too many items. Besides, 526px is probably ok for MyRT
    pages, but too big for default DashboardsInMenu pages.
    
    Here we set min/max height instead so they can expand automatically in
    most cases.

diff --git a/share/static/css/elevator-light/forms.css b/share/static/css/elevator-light/forms.css
index c536ba0809..e408ecd617 100644
--- a/share/static/css/elevator-light/forms.css
+++ b/share/static/css/elevator-light/forms.css
@@ -420,14 +420,16 @@ textarea.code {
 }
 
 .selectionbox-js .source .contents {
-    height: 526px;
+    min-height: 250px; /* to be consistent with the following .destination */
+    max-height: 1000px;
 }
 
 /* include ul rule specifically to make the drop target work when there are
    no selected searches */
 .selectionbox-js .destination .contents,
 .selectionbox-js .destination .contents ul {
-    height: 250px;
+    min-height: 250px;
+    max-height: 500px;
 }
 
 .selectionbox-js h2 {

commit 1dffdb554ce34e6fb2746ef42bd8b5f25bdd3faf
Merge: ae7a4bd0cc 6ad87d14af
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jul 8 06:38:29 2020 +0800

    Merge branch '5.0/search-selection-for-dashboards-menus' into 5.0.0-releng


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


More information about the rt-commit mailing list