[Rt-commit] rt branch, 4.6-theme-trunk, updated. rt-4.4.4-265-g31611ebea

? sunnavy sunnavy at bestpractical.com
Fri May 24 17:50:18 EDT 2019


The branch, 4.6-theme-trunk has been updated
       via  31611ebea9a148793d15dc7aa488779fe0fea937 (commit)
       via  b85bc73d94b9a73e6dd3f86644c5c58471dbda8d (commit)
      from  8c00a388807567abcb680696d0071f3e863eab35 (commit)

Summary of changes:
 lib/RT/Shredder/POD.pm                             | 51 ++++++++++++++++++--
 lib/RT/Shredder/Plugin/Attachments.pm              |  7 +++
 lib/RT/Shredder/Plugin/Base.pm                     | 11 +++++
 lib/RT/Shredder/Plugin/Tickets.pm                  |  9 +++-
 lib/RT/Shredder/Plugin/Users.pm                    | 15 ++++--
 .../Admin/Tools/Shredder/Elements/ObjectCheckBox   | 12 +++--
 .../Admin/Tools/Shredder/Elements/PluginArguments  | 54 +++++++++++++++++++---
 .../html/Admin/Tools/Shredder/Elements/PluginHelp  |  4 +-
 .../Admin/Tools/Shredder/Elements/SelectObjects    | 21 +++++----
 .../Admin/Tools/Shredder/Elements/SelectPlugin     | 18 ++++----
 share/html/Admin/Tools/Shredder/index.html         |  3 --
 11 files changed, 166 insertions(+), 39 deletions(-)

- Log -----------------------------------------------------------------
commit b85bc73d94b9a73e6dd3f86644c5c58471dbda8d
Author: michel <michel at bestpractical.com>
Date:   Tue May 21 18:58:51 2019 +0200

    Migrate /Admin/Tools/Shredder to elevator themes
    
       boolean arguments now generate checkboxes
       changed the plugin help to display the first paragraph for
       each argument under the input field

diff --git a/lib/RT/Shredder/POD.pm b/lib/RT/Shredder/POD.pm
index 568d606a2..35d521052 100644
--- a/lib/RT/Shredder/POD.pm
+++ b/lib/RT/Shredder/POD.pm
@@ -83,6 +83,46 @@ sub shredder_cli
     return;
 }
 
+# Extract the help foer each argument from the plugin POD
+# they must be on a =head2 line in the ARGUMENTS section of the POD
+# the return value is a hashref:
+#   keys are the argument names,
+#   values are hash_refs: { name => <ucfirst argument name>,
+#                           type => <from the head line>,
+#                           help => <first paragraph from the POD>
+#                         }
+sub arguments_help {
+    my ($file) = @_;
+
+    my $text;
+    open( my $io_handle, ">:scalar", \$text )
+        or die "Can't open scalar for write: $!";
+    my $parser = RT::Shredder::POD::HTML->new;
+    $parser->select('ARGUMENTS');
+    $parser->parse_from_file( $file, $io_handle );
+
+    my $arguments_help = {};
+
+    while( $text=~ m{<h4[^>]*>    # argument description starts with an h4 title
+                       \s*(\S*)   #   argument name ($1)
+                         \s*-\s*
+                       ([^<]*)    #   argument type ($2)
+                     </h4>\s*
+                       (?:<p[^>]*>\s*
+                       (.*?)      #   help: the first paragraph of the POD     ($3)
+                     (?=</p>)
+                       )?
+                    }gsx
+          ) {
+        my( $arg, $arg_name, $type, $help)= ( lc( $1), $1, $2, $3 || '');
+        $arguments_help->{$arg}= { name => $arg_name, type => $type, help => $help };
+    }
+
+    return $arguments_help;
+}
+
+1;
+
 package RT::Shredder::POD::HTML;
 use base qw(Pod::Select);
 
@@ -91,15 +131,19 @@ sub command
     my( $self, $command, $paragraph, $line_num ) = @_;
 
     my $tag;
-    if ($command =~ /^head(\d+)$/) { $tag = "h$1" }
+    # =head1 => h3, =head2 => h4
+    if ($command =~ /^head(\d+)$/) {
+        my $h_level = $1 + 2;
+        $tag = "h$h_level";
+    }
     my $out_fh = $self->output_handle();
     my $expansion = $self->interpolate($paragraph, $line_num);
     $expansion =~ s/^\s+|\s+$//;
     $expansion = lc( $expansion );
     $expansion = ucfirst( $expansion );
 
-    print $out_fh "<$tag class=\"rt-general-header1\">" if $tag eq 'h1';
-    print $out_fh "<$tag class=\"rt-general-header2\">" if $tag eq 'h2';
+    print $out_fh "<$tag class=\"rt-general-header1\">" if $tag eq 'h3';
+    print $out_fh "<$tag class=\"rt-general-header2\">" if $tag eq 'h4';
     print $out_fh $expansion;
     print $out_fh "</$tag>" if $tag;
     print $out_fh "\n";
@@ -134,6 +178,7 @@ sub interior_sequence {
     ## Expand an interior sequence; sample actions might be:
     return "<b>$seq_argument</b>" if $seq_command eq 'B';
     return "<i>$seq_argument</i>" if $seq_command eq 'I';
+    return "<tt>$seq_argument</tt>" if $seq_command eq 'C';
     return "<span class=\"pod-sequence-$seq_command\">$seq_argument</span>";
 }
 1;
diff --git a/lib/RT/Shredder/Plugin/Attachments.pm b/lib/RT/Shredder/Plugin/Attachments.pm
index 003725467..c9a47d590 100644
--- a/lib/RT/Shredder/Plugin/Attachments.pm
+++ b/lib/RT/Shredder/Plugin/Attachments.pm
@@ -78,6 +78,13 @@ kilobytes or megabytes.
 
 sub SupportArgs { return $_[0]->SUPER::SupportArgs, qw(files_only file longer) }
 
+# used to generate checkboxes instead of text fields in the web interface
+sub ArgIsBoolean {
+    my( $self, $arg ) = @_;
+    my %boolean_atts = map { $_ => 1 } qw( files_only );
+    return $boolean_atts{$arg};
+}
+
 sub TestArgs
 {
     my $self = shift;
diff --git a/lib/RT/Shredder/Plugin/Base.pm b/lib/RT/Shredder/Plugin/Base.pm
index 08ae1ac9f..ce4c04485 100644
--- a/lib/RT/Shredder/Plugin/Base.pm
+++ b/lib/RT/Shredder/Plugin/Base.pm
@@ -109,6 +109,17 @@ classes B<must> support.
 
 sub SupportArgs { return () }
 
+=head3 ArgIsBoolean
+
+Takes the name of an argument.
+Returns true if the argument is a boolean.
+
+Used to display checkboxes in the web interface.
+
+=cut
+
+sub ArgIsBoolean { return; }
+
 =head3 HasSupportForArgs
 
 Takes a list of argument names. Returns true if
diff --git a/lib/RT/Shredder/Plugin/Tickets.pm b/lib/RT/Shredder/Plugin/Tickets.pm
index 494bc8595..cc088960a 100644
--- a/lib/RT/Shredder/Plugin/Tickets.pm
+++ b/lib/RT/Shredder/Plugin/Tickets.pm
@@ -72,7 +72,7 @@ Arguments C<queue>, C<status> and C<updated_before> have been dropped
 as you can easy make the same search with the C<query> option.
 See examples above.
 
-=head2 with_linked - boolen
+=head2 with_linked - boolean
 
 Deletes all tickets that are linked to tickets that match L<query>.
 
@@ -86,6 +86,13 @@ See also L<with_linked>.
 
 sub SupportArgs { return $_[0]->SUPER::SupportArgs, qw(query with_linked apply_query_to_linked) }
 
+# used to genrate checkboxes instead of text fields in the web interface
+sub ArgIsBoolean {
+    my( $self, $arg ) = @_;
+    my %boolean_atts = map { $_ => 1 } qw( with_linked apply_query_to_linked );
+    return $boolean_atts{$arg};
+}
+
 sub TestArgs
 {
     my $self = shift;
diff --git a/lib/RT/Shredder/Plugin/Users.pm b/lib/RT/Shredder/Plugin/Users.pm
index a503e0d94..4e810ec9a 100644
--- a/lib/RT/Shredder/Plugin/Users.pm
+++ b/lib/RT/Shredder/Plugin/Users.pm
@@ -108,7 +108,7 @@ Email address mask.
 
 Using this option users that are members of a particular group can
 be selected for deletion. Identifier is name of user defined group
-or id of a group, as well C<Privileged> or <unprivileged> can used
+or id of a group, as well C<Privileged> or C<unprivileged> can used
 to select people from system groups.
 
 =head2 not_member_of - group identifier
@@ -153,8 +153,17 @@ want to use C<replace_relations> option.
 
 sub SupportArgs
 {
-    return $_[0]->SUPER::SupportArgs,
-           qw(status name email member_of not_member_of replace_relations no_tickets no_ticket_transactions);
+    return ( $_[0]->SUPER::SupportArgs,
+             qw( status name email member_of not_member_of replace_relations no_tickets no_ticket_transactions )
+           );
+}
+
+
+# used to genrate checkboxes instead of text fields in the web interface
+sub ArgIsBoolean {
+    my( $self, $arg ) = @_;
+    my %boolean_atts = map { $_ => 1 } qw( no_tickets no_ticket_transactions );
+    return $boolean_atts{$arg};
 }
 
 sub TestArgs
diff --git a/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox b/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox
index 08cb73508..c2a73f8f7 100644
--- a/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox
+++ b/share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox
@@ -48,14 +48,16 @@
 <%ARGS>
 $Object => undef
 </%ARGS>
-<input type="checkbox" name="WipeoutObject" value="<% $Object->UID %>" />
-<span>
+<div class="custom-control custom-checkbox">
+  <input type="checkbox" name="WipeoutObject" class="custom-control-input" id="cb-<% $Object->UID %>" value="<% $Object->UID %>" />
 % if( $m->comp_exists( $path ) ) {
-% $m->comp( $path, Object => $Object );
+  <label class="custom-control-label" for="cb-<% $Object->UID %>">
+%   $m->comp( $path, Object => $Object );
 % } else {
-<% $Object->UID %>
+    <% $Object->UID %>
 % }
-</span><br />
+  </label>
+</div>
 <%ONCE>
 require File::Spec;
 </%ONCE>
diff --git a/share/html/Admin/Tools/Shredder/Elements/PluginArguments b/share/html/Admin/Tools/Shredder/Elements/PluginArguments
index 987cb9dc6..cfe522e31 100644
--- a/share/html/Admin/Tools/Shredder/Elements/PluginArguments
+++ b/share/html/Admin/Tools/Shredder/Elements/PluginArguments
@@ -49,19 +49,59 @@
 $Plugin => ''
 </%ARGS>
 <div id="shredder-plugin-<% $Plugin %>-arguments" class="shredder-form">
-<span><% loc('Fill arguments') %>:</span><br />
-<table>
+<&| /Widgets/TitleBox, title => loc("Search") &>
 % for my $a ( $plugin_obj->SupportArgs ) {
-<tr>
-    <td class="label"><label for="<% "$Plugin:$a" %>"><% loc($a) %>:</label></td>
-    <td><input type="text" name="<% "$Plugin:$a" %>" id="<% "$Plugin:$a" %>" value="<% $ARGS{ "$Plugin:$a" } || '' %>" /></td>
-</tr>
+  <div class="form-row">
+%  if( $plugin_obj->ArgIsBoolean( $a ) ) {
+    <div class="col-md-9 offset-md-3">
+      <div class="custom-control custom-checkbox">
+        <input type="checkbox" id="<% "$Plugin:$a" %>" name="<% "$Plugin:$a" %>" class="custom-control-input" value="<% $ARGS{ "$Plugin:$a" } || '' %>" />
+        <label class="custom-control-label" for="<% "$Plugin:$a" %>"><% loc($a) %></label>
+        <span class="hints d-block"><% $arguments_help{$a}->{help} |n%></span>
+      </div>
+    </div>
+%  } else {
+    <div class="col-md-3 label"><% loc($a) %></div>
+    <div class="col-md-9 value">
+      <input type="text" name="<% "$Plugin:$a" %>" id="<% "$Plugin:$a" %>" class="form-control" value="<% $ARGS{ "$Plugin:$a" } || '' %>" />
+%     if( $arguments_help{$a} ) {
+          <span class="hints d-block"><% $arguments_help{$a}->{type} . ' - ' . $arguments_help{$a}->{help} |n%></span>
+%     }
+    </div>
+%  }
+  </div>
 % }
-</table>
+  <div id="shredder-submit-button" class="<% $Plugin? '': 'hidden' %>">
+    <div class="form-row">
+      <div class="col-md-12">
+        <& /Elements/Submit, Name => 'Search', Label => loc('Search') &>
+      </div>
+    </div>
+  </div>
+  </&>
 </div>
 <%INIT>
 use RT::Shredder::Plugin;
+use RT::Shredder::POD;
+
+my $base_obj = RT::Shredder::Plugin->new;
+
+my %plugins = $base_obj->List;
+
+my $base_file = $plugins{ 'Base' };
+$base_file =~ s/\.pm$/\/Search.pm/; # docs for the Base "plugin" is in the base file, not Search.pm
+my $base_arguments_help = RT::Shredder::POD::arguments_help( $base_file);
+
 my $plugin_obj = RT::Shredder::Plugin->new;
+
 my ($status, $msg) = $plugin_obj->LoadByName( $Plugin );
 die $msg unless $status;
+
+my $plugin_file = $plugins{ $Plugin };
+unless( $plugin_file ) {
+    $RT::Logger->error( "Couldn't find plugin '$Plugin'" );
+    return;
+}
+my $plugin_arguments_help = RT::Shredder::POD::arguments_help( $plugin_file);
+my %arguments_help = ( %$base_arguments_help, %$plugin_arguments_help );
 </%INIT>
diff --git a/share/html/Admin/Tools/Shredder/Elements/PluginHelp b/share/html/Admin/Tools/Shredder/Elements/PluginHelp
index 280ea8b76..5068e101e 100644
--- a/share/html/Admin/Tools/Shredder/Elements/PluginHelp
+++ b/share/html/Admin/Tools/Shredder/Elements/PluginHelp
@@ -49,7 +49,9 @@
 $Plugin => ''
 </%ARGS>
 <div id="shredder-plugin-<% $Plugin %>-help" class="shredder-help">
-<% $text |n%>
+  <&| /Widgets/TitleBox, title => "$Plugin Help" &>
+    <% $text |n%>
+  </&>
 </div>
 <%ONCE>
 use RT::Shredder::Plugin;
diff --git a/share/html/Admin/Tools/Shredder/Elements/SelectObjects b/share/html/Admin/Tools/Shredder/Elements/SelectObjects
index 7636dee82..240c420e6 100644
--- a/share/html/Admin/Tools/Shredder/Elements/SelectObjects
+++ b/share/html/Admin/Tools/Shredder/Elements/SelectObjects
@@ -49,19 +49,24 @@
 @Objects => ()
 </%ARGS>
 <div id="shredder-plugin-results">
+  <&| /Widgets/TitleBox, title => loc("Results") &>
+
 % unless( @Objects ) {
-<& /Elements/ListActions, actions => [loc("Objects list is empty")] &>
+    <& /Elements/ListActions, actions => [loc("Objects list is empty")] &>
 % } else {
-<div class="shredder-form">
-<input id="shredder-select-all-objects-checkbox" type="checkbox" name="SelectAllObjects" onclick="checkAllObjects()" />
-<span><% loc("click to check/uncheck all objects at once") %></span>
-<hr />
+    <div class="shredder-form">
+      <div class="custom-control custom-checkbox">
+        <input id="shredder-select-all-objects-checkbox" type="checkbox" name="SelectAllObjects" class="custom-control-input" onclick="checkAllObjects()" />
+        <label class="custom-control-label" for="shredder-select-all-objects-checkbox"><% loc("click to check/uncheck all objects at once") %></label>
+      </div>
+      <hr />
 % foreach my $o( @Objects ) {
-<& ObjectCheckBox, Object => $o &>
+      <& ObjectCheckBox, Object => $o &>
 % }
-</div>
-<& /Elements/Submit, Name => 'Wipeout', Label => loc('Wipeout') &>
+      <& /Elements/Submit, Name => 'Wipeout', Label => loc('Wipeout') &>
+    </div>
 % }
+  </&>
 </div>
 <%INIT>
 </%INIT>
diff --git a/share/html/Admin/Tools/Shredder/Elements/SelectPlugin b/share/html/Admin/Tools/Shredder/Elements/SelectPlugin
index 1db5ec924..a395e7452 100644
--- a/share/html/Admin/Tools/Shredder/Elements/SelectPlugin
+++ b/share/html/Admin/Tools/Shredder/Elements/SelectPlugin
@@ -49,20 +49,22 @@
 $Plugin => ''
 </%ARGS>
 <& PluginHelp, %ARGS, Plugin => 'Base' &>
-<div class="shredder-form">
-<span>Select plugin: </span>
-<select name="Plugin" onchange="showShredderPluginTab(this.value);">
-<option value=""><% loc('(no value)') %></option>
+<div class="shredder-form form-row">
+  <div class="col-md-auto label"><&|/l&>Select plugin</&>: </div>
+  <div class="col-md-auto">
+    <select name="Plugin" class="form-control selectpicker" onchange="showShredderPluginTab(this.value);">
+      <option value=""><% loc('(no value)') %></option>
 % foreach my $p( keys %plugins ) {
-<option value="<% $p %>" <% ($p eq $Plugin)? 'selected="selected"': '' %>><% loc($p) %></option>
+      <option value="<% $p %>" <% ($p eq $Plugin)? 'selected="selected"': '' %>><% loc($p) %></option>
 % }
-</select>
+    </select>
+  </div>
 </div>
 <div id="shredder-plugin-tabs">
 % foreach my $p( keys %plugins ) {
 <div id="shredder-plugin-<% $p %>-tab" class="<% ($p ne $Plugin)? 'hidden': '' %>">
-<& PluginHelp, %ARGS, Plugin => $p &>
-<& PluginArguments, %ARGS, Plugin => $p &>
+  <& PluginHelp, %ARGS, Plugin => $p &>
+  <& PluginArguments, %ARGS, Plugin => $p &>
 </div>
 % }
 </div>
diff --git a/share/html/Admin/Tools/Shredder/index.html b/share/html/Admin/Tools/Shredder/index.html
index 557d5da64..08f4a9af4 100644
--- a/share/html/Admin/Tools/Shredder/index.html
+++ b/share/html/Admin/Tools/Shredder/index.html
@@ -59,9 +59,6 @@ $Wipeout => ''
 <& /Elements/ListActions, actions => $messages{'Success'} &>
 <& Elements/DumpFileLink, File => $dump_file &>
 <& Elements/SelectPlugin, Plugin => $Plugin, %ARGS &>
-<div id="shredder-submit-button" class="<% $Plugin? '': 'hidden' %>">
-<& /Elements/Submit, Name => 'Search', Label => loc('Search') &>
-</div>
 </div>
 <br />
 % if( $Search || $Wipeout ) {

commit 31611ebea9a148793d15dc7aa488779fe0fea937
Merge: 8c00a3888 b85bc73d9
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat May 25 02:16:46 2019 +0800

    Merge branch '4.6-theme/admin-tools-shredder' into 4.6-theme-trunk


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


More information about the rt-commit mailing list