[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