rt 4.2.15
[freeside.git] / rt / share / html / Admin / CustomFields / Modify.html
index f75607a..4b1d8d8 100644 (file)
@@ -1,40 +1,40 @@
 %# BEGIN BPS TAGGED BLOCK {{{
-%# 
+%#
 %# COPYRIGHT:
-%# 
-%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
-%#                                          <jesse@bestpractical.com>
-%# 
+%#
+%# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
+%#                                          <sales@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
 %# 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 }}}
-<& /Admin/Elements/Header, Title => $title &>
-<& /Admin/Elements/CustomFieldTabs,
-    id => $CustomFieldObj->Id ,
-    current_tab => $current_tab,
-    Title => $title &>
+<& /Admin/Elements/Header,
+    Title => $title,
+    Focus => (($added_cfv or $ARGS{FocusAddValue})
+        ? "input[name=CustomField-$id-Value-new-Name]"
+        : undef),
+    &>
+<& /Elements/Tabs &>
 <& /Elements/ListActions, actions => \@results &>
 
 
-<form method="post" action="Modify.html" name="ModifyCustomField">
+<form method="post" action="Modify.html" name="ModifyCustomField" id="ModifyCustomField">
 <input type="hidden" class="hidden" name="id" value="<% $id %>" />
 
 <table>
 
 <tr><td class="label"><&|/l&>Name</&></td>
-<td><input name="Name" value="<% $CustomFieldObj->Name || '' %>" size="20" /></td></tr>
+<td><input name="Name" value="<% $CustomFieldObj->Name || $Name || '' %>" size="20" /></td></tr>
 
 <tr><td class="label"><&|/l&>Description</&></td>
-<td><input name="Description" value="<% $CustomFieldObj->Description || '' %>" size="80" /></td></tr>
+<td><input name="Description" value="<% $CustomFieldObj->Description || $Description || '' %>" size="80" /></td></tr>
 
 <tr><td class="label"><&|/l&>Type</&></td>
 <td><& /Admin/Elements/SelectCustomFieldType, 
         Default => $CustomFieldObj->TypeComposite, &>
 </td></tr>
 
+% if ( $CustomFieldObj->Id and $CustomFieldObj->HasRenderTypes ) {
+<tr>
+  <td class="label"><&|/l&>Render Type</&></td>
+  <td>
+    <& /Admin/Elements/SelectCustomFieldRenderType,
+        Name            => "RenderType",
+        TypeComposite   => $CustomFieldObj->TypeComposite,
+        Default         => $CustomFieldObj->RenderType, 
+        BasedOn         => $CustomFieldObj->BasedOnObj->id, &>
+  </td>
+</tr>
+% }
+
 % if ( $CustomFieldObj->Id and $CustomFieldObj->IsSelectionType and RT->Config->Get('CustomFieldValuesSources') and ( scalar(@{RT->Config->Get('CustomFieldValuesSources')}) > 0 ) ) {
 <tr><td class="label"><&|/l&>Field values source:</&></td><td>
 <& /Admin/Elements/EditCustomFieldValuesSource, CustomField => $CustomFieldObj &>
 <tr><td class="label"><&|/l&>Applies to</&></td>
 <td><& /Admin/Elements/SelectCustomFieldLookupType, 
         Name => "LookupType", 
-        Default => $CustomFieldObj->LookupType, &>
+        Default => $CustomFieldObj->LookupType || $LookupType, &>
+</td></tr>
+
+% if ( $CustomFieldObj->Id 
+%     and $CustomFieldObj->LookupType =~ /RT::Transaction/ ) {
+<tr><td class="label"><&|/l&>Display&nbsp;with</&></td>
+<td><& /Admin/Elements/EditCustomFieldUILocation,
+        CustomField => $CustomFieldObj &>
 </td></tr>
+% }
 
-<tr><td class="label"><&|/l&>Validation</&></td>
+<tr class="edit_validation"><td class="label"><&|/l&>Validation</&></td>
 <td><& /Widgets/ComboBox,
     Name    => 'Pattern',
-    Default => $CustomFieldObj->Pattern,
+    Default => $CustomFieldObj->Pattern || $Pattern,
     Size    => 20,
     Values  => \@CFvalidations,
 &></td></tr>
 
 <tr><td class="label"><&|/l&>Link values to</&></td><td>
-<input size="60" name="LinkValueTo"  value="<% $CustomFieldObj->LinkValueTo || '' %>" />
+<input size="60" name="LinkValueTo"  value="<% $CustomFieldObj->LinkValueTo || $LinkValueTo || '' %>" />
 <div class="hints">
 <&|/l&>RT can make this custom field's values into hyperlinks to another service.</&>
 <&|/l&>Fill in this field with a URL.</&>
-<&|/l&>RT will replace <tt>__id__</tt> and <tt>__CustomField__</tt> with the record id and custom field value, respectively</&>
+<&|/l_unsafe, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&>
 </div></td></tr>
 
 <tr><td class="label"><&|/l&>Include page</&></td><td>
-<input size="60" name="IncludeContentForValue" value="<% $CustomFieldObj->IncludeContentForValue || '' %>" />
+<input size="60" name="IncludeContentForValue" value="<% $CustomFieldObj->IncludeContentForValue || $IncludeContentForValue || '' %>" />
 <div class="hints">
 <&|/l&>RT can include content from another web service when showing this custom field.</&>
 <&|/l&>Fill in this field with a URL.</&>
-<&|/l&>RT will replace <tt>__id__</tt> and <tt>__CustomField__</tt> with the record id and custom field value, respectively</&>
+<&|/l_unsafe, '<tt>__id__</tt>', '<tt>__CustomField__</tt>' &>RT will replace [_1] and [_2] with the record's id and the custom field's value, respectively.</&>
 <i><&|/l&>Some browsers may only load content from the same domain as your RT server.</&></i>
 </div></td></tr>
 
-% if ( $CustomFieldObj->Id && $CustomFieldObj->IsSelectionType && !$CustomFieldObj->IsExternalValues ) {
-<tr><td class="label"><&|/l&>Categories are based on</&></td><td>
+% if ( $CustomFieldObj->Id && $CustomFieldObj->IsSelectionType ) {
+<tr class="categoriesbasedon"><td class="label"><&|/l&>Categories are based on</&></td><td>
 <& /Admin/Elements/SelectCustomField,
     Name => "BasedOn",
     LookupType => $CustomFieldObj->LookupType,
-    Default => $CustomFieldObj->BasedOnObj,
+    Default => $CustomFieldObj->BasedOnObj || $BasedOn,
     Not => $CustomFieldObj->id,
 &>
 </td></tr>
 % }
 
+% $m->callback(CallbackName => 'BeforeEnabled', CustomField => $CustomFieldObj, CFvalidations => \@CFvalidations);
+
+<tr><td class="label">&nbsp;</td><td>
+<input type="checkbox" class="checkbox" name="Required" value="1" <% $RequiredChecked |n%> />
+<&|/l&>Required for ticket resolution</&>
+</td></tr>
+
+<tr><td class="label">&nbsp;</td><td>
+<input type="checkbox" class="checkbox" name="YesClone" value="1" <% $YesCloneChecked |n%> />
+<&|/l&>Copy this field to new tickets</&>
+</td></tr>
+
 <tr><td class="label">&nbsp;</td><td>
 <input type="hidden" class="hidden" name="SetEnabled" value="1" />
-<input type="checkbox" class="checkbox" name="Enabled" value="1" <% $EnabledChecked |n%> />
-<&|/l&>Enabled (Unchecking this box disables this custom field)</&>
+<input type="checkbox" class="checkbox" id="Enabled" name="Enabled" value="1" <% $EnabledChecked |n %> />
+<label for="Enabled"><&|/l&>Enabled (Unchecking this box disables this custom field)</&></label>
 </td></tr>
 
+% $m->callback(CallbackName => 'EndOfTable', CustomField => $CustomFieldObj, CFvalidations => \@CFvalidations);
+
 </table>
 
 % if ( $CustomFieldObj->Id && $CustomFieldObj->IsSelectionType && !$CustomFieldObj->IsExternalValues ) {
 <& /Elements/Submit, Name => 'Update', Label => $id eq 'new'? loc('Create'): loc('Save Changes') &>
 
 </form>
+% $m->callback(%ARGS, CallbackName => 'EndOfPage', CustomFieldObj => $CustomFieldObj);
 <%INIT>
-my ($title, @results, $Disabled);
+my ($title, @results, $added_cfv);
 
 my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} );
-my $current_tab = 'Admin/CustomFields/Modify.html';
+
+$m->callback(CallbackName => 'Initial', Pattern => \$Pattern, Results => \@results, ARGSRef => \%ARGS);
 
 unless ( $id ) {
     $title = loc("Create a CustomField");
     $id    = 'new';
-    $current_tab .= '?Create=1';
 }
 else {
     if ( $id eq 'new' ) {
@@ -159,69 +197,164 @@ else {
             LinkValueTo   => $LinkValueTo,
             IncludeContentForValue => $IncludeContentForValue,
             BasedOn       => $BasedOn,
+            Disabled      => ($Enabled ? 0 : 1),
+            NoClone       => !$YesClone,
         );
-        $m->comp( "/Elements/Error", Why => loc( "Could not create CustomField", $msg ) ) unless $val;
-        push @results, $msg;
-        $title = loc( 'Created CustomField [_1]', $CustomFieldObj->Name );
+        if (!$val) {
+            push @results, loc("Could not create CustomField: [_1]", $msg);
+            $title = loc( 'Create a CustomField');
+        }
+        else {
+            push @results, loc("Object created");
+            $title = loc( 'Created CustomField [_1]', $CustomFieldObj->Name );
+        }
     } else {
-        $CustomFieldObj->Load( $id ) || $m->comp("/Elements/Error", Why => loc('No CustomField') );
+        push @results, loc('No CustomField')
+            unless  $CustomFieldObj->Load( $id );
+
         $title = loc( 'Editing CustomField [_1]', $CustomFieldObj->Name );
     }
-    $current_tab .= "?id=$id";
 }
 
 if ( $ARGS{'Update'} && $id ne 'new' ) {
-
     #we're asking about enabled on the web page but really care about disabled.
-    $ARGS{'Disabled'} = $Disabled = $Enabled? 0 : 1;
+    $ARGS{'Disabled'} = $Enabled? 0 : 1;
+    #  likewise
+    $ARGS{'NoClone'} = $YesClone ? 0 : 1;
+   
+    $ARGS{'Required'} ||= 0;
 
-    my @attribs = qw(Disabled Pattern Name TypeComposite LookupType Description LinkValueTo IncludeContentForValue);
+    my @attribs = qw(Disabled Required Pattern Name TypeComposite LookupType Description LinkValueTo IncludeContentForValue NoClone);
     push @results, UpdateRecordObject(
         AttributesRef => \@attribs,
         Object        => $CustomFieldObj,
         ARGSRef       => \%ARGS
     );
-    $CustomFieldObj->SetValuesClass( $ValuesClass );
+    if ( ($ValuesClass||'RT::CustomFieldValues') ne $CustomFieldObj->ValuesClass ) {
+        my $original = $CustomFieldObj->ValuesClass;
+        my ($good, $msg) = $CustomFieldObj->SetValuesClass( $ValuesClass );
+        if ( $good ) {
+            $msg = loc("[_1] changed from '[_2]' to '[_3]'",
+                        loc("Field values source"), $original, $ValuesClass );
+        }
+        push @results, $msg;
+    }
+
+    # Set the render type if we have it, but unset it if the new type doesn't
+    # support render types
+    if ( $CustomFieldObj->HasRenderTypes($TypeComposite) ) {
+        my $original = $CustomFieldObj->RenderType;
 
-    $CustomFieldObj->SetBasedOn( $BasedOn );
+        if ( defined $RenderType and $RenderType ne $original ) {
+            # It's changed!  Let's update it.
+            my ($good, $msg) = $CustomFieldObj->SetRenderType( $RenderType );
+
+            if ( $good ) {
+                $msg = loc("[_1] changed from '[_2]' to '[_3]'",
+                            loc("Render Type"), $original, $RenderType );
+            }
+
+            push @results, $msg;
+        }
+    }
+    else {
+        # Delete it if we no longer support render types
+        $CustomFieldObj->SetRenderType( undef );
+    }
+
+    if (($CustomFieldObj->BasedOn||'') ne ($BasedOn||'')) {
+        my ($good, $msg) = $CustomFieldObj->SetBasedOn( $BasedOn );
+        push @results, $msg;
+    }
+
+    $CustomFieldObj->SetUILocation( $UILocation );
 
     my $paramtag = "CustomField-". $CustomFieldObj->Id ."-Value";
     # Delete any fields that want to be deleted
     foreach my $key ( keys %ARGS ) {
-        next unless $key =~ /^Delete-$paramtag-(\d+)$/o;
+        next unless $key =~ /^Delete-$paramtag-(\d+)$/;
         my ($val, $msg) = $CustomFieldObj->DeleteValue( $1 );
         push (@results, $msg);
     }
 
+    # Clean up values
+    foreach my $param (grep /^$paramtag-/, keys(%ARGS)) {
+      for ($ARGS{$param}) {
+        s/\r+\n/\n/g;
+        s/^\s+//;
+        s/\s+$//;
+      }
+    }
+
     # Update any existing values
     my $values = $CustomFieldObj->ValuesObj;
     while ( my $value = $values->Next ) {
-        foreach my $attr qw(Name Description SortOrder Category) {
+        foreach my $attr (qw(Name Description SortOrder Category)) {
             my $param = join("-", $paramtag, $value->Id, $attr);
             next unless exists $ARGS{$param};
+            $ARGS{$param} =~ s/^\s+//;
+            $ARGS{$param} =~ s/\s+$//;
             next if ($value->$attr()||'') eq ($ARGS{$param}||'');
 
             my $mutator = "Set$attr";
             my ($id, $msg) = $value->$mutator( $ARGS{$param} );
             push (@results, $msg);
         }
+        $m->callback(CallbackName => 'AfterUpdateCustomFieldValue', CustomFieldObj => $CustomFieldObj, CustomFieldValueObj => $value, ARGSRef => \%ARGS );
     }
 
     # Add any new values
     if ( defined $ARGS{ $paramtag ."-new-Name" } && length $ARGS{ $paramtag ."-new-Name" } ) {
         my ($id, $msg) = $CustomFieldObj->AddValue(
-            map { $_ => $ARGS{ $paramtag ."-new-$_" } }
-                qw( Name Description SortOrder Category )
+            map { 
+                $ARGS{$paramtag."-new-$_"} =~ s/^\s+//;
+                $ARGS{$paramtag."-new-$_"} =~ s/\s+$//;
+                $_ => $ARGS{ $paramtag ."-new-$_" } } qw/ Name Description SortOrder Category/
         );
         push (@results, $msg);
+        $added_cfv = 1 if $id;
+
+        my $cfv = RT::CustomFieldValue->new( $session{CurrentUser} );
+        $cfv->Load($id);
+        $m->callback(CallbackName => 'AfterCreateCustomFieldValue',
+CustomFieldObj => $CustomFieldObj, CustomFieldValueObj => $cfv, ARGSRef => \%ARGS );
     }
 }
 
+if ( $CustomFieldObj->id && $CustomFieldObj->IsOnlyGlobal ) {
+    my ( $ret, $msg );
+    my $object = $CustomFieldObj->RecordClassFromLookupType->new( $session{'CurrentUser'} );
+
+    if ( $CustomFieldObj->Disabled && $CustomFieldObj->IsGlobal ) {
+        ( $ret, $msg ) = $CustomFieldObj->RemoveFromObject($object);
+    }
+    elsif ( !$CustomFieldObj->Disabled && !$CustomFieldObj->IsGlobal ) {
+        ( $ret, $msg ) = $CustomFieldObj->AddToObject($object);
+    }
+
+    # successful msg("object created" or "object deleted ) is useless here
+    push @results, $msg unless $ret;
+}
+
 $id = $CustomFieldObj->id if $CustomFieldObj->id;
 
+# This code does automatic redirection if any updates happen.
+MaybeRedirectForResults(
+    Actions     => \@results,
+    Arguments   => { id => $id, FocusAddValue => ($added_cfv ? 1 : 0) },
+) if $CustomFieldObj->id;
+
+
 my $EnabledChecked = qq[checked="checked"];
 $EnabledChecked = '' if $CustomFieldObj->Disabled;
 
+my $RequiredChecked = '';
+$RequiredChecked = qq[checked="checked"] if $CustomFieldObj->Required;
+
+my $YesCloneChecked = qq[checked="checked"];
+$YesCloneChecked = '' if $CustomFieldObj->NoClone;
+
+
 my @CFvalidations = (
     '(?#Mandatory).',
     '(?#Digits)^[\d.]+$',
@@ -234,7 +367,7 @@ $m->callback(CallbackName => 'ValidationPatterns', Values => \@CFvalidations);
 <%ARGS>
 $id => undef
 $TypeComposite => undef
-$LookupType => undef
+$LookupType => RT::Ticket->CustomFieldLookupType
 $MaxValues => undef
 $SortOrder => undef
 $Description => undef
@@ -243,7 +376,10 @@ $Name => undef
 $SetEnabled => undef
 $Enabled => 0
 $ValuesClass => 'RT::CustomFieldValues'
+$RenderType => undef
 $LinkValueTo => undef
 $IncludeContentForValue => undef
 $BasedOn => undef
+$UILocation => undef
+$YesClone => undef
 </%ARGS>