[Bps-public-commit] rt-extension-spamfilter branch add-checkbox-selection created. 7bfcf78e6d1bb3ff845b659a40bb30a52ed352ec
BPS Git Server
git at git.bestpractical.com
Thu Jul 13 12:07:21 UTC 2023
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt-extension-spamfilter".
The branch, add-checkbox-selection has been created
at 7bfcf78e6d1bb3ff845b659a40bb30a52ed352ec (commit)
- Log -----------------------------------------------------------------
commit 7bfcf78e6d1bb3ff845b659a40bb30a52ed352ec
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date: Thu Jul 13 09:00:05 2023 -0300
Implement multiple selection of checkboxes holding shift key
Improve the selection of large number of Tickets/Messages by holding
shift key and clicking on the checkbox.
diff --git a/html/Tools/SpamFilter/List.html b/html/Tools/SpamFilter/List.html
index a312038..1bf7846 100644
--- a/html/Tools/SpamFilter/List.html
+++ b/html/Tools/SpamFilter/List.html
@@ -52,6 +52,10 @@
.custom-checkbox label {
white-space: nowrap;
}
+ /* allow multiple checkboxes to be checked holding shift key*/
+ .checkbox {
+ z-index: 1;
+ }
</style>
<script type="text/javascript">
jQuery( function() {
@@ -94,6 +98,38 @@
}
}
});
+ // Enable shift selection of checkboxes
+ lastReleaseSelected = null;
+ lastDeleteSelected = null;
+ ReleaseCheckboxes = jQuery('input.not_spam');
+ DeleteCheckboxes = jQuery('input.discard');
+ jQuery('input.not_spam,input.discard').click( function (e) {
+ // get id and split it
+ var id = this.id.split('-');
+ if (id[0] == 'Release') {
+ if (!lastReleaseSelected) {
+ lastReleaseSelected = this;
+ return;
+ }
+ if (e.shiftKey) {
+ var start = ReleaseCheckboxes.index(this);
+ var end = ReleaseCheckboxes.index(lastReleaseSelected);
+ ReleaseCheckboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastReleaseSelected.checked).change();
+ }
+ lastReleaseSelected = this;
+ } else {
+ if (!lastDeleteSelected) {
+ lastDeleteSelected = this;
+ return;
+ }
+ if (e.shiftKey) {
+ var start = DeleteCheckboxes.index(this);
+ var end = DeleteCheckboxes.index(lastDeleteSelected);
+ DeleteCheckboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastDeleteSelected.checked).change();
+ }
+ lastDeleteSelected = this;
+ }
+ });
});
</script>
commit 019d4bc4c42571034925494cb618be0d9394367c
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date: Thu Jul 13 09:03:23 2023 -0300
Add option to configure rows per page in spam list
diff --git a/html/Tools/SpamFilter/List.html b/html/Tools/SpamFilter/List.html
index 0b9a86b..a312038 100644
--- a/html/Tools/SpamFilter/List.html
+++ b/html/Tools/SpamFilter/List.html
@@ -159,7 +159,7 @@ unless ($Format) {
$Order ||= 'ASC';
$OrderBy ||= 'id';
-$Rows ||= $ARGS{RowsPerPage} || 50;
+$Rows ||= $ARGS{RowsPerPage} || RT->Config->Get('SpamListRowsPerPage') || 50;
$Page = 1 unless $Page && $Page > 0;
use RT::Spams;
diff --git a/lib/RT/Extension/SpamFilter.pm b/lib/RT/Extension/SpamFilter.pm
index 3b9b02c..d0cdec9 100644
--- a/lib/RT/Extension/SpamFilter.pm
+++ b/lib/RT/Extension/SpamFilter.pm
@@ -113,6 +113,8 @@ is shown below:
}
);
+ Set( $SpamListRowsPerPage, 50 );
+
=head2 C<@SpamFilters>
The C<@SpamFilters> array is an array of hashes. Each hash
@@ -146,6 +148,11 @@ presence of the spam header and then add the score you configure.
The C<$SpamFilterThreshold> is the score above which an incoming message
is considered to be spam and placed in the spam list.
+=head2 C<$SpamListRowsPerPage>
+
+The C<$SpamListRowsPerPage> is an optional configuration to change the
+number of rows to display per page in the spam list. Default is 50.
+
=head1 AUTHOR
Best Practical Solutions, LLC E<lt>modules at bestpractical.comE<gt>
commit eb51bb2ed637e0ac40025c57f3d70b305393ea66
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date: Thu Jul 13 08:58:20 2023 -0300
Implement checkbox selection for spam filter actions
It's now possible to select multiple spam filter actions and perform
bulk actions on them.
diff --git a/html/Elements/RT__Spam/ColumnMap b/html/Elements/RT__Spam/ColumnMap
index 339867d..1541667 100644
--- a/html/Elements/RT__Spam/ColumnMap
+++ b/html/Elements/RT__Spam/ColumnMap
@@ -53,25 +53,6 @@ $Attr => undef
<%once>
-# For readability, ncapsulate the button-generating code into a
-# function here rather than putting it inline in the big hash.
-my $buttons_sub = sub {
- my ($email) = @_;
-
- my $ret = '';
- if ($email->Status ne 'resolved') {
- $ret .= '<button type="button" class="create_user" name="Release-' . $email->id . '">' . loc('Not Spam') . '</button>';
- }
- if ($email->Status ne 'deleted') {
- $ret .= ' <button type="button" class="discard" name="Delete-' . $email->id . '">' . loc('Delete') . '</button>';
- }
-
- # Here's a magical thing... if you return a *reference* to a scalar,
- # the result is not HTML-escaped. If you just return a scalar, it is.
- # Hence the \ before $ret.
- return \$ret;
-};
-
my $COLUMN_MAP;
$COLUMN_MAP = {
@@ -111,9 +92,49 @@ $COLUMN_MAP = {
title => 'Score', # loc
value => sub { return $_[0]->Score }
},
- Disposition => {
- title => 'Disposition', #loc
- value => $buttons_sub,
+ NotSpam => {
+ # Here's a magical thing... if you return a *reference* to a scalar,
+ # the result is not HTML-escaped. If you just return a scalar, it is.
+ # Hence the \ before $ret.
+ title => sub {
+ return \qq{
+<div class="custom-control custom-checkbox">
+ <input type="checkbox" name="not_spam_all" id="not_spam_all" value="1" class="checkbox custom-control-input" />
+ <label class="custom-control-label" for="not_spam_all">Not Spam</label>
+</div>
+};
+ },
+ value => sub {
+ if ( $_[0]->Status ne 'resolved' ) {
+ return \(
+'<div class="custom-control custom-checkbox">
+ <input type="checkbox" name="Release" id="Release-'.$_[0]->id.'" value="'.$_[0]->id.'" class="not_spam checkbox custom-control-input" />
+ <label class="custom-control-label" for="Release-'.$_[0]->id.'"></label>
+</div>');
+ }
+ },
+ },
+ Delete => {
+ # Here's a magical thing... if you return a *reference* to a scalar,
+ # the result is not HTML-escaped. If you just return a scalar, it is.
+ # Hence the \ before $ret.
+ title => sub {
+ return \qq{
+<div class="custom-control custom-checkbox">
+ <input type="checkbox" name="discard_all" id="discard_all" value="1" class="checkbox custom-control-input" />
+ <label class="custom-control-label" for="discard_all">Delete</label>
+</div>
+};
+ },
+ value => sub {
+ if ( $_[0]->Status ne 'deleted' ) {
+ return \(
+'<div class="custom-control custom-checkbox">
+ <input type="checkbox" name="Delete" id="Delete-'.$_[0]->id.'" value="'.$_[0]->id.'" class="discard checkbox custom-control-input" />
+ <label class="custom-control-label" for="Delete-'.$_[0]->id.'"></label>
+</div>');
+ }
+ },
},
};
diff --git a/html/Tools/SpamFilter/List.html b/html/Tools/SpamFilter/List.html
index f5a969e..0b9a86b 100644
--- a/html/Tools/SpamFilter/List.html
+++ b/html/Tools/SpamFilter/List.html
@@ -48,19 +48,51 @@
<& /Elements/Header, Title => $title &>
<& /Elements/Tabs &>
+<style type="text/css">
+ .custom-checkbox label {
+ white-space: nowrap;
+ }
+</style>
<script type="text/javascript">
jQuery( function() {
- jQuery('button.create_user').click( function () {
- url = new URL(window.location.href);
- status = url.searchParams.get('Status') || 'new';
- bits = this.name.split('-');
- window.location.href = '?emailid=' + bits[1] + '&Action=' + bits[0] + '&Status=' + status;
+ // adjust the width of the checkboxes columns since it's not possible
+ // to add specific class to the th element
+ jQuery('#discard_all,#not_spam_all').closest('th').css('width', '1%');
+
+ jQuery('#not_spam_all').change( function () {
+ // toggle all checkboxes
+ jQuery('input.not_spam').prop('checked', this.checked).change();
+ jQuery('#discard_all').prop('checked', false);
});
- jQuery('button.discard').click( function () {
- url = new URL(window.location.href);
- status = url.searchParams.get('Status') || 'new';
- bits = this.name.split('-');
- window.location.href = '?emailid=' + bits[1] + '&Action=' + bits[0] + '&Status=' + status;
+ jQuery('#discard_all').change( function () {
+ // toggle all checkboxes
+ jQuery('input.discard').prop('checked', this.checked).change();
+ jQuery('#not_spam_all').prop('checked', false);
+ });
+ // check if the corresponding Release-X or Delete-X is already checked
+ // and uncheck it
+ jQuery('input.not_spam,input.discard').change( function () {
+ // get id and split it
+ var id = this.id.split('-');
+
+ if (!this.checked) {
+ // disable the oposite checkbox
+ if (id[0] == 'Release') {
+ jQuery('#not_spam_all').prop('checked', false);
+ } else {
+ jQuery('#discard_all').prop('checked', false);
+ }
+ return;
+ } else {
+ // disable the oposite checkbox
+ if (id[0] == 'Release') {
+ jQuery('#Delete-' + id[1]).prop('checked', false);
+ jQuery('#discard_all').prop('checked', false);
+ } else {
+ jQuery('#Release-' + id[1]).prop('checked', false);
+ jQuery('#not_spam_all').prop('checked', false);
+ }
+ }
});
});
</script>
@@ -68,6 +100,7 @@
<& /Elements/ListActions, actions => \@results &>
<div class="spams">
+<form method="post" enctype="multipart/form-data" name="SpamUpdate" id="SpamUpdate">
<& /Elements/CollectionList,
Collection => $emails,
AllowSorting => 1,
@@ -82,10 +115,46 @@
&>
</div>
+<hr />
+
+<div class="form-row">
+ <div class="col-12">
+ <& /Elements/Submit, Label => loc('Update') &>
+ </div>
+</div>
+
+</form>
+
<%init>
my @results;
-$Format ||= qq{'<a href="__WebPath__/Tools/SpamFilter/Display.html?id=__id__">__id__</a>/TITLE:#','<a href="__WebPath__/Tools/SpamFilter/Display.html?id=__id__">__Subject__</a>',__From__,__To__,__Status__,__Date__,__Score__,__Disposition__};
+
+unless ($Format) {
+ $Format = qq{
+ '<a href="__WebPath__/Tools/SpamFilter/Display.html?id=__id__">__id__</a>/TITLE:#',
+ '<a href="__WebPath__/Tools/SpamFilter/Display.html?id=__id__">__Subject__</a>',
+ __From__,
+ __To__,
+ __Status__,
+ __Date__,
+ __Score__
+ };
+
+ if (!$Status || $Status eq 'new') {
+ $Format .= qq{
+ __NotSpam__,
+ __Delete__
+ };
+ } elsif ($Status eq 'resolved') {
+ $Format .= qq{
+ __Delete__
+ };
+ } elsif ($Status eq 'deleted') {
+ $Format .= qq{
+ __NotSpam__
+ };
+ }
+}
$Order ||= 'ASC';
$OrderBy ||= 'id';
@@ -96,18 +165,36 @@ $Page = 1 unless $Page && $Page > 0;
use RT::Spams;
use RT::Spam;
-if ($Action && $emailid) {
- my $email = RT::Spam->new($session{'CurrentUser'}) ;
- $email->Load($emailid);
- if ($email->id) {
- my ($ret, $msg, $ticket);
- if ($Action eq 'Delete') {
- ($ret, $msg) = $email->Delete();
+if ($Delete) {
+ my @ToBeDeleted;
+ if (ref $Delete eq 'ARRAY') {
+ @ToBeDeleted = @$Delete;
+ } else {
+ push @ToBeDeleted, $Delete;
+ };
+ foreach my $id (@ToBeDeleted) {
+ my $email = RT::Spam->new($session{'CurrentUser'}) ;
+ $email->Load($id);
+ if ($email->id) {
+ my ($ret, $msg) = $email->Delete();
if ($ret) {
push(@results, loc('Marked item [_1] as spam', $email->id));
}
- } elsif ($Action eq 'Release') {
- ($ret, $msg, $ticket) = $email->Release(\%session);
+ }
+ }
+}
+if ($Release) {
+ my @ToBeReleased;
+ if (ref $Release eq 'ARRAY') {
+ @ToBeReleased = @$Release;
+ } else {
+ push @ToBeReleased, $Release;
+ };
+ foreach my $id (@ToBeReleased) {
+ my $email = RT::Spam->new($session{'CurrentUser'}) ;
+ $email->Load($id);
+ if ($email->id) {
+ my ($ret, $msg, $ticket) = $email->Release(\%session);
if ($ret) {
push(@results, loc('Marked item [_1] as non-spam and created ticket #[_2]', $email->id, $ticket->Id));
}
@@ -139,6 +226,6 @@ $Page => 1
$OrderBy => undef
$Order => undef
$Status => 'new'
-$Action => undef,
-$emailid => undef
+$Delete => undef
+$Release => undef
</%ARGS>
commit 677d40409c07d9bacfdd8e3f08c62e0a4f2dc537
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date: Fri Jul 7 16:09:39 2023 -0300
Update POD with correct version of RT where patch was cored
The required patch was added to RT 5.0.5 and not on 5.0.2.
diff --git a/lib/RT/Extension/SpamFilter.pm b/lib/RT/Extension/SpamFilter.pm
index f739dd9..3b9b02c 100644
--- a/lib/RT/Extension/SpamFilter.pm
+++ b/lib/RT/Extension/SpamFilter.pm
@@ -72,7 +72,7 @@ in your database.
If you are upgrading this module, check for upgrading instructions
in case changes need to be made to your database.
-=item Patch RT earlier than 5.0.2
+=item Patch RT earlier than 5.0.5
patch -d /opt/rt5 -p1 < patches/0001-Pass-action-info-to-GetCurrentUser-for-email-interfa.patch
-----------------------------------------------------------------------
hooks/post-receive
--
rt-extension-spamfilter
More information about the Bps-public-commit
mailing list