[Rt-commit] rt branch, 5.0/search-selection-for-dashboards-menus, created. rt-5.0.0beta1-4-ga2425a97ea

Craig Kaiser craig at bestpractical.com
Thu Jul 2 05:30:45 EDT 2020


The branch, 5.0/search-selection-for-dashboards-menus has been created
        at  a2425a97ea49c8975edd957b3fb5e3973d47b6bc (commit)

- Log -----------------------------------------------------------------
commit 99401983281cb3f87387b5ff7ec35d30a414f628
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..01ba195a8a 100644
--- a/share/html/Prefs/DashboardsInMenu.html
+++ b/share/html/Prefs/DashboardsInMenu.html
@@ -50,31 +50,47 @@
 &>
 <& /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") &>
-<div class="mt-3 mb-1 ml-3">
-  <form method="post" action="DashboardsInMenu.html">
+<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" &>
+  <form method="post" action="/Prefs/DashboardsInMenu.html">
     <input type="submit" name="ResetDashboards" class="button form-control btn btn-primary" value="<% loc('Reset dashboards to default') %>">
   </form>
-</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">
+  <form method="post" action="/Prefs/DashboardsInMenu.html">
     <input type="submit" name="ResetReports" class="button form-control btn btn-primary" value="<% loc('Reset reports to default') %>">
   </form>
 </div>
@@ -93,72 +109,93 @@ if ( $ARGS{ResetDashboards} ) {
 }
 
 if ( $ARGS{ResetReports} ) {
-    if ( $user->Preferences('ReportsInMenu') ) {
-        # Empty ReportsInMenu pref means empty, not to use default,
-        # thus we need to delete preference instead.
-        my ( $ok, $msg ) = $user->DeletePreferences('ReportsInMenu');
-        push @results, $ok ? loc('Preferences saved.') : $msg;
-        delete $session{'reports_in_menu'};
-    }
+  if ( $user->Preferences('ReportsInMenu') ) {
+      # Empty ReportsInMenu pref means empty, not to use default,
+      # thus we need to delete preference instead.
+      my ( $ok, $msg ) = $user->DeletePreferences('ReportsInMenu');
+      push @results, $ok ? loc('Preferences saved.') : $msg;
+      delete $session{'reports_in_menu'};
+  }
 }
 
-my ($default_dashboards) =
-RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu');
-
-my $dashboard_pref =
-  $session{CurrentUser}->UserObj->Preferences( 'DashboardsInMenu',
-    $default_dashboards ? $default_dashboards->Content : () );
-
-my $current_dashboards = $dashboard_pref->{dashboards} || [];
-
-my @dashboards = map { [$_->id, $_->Name] } $m->comp("/Dashboards/Elements/ListOfDashboards", IncludeSuperuserGroups => 0 );
-
-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 );
-        push @results, $ok ? loc('Preferences saved for dashboards in menu.') : $msg;
-        delete $session{'dashboards_in_menu'};
+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 @results, "Could not load dashboard $name";
+          }
+      }
+
+      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'};
+  }
+  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 ) = $user->SetPreferences( $ARGS{'dashboard_id'}, \@ret );
+    push @results, $ok ? loc('Preferences saved for reports in menu.') : $msg;
+    delete $session{'reports_in_menu'};
+  }
+}
+
+my %selected;
+
+my $dashboard_pref = $user->Preferences('DashboardsInMenu');
+unless ($dashboard_pref) {
+    my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu');
+    $dashboard_pref = $defaults ? $defaults->Content : {};
 }
 
-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;
-
-        delete $session{'reports_in_menu'};
+# 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 f5e8dade1c6d501f9c23be3628d58cf0547781e5
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..824e6a4870 100644
--- a/share/html/Admin/Users/DashboardsInMenu.html
+++ b/share/html/Admin/Users/DashboardsInMenu.html
@@ -45,133 +45,160 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Admin/Elements/Header, Title => $title  &>
-<& /Elements/Tabs &>
-
-<& /Elements/ListActions, actions => \@actions &>
-
-<&|/Widgets/TitleBox,
-    title => loc('Dashboards in menu'),
-    bodyclass => ""
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs
 &>
-<& /Widgets/SelectionBox:show, self => $dashboard_pane &>
-</&>
-
-<&|/Widgets/TitleBox, title => loc("Reset dashboards in menu") &>
-<div class="mt-3 mb-1 ml-3">
+<& /Elements/ListActions, actions => \@results &>
+
+<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="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" &>
   <form method="post" action="DashboardsInMenu.html">
-    <input type="hidden" name="id" value="<% $id %>" />
     <input type="submit" name="ResetDashboards" class="button form-control btn btn-primary" value="<% loc('Reset dashboards to default') %>">
   </form>
-</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="hidden" name="id" value="<% $id %>" />
     <input type="submit" name="ResetReports" class="button form-control btn btn-primary" value="<% loc('Reset reports to default') %>">
   </form>
 </div>
 </&>
 
-<%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);
+<%INIT>
+my @results;
+
+my $user = RT::User->new($session{'CurrentUser'});
+$user->Load($id) || Abort("Couldn't load user '" . ($id || '') . "'");
+my $title = loc("Reports menu for the user [_1]", $user->Name);
 
 if ( $ARGS{ResetDashboards} ) {
     # Empty DashboardsInMenu pref means to use system default.
-    my ( $ok, $msg ) = $UserObj->SetPreferences( 'DashboardsInMenu', {} );
-    push @actions, $ok ? loc( 'Preferences saved for user [_1].', $UserObj->Name ) : $msg;
+    my ( $ok, $msg ) = $user->SetPreferences( 'DashboardsInMenu', {} );
+    push @results, $ok ? loc( 'Preferences saved for user [_1].', $user->Name ) : $msg;
 }
 
 if ( $ARGS{ResetReports} ) {
-    if ( $UserObj->Preferences('ReportsInMenu') ) {
+    if ( $user->Preferences('ReportsInMenu') ) {
         # Empty ReportsInMenu pref means empty, not to use default,
         # thus we need to delete preference instead.
-        my ( $ok, $msg ) = $UserObj->DeletePreferences('ReportsInMenu');
-        push @actions, $ok ? loc( 'Preferences saved for user [_1].', $UserObj->Name ) : $msg;
+        my ( $ok, $msg ) = $user->DeletePreferences('ReportsInMenu');
+        push @results, $ok ? loc( 'Preferences saved for user [_1].', $user->Name ) : $msg;
     }
 }
 
-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 @results, "Could not load dashboard $name";
+          }
+      }
+
+      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'};
+  }
+  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 ) = $user->SetPreferences( $ARGS{'dashboard_id'}, \@ret );
+    push @results, $ok ? loc('Preferences saved for reports in menu.') : $msg;
+    delete $session{'reports_in_menu'};
+  }
+}
+
+my %selected;
+
+my $dashboard_pref = $user->Preferences('DashboardsInMenu');
+unless ($dashboard_pref) {
+    my ($defaults) = RT::System->new($session{'CurrentUser'})->Attributes->Named('DashboardsInMenu');
+    $dashboard_pref = $defaults ? $defaults->Content : {};
 }
 
-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;
-        }
+# 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>
 
-</%init>
 <%ARGS>
 $id => undef
 </%ARGS>

commit f11b27c69e2b2466014b0c48c5ce5a6c3ba59d42
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..ba705fcf42 100644
--- a/share/html/Admin/Global/DashboardsInMenu.html
+++ b/share/html/Admin/Global/DashboardsInMenu.html
@@ -48,99 +48,148 @@
 <& /Admin/Elements/Header, Title => loc("Reports menu") &>
 <& /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 &></&>
-<%init>
-my @actions;
+<& /Elements/ListActions, actions => \@results &>
+
+<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 @results;
+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 @results, 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 @results, "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 @results, $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 @results, $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;
 
-</%init>
+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 a2425a97ea49c8975edd957b3fb5e3973d47b6bc
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' );

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


More information about the rt-commit mailing list