[Rt-commit] rt branch, 4.2/scrip-custom-code-textareas-visible-only-when-needed, created. rt-4.2.13-53-g4417c1c

Dustin Collins strega at bestpractical.com
Tue Sep 27 14:42:43 EDT 2016


The branch, 4.2/scrip-custom-code-textareas-visible-only-when-needed has been created
        at  4417c1c33794a6dddbe417dc0f65c6e31304e436 (commit)

- Log -----------------------------------------------------------------
commit 4417c1c33794a6dddbe417dc0f65c6e31304e436
Author: Dustin Collins <strega at bestpractical.com>
Date:   Sat Sep 3 21:39:17 2016 -0400

    Hide scrip custom code fields when appropriate
    
    The textareas for condition, action prepare, and action commit code
    only make sense for scrips that use "User Defined" condition or action.
    This commit shows or hides each textarea (using JavaScript) based on
    whether the scrip's current configuration will use its contents. This
    is meant to reduce user confusion about when these textareas take
    effect, and significantly reduce the length of the page in the common
    case of no "User Defined" code.
    
    To reinforce to users the relationship between the dropdown and its
    custom code textarea(s), we've moved each textarea up into the form,
    right below to its dropdown. If the fields were to remain in two
    separate sections, then users wouldn't notice the show/hide action at
    a distance and would wonder why the textareas appear only some of the
    time. This also reduces the perceived complexity of the scrip
    create/modify page down to one consistent form, rather than two
    confusingly-related sections, each with its own Save Changes button.
    
    In order to ease the transition for custom deployments, a new method
    (IsUserEditable) is added to RT::Condition and RT::Action to allow
    users to easily inform RT of condition or action objects they have
    made user editable.
    
    Add Condition method to RT::ScripCondition for easily obtaining the
    RT::Condition object, simillar to the Action method on RT::ScripAction.
    Add lazy loading check to RT:ScripAction->Action.
    
    Move module name creation logic into own method on both ScripAction and ScripCondition for convenience.
    
    Now that we've moved the textareas to be inline with the rest of the
    form, there arises a new problem where specifying lots of code would
    cause the rest of the page (e.g. Template selection) to scroll
    offscreen. So adapting the size of the textbox to how many lines are
    in the provided code (+3 lines for buffer) has been replaced with a
    constant of 6 rows. Users will still be able to use their browser's
    textarea resize tool to make the code entry fields longer.
    
    There is no animation for the show/hide actions because jQuery's
    slideUp and slideDown animations cannot handle table tags.
    
    Fixes: I#32260

diff --git a/lib/RT/Action.pm b/lib/RT/Action.pm
index ac4dfe6..ba17284 100644
--- a/lib/RT/Action.pm
+++ b/lib/RT/Action.pm
@@ -171,6 +171,12 @@ sub Prepare  {
   return (0, $self->loc("Prepare Stubbed"));
 }
 
+=head2 IsUserEditable
+Return 1 if the action can be edited by a user, otherwise 0.
+=cut
+sub IsUserEditable {
+    return 0;
+}
 
 RT::Base->_ImportOverlays();
 
diff --git a/lib/RT/Action/UserDefined.pm b/lib/RT/Action/UserDefined.pm
index 48bee18..03c66a8 100644
--- a/lib/RT/Action/UserDefined.pm
+++ b/lib/RT/Action/UserDefined.pm
@@ -68,6 +68,10 @@ sub Prepare {
     return ($retval);
 }
 
+sub IsUserEditable {
+    return 1;
+}
+
 =head2 Commit
 
 This happens on every transaction. it's always applicable
diff --git a/lib/RT/Condition.pm b/lib/RT/Condition.pm
index 537aa54..84b7046 100644
--- a/lib/RT/Condition.pm
+++ b/lib/RT/Condition.pm
@@ -193,6 +193,14 @@ sub IsApplicable  {
   return(undef);
 }
 
+=head2 IsUserEditable
+Return 1 if the condition can be edited by a user, otherwise 0.
+=cut
+sub IsUserEditable {
+    my $self = shift;
+    return 0;
+}
+
 sub DESTROY {
     my $self = shift;
 
diff --git a/lib/RT/Condition/UserDefined.pm b/lib/RT/Condition/UserDefined.pm
index a6e0132..80b6f71 100644
--- a/lib/RT/Condition/UserDefined.pm
+++ b/lib/RT/Condition/UserDefined.pm
@@ -69,6 +69,13 @@ sub IsApplicable {
     return ($retval);
 }
 
+=head2 IsUserEditable
+Return 1 if the condition can be edited by a user, otherwise 0.
+=cut
+sub IsUserEditable {
+    return 1;
+}
+
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index 712b109..17e97cb 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -167,18 +167,32 @@ sub LoadAction  {
         $self->{'TemplateObj'} = $args{'TemplateObj'};
     }
 
-    $self->ExecModule =~ /^(\w+)$/;
-    my $module = $1;
-    my $type = "RT::Action::". $module;
-
-    $type->require or die "Require of $type action module failed.\n$@\n";
-
-    return $self->{'Action'} = $type->new(
+    $self->{'Action'} = $self->ModuleName->new(
         %args,
         Argument       => $self->Argument,
         CurrentUser    => $self->CurrentUser,
         ScripActionObj => $self,
     );
+
+    return $self->{'Action'};
+}
+
+
+=head2 ModuleName
+
+Returns the name for the actual action object as a module.
+
+=cut
+
+sub ModuleName {
+    my $self = shift;
+
+    $self->ExecModule =~ /^(\w+)$/;
+    my $type = "RT::Action::" . $1;
+
+    $type->require or die "Require of $type action module failed.\n$@\n";
+
+    return $type;
 }
 
 
@@ -241,9 +255,13 @@ Return the actual RT::Action object for this scrip.
 
 sub Action {
     my $self = shift;
+    unless (defined $self->{'Action'}) {
+        $self->LoadAction;
+    }
     return $self->{'Action'};
 }
 
+
 =head2 id
 
 Returns the current value of id.
diff --git a/lib/RT/ScripCondition.pm b/lib/RT/ScripCondition.pm
index c93b606..71678be 100644
--- a/lib/RT/ScripCondition.pm
+++ b/lib/RT/ScripCondition.pm
@@ -157,26 +157,36 @@ sub LoadCondition  {
                  TicketObj => undef,
                  @_ );
 
-    #TODO: Put this in an eval
+    $self->{'Condition'} = $self->ModuleName->new(
+        'ScripConditionObj' => $self,
+        'TicketObj' => $args{'TicketObj'},
+        'ScripObj' => $args{'ScripObj'},
+        'TransactionObj' => $args{'TransactionObj'},
+        'Argument' => $self->Argument,
+        'ApplicableTransTypes' => $self->ApplicableTransTypes,
+        CurrentUser => $self->CurrentUser
+    );
+}
+
+
+=head2 ModuleName
+
+Returns the name for the actual condition object as a module.
+
+=cut
+
+sub ModuleName {
+    my $self = shift;
+
     $self->ExecModule =~ /^(\w+)$/;
-    my $module = $1;
-    my $type = "RT::Condition::". $module;
+    my $type = "RT::Condition::". $1;
 
     $type->require or die "Require of $type condition module failed.\n$@\n";
 
-    $self->{'Condition'}  = $type->new ( 'ScripConditionObj' => $self,
-                                         'TicketObj' => $args{'TicketObj'},
-                                         'ScripObj' => $args{'ScripObj'},
-                                         'TransactionObj' => $args{'TransactionObj'},
-                                         'Argument' => $self->Argument,
-                                         'ApplicableTransTypes' => $self->ApplicableTransTypes,
-                                         CurrentUser => $self->CurrentUser
-                                       );
+    return $type;
 }
 
 
-
-
 =head2 Describe 
 
 Helper method to call the condition module's Describe method.
@@ -189,6 +199,19 @@ sub Describe  {
     
 }
 
+=head2 Condition
+
+Return the actual RT::Condition object for this scrip.
+
+=cut
+
+sub Condition {
+    my $self = shift;
+    unless (defined $self->{'Condition'}) {
+        $self->LoadCondition;
+    }
+    return $self->{'Condition'};
+}
 
 =head2 IsApplicable
 
diff --git a/share/html/Admin/Scrips/Create.html b/share/html/Admin/Scrips/Create.html
index 7cc3406..4af7a7f 100644
--- a/share/html/Admin/Scrips/Create.html
+++ b/share/html/Admin/Scrips/Create.html
@@ -75,14 +75,6 @@
     Name => 'Create',
 &>
 
-% if ($session{CurrentUser}->HasRight(Object => $RT::System, Right => 'ExecuteCode')) {
-<& Elements/EditCustomCode, %ARGS, Scrip => $scrip &>
-<& /Elements/Submit,
-    Label => loc('Create'),
-    Name => 'Create',
-&>
-% }
-
 </form>
 <%ARGS>
 $Queue => 0
diff --git a/share/html/Admin/Scrips/Elements/EditBasics b/share/html/Admin/Scrips/Elements/EditBasics
index aad681c..49a6d38 100644
--- a/share/html/Admin/Scrips/Elements/EditBasics
+++ b/share/html/Admin/Scrips/Elements/EditBasics
@@ -56,19 +56,88 @@
     Default => $ARGS{"ScripCondition"} || $Scrip->ConditionObj->Id,
 &></td></tr>
 
+% if ($canExecuteCode) {
+<tr class="CustomIsApplicableCode <% $editableConditionInitiallyHidden ? 'hidden' : '' %>">
+<td class="label"><&|/l&>Condition code</&>:</td><td class="value">\
+% my $conditionCode = $ARGS{ CustomIsApplicableCode } || $Scrip->CustomIsApplicableCode() || '';
+<textarea cols="80" rows="6" name="CustomIsApplicableCode"><% $conditionCode %></textarea>
+</td></tr>
+% }
+
 <tr><td class="label"><&|/l&>Action</&>:</td><td class="value">\
 <& /Admin/Elements/SelectScripAction,
     Default => $ARGS{"ScripAction"} || $Scrip->ActionObj->Id,
 &></td></tr>
 
+% if ($canExecuteCode) {
+<tr class="CustomPrepareCode <% $editableActionInitiallyHidden ? 'hidden' : '' %>">
+<td class="label"><&|/l&>Prepare code</&>:</td><td class="value">\
+% my $prepareCode = $ARGS{ CustomPrepareCode } || $Scrip->CustomPrepareCode() || '';
+<textarea cols="80" rows="6" name="CustomPrepareCode"><% $prepareCode %></textarea>
+</td></tr>
+
+<tr class="CustomCommitCode <% $editableActionInitiallyHidden ? 'hidden' : '' %>">
+<td class="label"><&|/l&>Commit code</&>:</td><td class="value">\
+% my $commitCode = $ARGS{ CustomCommitCode } || $Scrip->CustomCommitCode() || '';
+<textarea cols="80" rows="6" name="CustomCommitCode"><% $commitCode %></textarea>
+</td></tr>
+% }
+
 <tr><td class="label"><&|/l&>Template</&>:</td><td class="value">\
 <& SelectTemplate,
     Default => $ARGS{"Template"}, Scrip => $Scrip, Queue => $Queue,
 &></td></tr>
 
+<script type="text/javascript">
+jQuery(function () {
+    jQuery("select[name=ScripCondition]").change(function (e) {
+        var scripConditionId = parseInt(jQuery(this).val());
+        var userEditableIDs = [<% join( ', ', @editableConditionIDs) %>]
+        if (userEditableIDs.indexOf(scripConditionId) > -1) {
+            jQuery(".CustomIsApplicableCode").removeClass('hidden');
+        }else{
+            jQuery(".CustomIsApplicableCode").addClass('hidden');
+        }
+    });
+
+    jQuery("select[name=ScripAction]").change(function (e) {
+        var scripConditionId = parseInt(jQuery(this).val());
+        var userEditableIDs = [<% join( ', ', @editableActionIDs) %>]
+        if (userEditableIDs.indexOf(scripConditionId) > -1) {
+            jQuery(".CustomPrepareCode, .CustomCommitCode").removeClass('hidden');
+        }else{
+            jQuery(".CustomPrepareCode, .CustomCommitCode").addClass('hidden');
+        }
+    });
+});
+</script>
+
 <%ARGS>
 $Scrip
 $Queue => undef
 </%ARGS>
 <%INIT>
+
+my $canExecuteCode = ($session{CurrentUser}->HasRight(Object => $RT::System, Right => 'ExecuteCode'));
+
+my $editableConditionInitiallyHidden = ($Scrip->ConditionObj->Id) ? !$Scrip->ConditionObj->ModuleName->IsUserEditable : 1;
+my @editableConditionIDs;
+my $ScripConditions = RT::ScripConditions->new($session{'CurrentUser'});
+$ScripConditions->UnLimit;
+while (my $ScripCondition = $ScripConditions->Next) {
+    if ($ScripCondition->ModuleName->IsUserEditable) {
+        push @editableConditionIDs, $ScripCondition->Id;
+    }
+}
+
+my $editableActionInitiallyHidden = ($Scrip->ActionObj->Id) ? !$Scrip->ActionObj->ModuleName->IsUserEditable : 1;
+my @editableActionIDs;
+my $ScripActions = RT::ScripActions->new($session{'CurrentUser'});
+$ScripActions->UnLimit;
+while (my $ScripAction = $ScripActions->Next) {
+    if ($ScripAction->ModuleName->IsUserEditable) {
+        push @editableActionIDs, $ScripAction->Id;
+    }
+}
+
 </%INIT>
diff --git a/share/html/Admin/Scrips/Elements/EditCustomCode b/share/html/Admin/Scrips/Elements/EditCustomCode
deleted file mode 100644
index 1c6247e..0000000
--- a/share/html/Admin/Scrips/Elements/EditCustomCode
+++ /dev/null
@@ -1,77 +0,0 @@
-%# BEGIN BPS TAGGED BLOCK {{{
-%#
-%# COPYRIGHT:
-%#
-%# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
-%#                                          <sales at bestpractical.com>
-%#
-%# (Except where explicitly superseded by other copyright notices)
-%#
-%#
-%# LICENSE:
-%#
-%# This work is made available to you under the terms of Version 2 of
-%# the GNU General Public License. A copy of that license should have
-%# been provided with this software, but in any event can be snarfed
-%# from www.gnu.org.
-%#
-%# This work is distributed in the hope that it will be useful, but
-%# WITHOUT ANY WARRANTY; without even the implied warranty of
-%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%# General Public License for more details.
-%#
-%# You should have received a copy of the GNU General Public License
-%# along with this program; if not, write to the Free Software
-%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-%# 02110-1301 or visit their web page on the internet at
-%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-%#
-%#
-%# CONTRIBUTION SUBMISSION POLICY:
-%#
-%# (The following paragraph is not intended to limit the rights granted
-%# to you to modify and distribute this software under the terms of
-%# the GNU General Public License and is only of importance to you if
-%# you choose to contribute your changes and enhancements to the
-%# community by submitting them to Best Practical Solutions, LLC.)
-%#
-%# By intentionally submitting any modifications, corrections or
-%# derivatives to this work, or any other work intended for use with
-%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-%# you are the copyright holder for those contributions and you grant
-%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-%# royalty-free, perpetual, license to use, copy, create derivative
-%# works based on those contributions, and sublicense and distribute
-%# those contributions and any derivatives thereof.
-%#
-%# END BPS TAGGED BLOCK }}}
-<&| /Widgets/TitleBox, title => loc('User Defined conditions and results') &>
-
-<table>
-<tr><td colspan="2" class="comment">
-<i><&|/l&>(Use these fields when you choose 'User Defined' for a condition or action)</&></i>
-</td></tr>
-
-% while ( my ($method, $desc) = splice @list, 0, 2 ) {
-<tr><td class="labeltop"><% $desc %>:</td><td class="value">
-% my $code = $ARGS{ $method } || $Scrip->$method() || '';
-% my $lines = @{[ $code =~ /\n/gs ]} + 3;
-% $lines = $min_lines if $lines < $min_lines;
-<textarea cols="80" rows="<% $lines %>" name="<% $method %>"><% $code %></textarea>
-</td></tr>
-% }
-
-</table>
-</&>
-<%ARGS>
-$Scrip
-</%ARGS>
-<%INIT>
-my @list = (
-    CustomIsApplicableCode => loc('Custom condition'),
-    CustomPrepareCode      => loc('Custom action preparation code'),
-    CustomCommitCode       => loc('Custom action commit code'),
-);
-
-my $min_lines = 10;
-</%INIT>
diff --git a/share/html/Admin/Scrips/Modify.html b/share/html/Admin/Scrips/Modify.html
index 618c48d..d5929e3 100644
--- a/share/html/Admin/Scrips/Modify.html
+++ b/share/html/Admin/Scrips/Modify.html
@@ -88,11 +88,6 @@
 
 <& /Elements/Submit, Label => loc('Save Changes'), Name => 'Update', Reset => 1 &>
 
-% if ($session{CurrentUser}->HasRight(Object => $RT::System, Right => 'ExecuteCode')) {
-<& Elements/EditCustomCode, %ARGS, Scrip => $scrip &>
-<& /Elements/Submit, Label => loc('Save Changes'), Name => 'Update', Reset => 1 &>
-% }
-
 </form>
 <%ARGS>
 $id     => undef

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


More information about the rt-commit mailing list