[Rt-commit] rt branch, 4.4/empty-dashboard-mail, created. rt-4.4.0rc2-22-gf8fc426

Shawn Moore shawn at bestpractical.com
Wed Jan 6 16:15:06 EST 2016


The branch, 4.4/empty-dashboard-mail has been created
        at  f8fc426e0b86fbc6fb750c5e8abed3119e46ecaa (commit)

- Log -----------------------------------------------------------------
commit f8fc426e0b86fbc6fb750c5e8abed3119e46ecaa
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Nov 17 17:52:53 2015 +0000

    Let users choose to suppress dashboards with no results

diff --git a/lib/RT/Dashboard/Mailer.pm b/lib/RT/Dashboard/Mailer.pm
index 1786c06..261a512 100644
--- a/lib/RT/Dashboard/Mailer.pm
+++ b/lib/RT/Dashboard/Mailer.pm
@@ -272,12 +272,24 @@ SUMMARY
     local $HTML::Mason::Commands::session{CurrentUser} = $currentuser;
     local $HTML::Mason::Commands::r = RT::Dashboard::FakeRequest->new;
 
+    my $HasResults = undef;
+
     my $content = RunComponent(
         '/Dashboards/Render.html',
-        id      => $dashboard->Id,
-        Preview => 0,
+        id         => $dashboard->Id,
+        Preview    => 0,
+        HasResults => \$HasResults,
     );
 
+    if ($subscription->SubValue('SuppressIfEmpty')) {
+        # undef means there were no searches, so we should still send it (it's just portlets)
+        # 0 means there was at least one search and none had any result, so we should suppress it
+        if (defined($HasResults) && !$HasResults) {
+            $RT::Logger->debug("Not sending because there are no results and the subscription has SuppressIfEmpty");
+            return;
+        }
+    }
+
     if ( RT->Config->Get('EmailDashboardRemove') ) {
         for ( RT->Config->Get('EmailDashboardRemove') ) {
             $content =~ s/$_//g;
diff --git a/share/html/Dashboards/Elements/ShowPortlet/component b/share/html/Dashboards/Elements/ShowPortlet/component
index 3b54da2..6a90aa8 100644
--- a/share/html/Dashboards/Elements/ShowPortlet/component
+++ b/share/html/Dashboards/Elements/ShowPortlet/component
@@ -50,6 +50,7 @@ $Dashboard
 $Portlet
 $Rows => 20
 $Preview => 0
+$HasResults
 </%args>
 <%init>
 my $full_path = $Portlet->{path};
@@ -60,5 +61,5 @@ my $allowed = grep { $_ eq $path } @{RT->Config->Get('HomepageComponents')};
 % if (!$allowed) {
 %     $m->out( $m->interp->apply_escapes( loc("Invalid portlet [_1]", $path), "h" ) );
 % } else {
-%     $m->comp($full_path);
+%     $m->comp($full_path, HasResults => $HasResults);
 % }
diff --git a/share/html/Dashboards/Elements/ShowPortlet/dashboard b/share/html/Dashboards/Elements/ShowPortlet/dashboard
index 3c35ea8..84c6ef9 100644
--- a/share/html/Dashboards/Elements/ShowPortlet/dashboard
+++ b/share/html/Dashboards/Elements/ShowPortlet/dashboard
@@ -52,6 +52,7 @@ $Portlet
 $Rows => 20
 $Preview => 0
 $Depth => 0
+$HasResults
 </%args>
 <%init>
 my $current_dashboard;
@@ -76,12 +77,13 @@ Abort("Possible recursive dashboard detected.") if $Depth > 8;
 <%perl>
 for my $portlet (@panes) {
     $m->comp($portlet->{portlet_type},
-        Portlet   => $portlet,
-        Rows      => $Rows,
-        Preview   => $Preview,
-        Dashboard => $current_dashboard,
-        Pane      => $Pane,
-        Depth     => $Depth + 1,
+        Portlet    => $portlet,
+        Rows       => $Rows,
+        Preview    => $Preview,
+        Dashboard  => $current_dashboard,
+        Pane       => $Pane,
+        Depth      => $Depth + 1,
+        HasResults => $HasResults
     );
 }
 </%perl>
diff --git a/share/html/Dashboards/Elements/ShowPortlet/search b/share/html/Dashboards/Elements/ShowPortlet/search
index d190295..2910c36 100644
--- a/share/html/Dashboards/Elements/ShowPortlet/search
+++ b/share/html/Dashboards/Elements/ShowPortlet/search
@@ -50,6 +50,7 @@ $Dashboard
 $Portlet
 $Rows => 20
 $Preview => 0
+$HasResults
 </%args>
 <%init>
 my @for_showsearch = $Dashboard->ShowSearchName($Portlet);
@@ -57,7 +58,8 @@ my @for_showsearch = $Dashboard->ShowSearchName($Portlet);
 
 <& /Elements/ShowSearch,
     @for_showsearch,
-    Override       => { Rows => $Rows },
-    hideable       => $Preview,
+    Override      => { Rows => $Rows },
+    hideable      => $Preview,
     ShowCustomize => $Preview,
+    HasResults    => $HasResults,
 &>
diff --git a/share/html/Dashboards/Render.html b/share/html/Dashboards/Render.html
index 0306077..6078c3a 100644
--- a/share/html/Dashboards/Render.html
+++ b/share/html/Dashboards/Render.html
@@ -122,12 +122,13 @@ my $title = loc '[_1] Dashboard', $Dashboard->Name;
 my $show_cb = sub {
     my $pane = shift;
     $m->comp('Elements/ShowPortlet/dashboard',
-        Portlet   => $Dashboard,
-        Rows      => $rows,
-        Preview   => $Preview,
-        Dashboard => $Dashboard,
-        Pane      => $pane,
-        Depth     => 0,
+        Portlet    => $Dashboard,
+        Rows       => $rows,
+        Preview    => $Preview,
+        Dashboard  => $Dashboard,
+        Pane       => $pane,
+        Depth      => 0,
+        HasResults => $HasResults,
     );
 };
 
@@ -140,5 +141,6 @@ my $Refresh = $Preview
 <%ARGS>
 $id => undef
 $Preview => 1
+$HasResults => undef
 </%ARGS>
 
diff --git a/share/html/Dashboards/Subscription.html b/share/html/Dashboards/Subscription.html
index cb45f1b..53772f5 100644
--- a/share/html/Dashboards/Subscription.html
+++ b/share/html/Dashboards/Subscription.html
@@ -173,6 +173,12 @@
 %   }
 </select>
 </td></tr>
+
+<tr><td align="right"><input type="checkbox" id="SuppressIfEmpty" name="SuppressIfEmpty" value="1" <% $fields{'SuppressIfEmpty'} ? 'checked="checked"' : "" |n %> /></td>
+<td><label for="SuppressIfEmpty"><&|/l&>Suppress if empty (Check this to avoid sending mail if all searches have no results)</&></label><br />
+<input type="hidden"class="hidden" name="SuppressIfEmpty-Magic" value=1 />
+</td></tr>
+
 </table>
 </&>
 
@@ -228,6 +234,7 @@ my %fields = (
     Recipients  => { Users => [], Groups => [] },
     Fow         => 1,
     Counter     => 0,
+    SuppressIfEmpty => 0,
 );
 
 # update any fields with the values from the subscription object
diff --git a/share/html/Elements/CollectionList b/share/html/Elements/CollectionList
index 99a2f64..471277d 100644
--- a/share/html/Elements/CollectionList
+++ b/share/html/Elements/CollectionList
@@ -51,6 +51,10 @@ if (!$Collection && $Class eq 'RT::Tickets') {
     $Collection->FromSQL($Query);
 }
 
+# flip HasResults from undef to 0 to indicate there was a search, so
+# dashboard mail can be suppressed if there are no results
+$$HasResults = 0 if $HasResults && !defined($$HasResults);
+
 $TotalFound = $Collection->CountAll() unless defined $TotalFound;
 return '' if !$TotalFound && !$ShowEmpty;
 
@@ -159,6 +163,8 @@ while ( my $record = $Collection->Next ) {
         Warning   => $warning,
         Classes   => $Classes,
     );
+
+    $$HasResults++ if $HasResults;
 }
 
 $m->out('</table>');
@@ -202,4 +208,5 @@ $ShowNavigation => 1
 $ShowHeader     => 1
 $ShowEmpty      => 0
 $Query => 0
+$HasResults     => undef
 </%ARGS>
diff --git a/share/html/Elements/MyAssets b/share/html/Elements/MyAssets
index d2f1158..b7122a0 100644
--- a/share/html/Elements/MyAssets
+++ b/share/html/Elements/MyAssets
@@ -45,4 +45,7 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /User/Elements/AssetList, User => $session{'CurrentUser'}->UserObj, Roles => [qw(HeldBy)], Title => loc('My Assets') &>
+<& /User/Elements/AssetList, User => $session{'CurrentUser'}->UserObj, Roles => [qw(HeldBy)], Title => loc('My Assets'), HasResults => $HasResults &>
+<%ARGS>
+$HasResults => undef
+</%ARGS>
diff --git a/share/html/Elements/MyReminders b/share/html/Elements/MyReminders
index f4fbf5d..9c85a55 100644
--- a/share/html/Elements/MyReminders
+++ b/share/html/Elements/MyReminders
@@ -50,10 +50,13 @@
     title => loc("My reminders"),
     title_href => RT->Config->Get('WebPath') . '/Tools/MyReminders.html' &>
 
-<& /Elements/ShowReminders &>
+<& /Elements/ShowReminders, HasResults => $HasResults &>
 
 </&>
 
 <%init>
 return unless RT->Config->Get('EnableReminders');
 </%init>
+<%ARGS>
+$HasResults => undef
+</%ARGS>
diff --git a/share/html/Elements/ShowReminders b/share/html/Elements/ShowReminders
index 61d8040..fd89f7c 100644
--- a/share/html/Elements/ShowReminders
+++ b/share/html/Elements/ShowReminders
@@ -64,6 +64,7 @@ $targets->{'allow_deleted_search'} = 1;
 $targets->FromSQL( "ReferredToBy = " . $reminder->id );
 
 if ( my $ticket= $targets->First ) {
+    $$HasResults++ if $HasResults;
 </%PERL>
 <tr class="<% $i%2 ? 'oddline' : 'evenline' %>">
 <td class="collection-as-table">
@@ -95,8 +96,13 @@ $tsql .= ' AND ( Due < "now" OR Due IS NULL )' if $OnlyOverdue;
 
 $reminders->FromSQL($tsql);
 $reminders->OrderBy( FIELD => 'Due', ORDER => 'ASC' );
+
+# flip HasResults from undef to 0 to indicate there was a search, so
+# dashboard mail can be suppressed if there are no results
+$$HasResults = 0 if $HasResults && !defined($$HasResults);
 </%INIT>
 
 <%ARGS>
 $OnlyOverdue => 0
+$HasResults => undef
 </%ARGS>
diff --git a/share/html/Elements/ShowSearch b/share/html/Elements/ShowSearch
index 52e628b..b355557 100644
--- a/share/html/Elements/ShowSearch
+++ b/share/html/Elements/ShowSearch
@@ -51,7 +51,7 @@
     titleright => $customize ? loc('Edit') : '',
     titleright_href => $customize,
     hideable => $hideable &>
-<& $query_display_component, hideable => $hideable, %$ProcessedSearchArg, ShowNavigation => 0, Class => 'RT::Tickets' &>
+<& $query_display_component, hideable => $hideable, %$ProcessedSearchArg, ShowNavigation => 0, Class => 'RT::Tickets', HasResults => $HasResults &>
 </&>
 <%init>
 my $search;
@@ -135,5 +135,6 @@ $SavedSearch    => undef
 %Override       => ()
 $IgnoreMissing  => undef
 $hideable       => 1
-$ShowCustomize => 1
+$ShowCustomize  => 1
+$HasResults     => undef
 </%ARGS>
diff --git a/share/html/User/Elements/AssetList b/share/html/User/Elements/AssetList
index e8eaec2..8c5564f 100644
--- a/share/html/User/Elements/AssetList
+++ b/share/html/User/Elements/AssetList
@@ -69,10 +69,12 @@ $m->callback( CallbackName => 'ModifyFormat', %ARGS, Format => \$Format );
         Order           => 'ASC',
         Format          => $Format,
         AllowSorting    => 0,
+        HasResults      => $HasResults,
         &>
 </&>
 <%args>
 $User
 $Title
 @Roles
+$HasResults => undef
 </%args>
diff --git a/t/mail/dashboard-empty.t b/t/mail/dashboard-empty.t
new file mode 100644
index 0000000..91ec031
--- /dev/null
+++ b/t/mail/dashboard-empty.t
@@ -0,0 +1,132 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef;
+use RT::Dashboard::Mailer;
+
+my $root = RT::Test->load_or_create_user( Name => 'root' );
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok( $m->login, 'logged in' );
+
+sub create_dashboard {
+    my ($name, $suppress_if_empty, $assets) = @_;
+
+    # first, create and populate a "suppress if empty" dashboard
+    $m->get_ok('/Dashboards/Modify.html?Create=1');
+    $m->form_name('ModifyDashboard');
+    $m->field( 'Name' => $name );
+    $m->click_button( value => 'Create' );
+
+    $m->follow_link_ok( { text => 'Content' } );
+    my $form  = $m->form_name('Dashboard-Searches-body');
+    my @input = $form->find_input('Searches-body-Available');
+
+    my $add_component = sub {
+        my $name = shift;
+        my ($dashboards_component) =
+          map { ( $_->possible_values )[1] }
+          grep { ( $_->value_names )[1] =~ $name } @input;
+        $form->value( 'Searches-body-Available' => $dashboards_component );
+        $m->click_button( name => 'add' );
+        $m->content_contains('Dashboard updated');
+    };
+
+    $add_component->('My Tickets') unless $assets;
+    $add_component->('MyAssets') if $assets;
+
+    $m->follow_link_ok( { text => 'Subscription' } );
+    $m->form_name('SubscribeDashboard');
+    $m->field( 'Frequency' => 'daily' );
+    $m->field( 'Hour'      => '06:00' );
+
+    $m->field( 'SuppressIfEmpty' => 1 ) if $suppress_if_empty;
+
+    $m->click_button( name => 'Save' );
+    $m->content_contains("Subscribed to dashboard $name");
+}
+
+create_dashboard('Suppress if empty', 1);
+
+diag 'no mail since the dashboard is suppressed if empty' if $ENV{'TEST_VERBOSE'};
+{
+    RT::Dashboard::Mailer->MailDashboards(All => 1);
+
+    my @mails = RT::Test->fetch_caught_mails;
+    is @mails, 0, "got no dashboard mail because the dashboard is empty";
+}
+
+create_dashboard('Always send', 0);
+
+diag 'one mail since one of two dashboards is suppressed if empty' if $ENV{'TEST_VERBOSE'};
+{
+    RT::Dashboard::Mailer->MailDashboards(All => 1);
+
+    my @mails = RT::Test->fetch_caught_mails;
+    is @mails, 1, "got a dashboard mail from the always-send dashboard";
+    my $content = parse_mail( $mails[0] )->bodyhandle->as_string;
+    ok($content =~ qr/highest priority tickets I own/);
+}
+
+RT::Test->create_ticket(
+    Queue     => 'General',
+    Subject   => 'a search result!',
+    Owner     => $root,
+);
+RT::Test->fetch_caught_mails; # dump ticket notifications
+
+diag 'two mails since both dashboards now have results' if $ENV{'TEST_VERBOSE'};
+{
+    RT::Dashboard::Mailer->MailDashboards(All => 1);
+
+    my @mails = RT::Test->fetch_caught_mails;
+    is @mails, 2, "got a dashboard mail from the always-send dashboard";
+
+    for my $mail (@mails) {
+        my $content = parse_mail( $mail )->bodyhandle->as_string;
+        ok($content =~ qr/highest priority tickets I own/);
+        ok($content =~ qr/a search result!/);
+    }
+}
+
+create_dashboard('My Assets', 1, 1);
+
+diag 'two mails since no asset yet' if $ENV{'TEST_VERBOSE'};
+{
+    RT::Dashboard::Mailer->MailDashboards(All => 1);
+
+    my @mails = RT::Test->fetch_caught_mails;
+    is @mails, 2, "got 2 dashboard mails";
+
+    for my $mail (@mails) {
+        my $content = parse_mail( $mail )->bodyhandle->as_string;
+        ok($content =~ qr/highest priority tickets I own/);
+        ok($content =~ qr/a search result!/);
+    }
+}
+
+my $asset = RT::Asset->new( RT->SystemUser );
+my ($ok, $msg) = $asset->Create(
+    Catalog     => 'General assets',
+    HeldBy      => 'root at localhost',
+    Description => 'a computer asset',
+);
+ok($ok, $msg);
+
+{
+    RT::Dashboard::Mailer->MailDashboards(All => 1);
+
+    my @mails = RT::Test->fetch_caught_mails;
+    is @mails, 3, "got 3 dashboard mails";
+    my @contents = map { parse_mail( $_ )->bodyhandle->as_string } @mails;
+
+    ok($contents[0] =~ qr/highest priority tickets I own/);
+    ok($contents[0] =~ qr/a search result!/);
+    ok($contents[1] =~ qr/highest priority tickets I own/);
+    ok($contents[1] =~ qr/a search result!/);
+    ok($contents[2] =~ qr/a computer asset/);
+}
+
+undef $m;
+done_testing;
+

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


More information about the rt-commit mailing list