diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in index 6433198a36b..026b065c405 100644 --- a/etc/RT_Config.pm.in +++ b/etc/RT_Config.pm.in @@ -3992,8 +3992,8 @@ Set(%AdminSearchResultFormat, .q{,__Condition__, __Action__, __Template__, __Disabled__,__HasLogs__}, Templates => - q{'__id__/TITLE:#'} - .q{,'__Name__/TITLE:Name'} + q{'__id__/TITLE:#'} + .q{,'__Name__/TITLE:Name'} .q{,'__Description__','__UsedBy__','__IsEmpty__'}, Classes => q{ '__id__/TITLE:#'} diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm index 7838f3e0a5a..0cab1cede87 100644 --- a/lib/RT/Interface/Web.pm +++ b/lib/RT/Interface/Web.pm @@ -3171,8 +3171,6 @@ sub ProcessCustomFieldUpdates { return (@results); } - - =head2 ProcessTicketBasics ( TicketObj => $Ticket, ARGSRef => \%ARGS ); Returns an array of results messages. @@ -5321,6 +5319,139 @@ sub ProcessAuthToken { return @results; } +=head2 ProcessTemplateUpdate ( TemplateObj => $Template, ARGSRef => \%ARGS ); + +Accepts a Template Object and a ref to %ARGS and processes any updates +to the Template Object in %ARGS. + +Returns an array of results messages. + +=cut + +sub ProcessTemplateUpdate { + my %args = ( + TemplateObj => undef, + ARGSRef => undef, + @_ + ); + + my @results; + my @FIELDS = qw( + PerlCode + Queue + Subject + Status + SLA + Due + Starts + Started + Resolved + Owner + Requestor + Cc + AdminCc + RequestorGroup + CcGroup + AdminCcGroup + TimeWorked + TimeEstimated + TimeLeft + InitialPriority + FinalPriority + Type + DependsOn + DependedOnBy + RefersTo + ReferredToBy + Members + MemberOf + CustomFields + Content + ContentType + UpdateType + SkipCreate + ); + + # ensure $args{ARGSRef}{CreateSectionName} is an array ref + # could be undefined (new template), scalar (single section), or an array ref (multiple sections) + if ( $args{ARGSRef}{CreateSectionName} ) { + $args{ARGSRef}{CreateSectionName} = [ $args{ARGSRef}{CreateSectionName} ] + unless ref $args{ARGSRef}{CreateSectionName}; + } + else { + $args{ARGSRef}{CreateSectionName} = []; + } + + # check if the user submitted a new section without filling in section name + # if so then set a section name, making sure to set it to a unique value + unless ( $args{ARGSRef}{AddNewSectionName} ) { + for my $field ( @FIELDS ) { + if ( defined( $args{ARGSRef}{"ADD-NEW-SECTION-$field"} ) && ( $args{ARGSRef}{"ADD-NEW-SECTION-$field"} ne '' ) ) { + my $new_section_name = 'new-section'; + my $counter = 1; + while ( grep { $_ eq $new_section_name } @{ $args{ARGSRef}{CreateSectionName} } ) { + $new_section_name = 'new-section-' . $counter++; + } + $args{ARGSRef}{AddNewSectionName} = $new_section_name; + push @results, "Section Name was not filled in for the new Section. Set Section Name to '$new_section_name'"; + last; + } + } + } + + push @{ $args{ARGSRef}{CreateSectionName} }, 'ADD-NEW-SECTION' + if $args{ARGSRef}{AddNewSectionName}; + + if ( @{ $args{ARGSRef}{CreateSectionName} } ) { + my $new_content = ''; + for my $name ( @{ $args{ARGSRef}{CreateSectionName} } ) { + my $section_name = $name eq 'ADD-NEW-SECTION' ? $args{ARGSRef}{AddNewSectionName} : $name; + if ( my $new_name = $args{ARGSRef}{"$name-NewSectionName"} ) { + $section_name = $new_name; + } + $new_content .= "===Create-Ticket: $section_name\n"; + for my $field ( @FIELDS ) { + if ( $field eq "CustomFields" ) { + while ( my $cf_id = shift @{ $args{ARGSRef}{ $name . "-CustomField-id" } || [] } ) { + my $cf_val = shift @{ $args{ARGSRef}{ $name . "-CustomField-val" } || [] }; + $new_content .= "CustomField-$cf_id: $cf_val\n"; + } + } + else { + if ( my $val = $args{ARGSRef}{"$name-$field"} ) { + if ( $field eq 'PerlCode' ) { + # trim leading and trailing whitespace + $val =~ s/^\s+//; + $val =~ s/\s+$//; + $new_content .= "{\n$val\n}\n"; + } + elsif ( $field eq 'Content' ) { + $new_content .= "Content: $val\nENDOFCONTENT\n" + } + else { + $new_content .= "$field: $val\n"; + } + } + } + } + } + $args{ARGSRef}{Content} = $new_content; + } + + my @attribs = qw( Name Description Queue Type Content ); + my @aresults = UpdateRecordObject( + AttributesRef => \@attribs, + Object => $args{TemplateObj}, + ARGSRef => $args{ARGSRef} + ); + push @results, @aresults; + + my ( $ok, $msg ) = $args{TemplateObj}->CompileCheck; + push @results, $msg if !$ok; + + return ( @results ); +} + =head3 CachedCustomFieldValues FIELD Similar to FIELD->Values, but caches the return value of FIELD->Values diff --git a/lib/RT/Interface/Web/MenuBuilder.pm b/lib/RT/Interface/Web/MenuBuilder.pm index 82f67b0018c..0fd632e523e 100644 --- a/lib/RT/Interface/Web/MenuBuilder.pm +++ b/lib/RT/Interface/Web/MenuBuilder.pm @@ -1204,10 +1204,10 @@ sub _BuildAdminMenu { my $templates = $admin_global->child( templates => title => loc('Templates'), description => loc('Edit system templates'), - path => '/Admin/Global/Templates.html', + path => '/Admin/Templates/', ); - $templates->child( select => title => loc('Select'), path => "/Admin/Global/Templates.html" ); - $templates->child( create => title => loc('Create'), path => "/Admin/Global/Template.html?Create=1" ); + $templates->child( select => title => loc('Select'), path => "/Admin/Templates/" ); + $templates->child( create => title => loc('Create'), path => "/Admin/Templates/Create.html" ); my $cfadmin = $admin_global->child( 'custom-fields' => title => loc('Custom Fields'), @@ -1427,8 +1427,8 @@ sub _BuildAdminMenu { $queue->child( people => title => loc('Watchers'), path => "/Admin/Queues/People.html?id=" . $id ); my $templates = $queue->child(templates => title => loc('Templates'), path => "/Admin/Queues/Templates.html?id=" . $id); - $templates->child( select => title => loc('Select'), path => "/Admin/Queues/Templates.html?id=".$id); - $templates->child( create => title => loc('Create'), path => "/Admin/Queues/Template.html?Create=1;Queue=".$id); + $templates->child( select => title => loc('Select'), path => "/Admin/Queues/Templates.html?id=" . $id); + $templates->child( create => title => loc('Create'), path => "/Admin/Templates/Create.html?Queue=".$id); my $scrips = $queue->child( scrips => title => loc('Scrips'), path => "/Admin/Queues/Scrips.html?id=" . $id); $scrips->child( select => title => loc('Select'), path => "/Admin/Queues/Scrips.html?id=" . $id ); @@ -1654,9 +1654,22 @@ sub _BuildAdminMenu { $page->child( create => title => loc('Create'), path => "/Admin/Actions/Create.html" ); } - if ( $request_path =~ m{^/Admin/Global/Templates?\.html} ) { - $page->child( select => title => loc('Select'), path => "/Admin/Global/Templates.html" ); - $page->child( create => title => loc('Create'), path => "/Admin/Global/Template.html?Create=1" ); + if ( $request_path =~ m{^/Admin/Templates/} ) { + if ( $HTML::Mason::Commands::m->request_args->{'Template'} && $HTML::Mason::Commands::m->request_args->{'Template'} =~ /^\d+$/ ) { + my $id = $HTML::Mason::Commands::m->request_args->{'Template'}; + my $queue = $HTML::Mason::Commands::m->request_args->{'Queue'} || 0; + my $templates = $page->child( select => title => loc('Templates'), + path => "/Admin/Templates/" ); + $templates->child( select => title => loc('Select'), path => "/Admin/Templates/" ); + $templates->child( create => title => loc('Create'), path => "/Admin/Templates/Create.html" ); + $page->child( basics => title => loc('Basics'), path => "/Admin/Templates/Basics.html?Queue=$queue&Template=$id" ); + $page->child( content => title => loc('Content'), path => "/Admin/Templates/Content.html?Queue=$queue&Template=$id" ); + $page->child( advanced => title => loc('Advanced'), path => "/Admin/Templates/Advanced.html?Queue=$queue&Template=$id" ); + } + else { + $page->child( select => title => loc('Select'), path => "/Admin/Templates/" ); + $page->child( create => title => loc('Create'), path => "/Admin/Templates/Create.html" ); + } } if ( $request_path =~ m{^/Admin/Articles/Classes/} ) { diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm index 87ea9940a8a..2d079604fda 100644 --- a/lib/RT/Template.pm +++ b/lib/RT/Template.pm @@ -1113,6 +1113,108 @@ sub PreInflate { return 1; } +=head2 my ( $parsed, $error ) = ParseContentAsCreateTicket; + +Attempts to parse the value of the Content as a Create Ticket template. + +If successful it returns a list of an arrayref and an empty error +message. The arrayref contains a hashref for each section in the +template. + +If it cannot parse the Content it returns a list of undef and an error +message. + +=cut + +sub ParseContentAsCreateTicket { + my $self = shift; + + my $content = $self->Content || ''; + + # allow blank content for new templates + unless ( length($content) > 0 ) { + return ( [], '' ); + } + unless ( $self->Type eq 'Create' ) { + return ( undef, 'Template is not Type Create Ticket' ); + } + unless ( substr( $content, 0, 3 ) eq '===' ) { + return ( undef, 'Template content is not valid Create Ticket format' ); + } + + my @parsed = (); + my ( $current_ticket, %current_section ); + my @lines = split /\n/, $content; + while ( my $line = shift @lines ) { + if ( $line =~ /^===(.*)-Ticket: (.*)$/ ) { + # TODO: do we need to do anything different for different ticket action? + # Create vs Update vs Base + my $ticket_action = $1; + my $ticket_name = $2; + + if ( ! $current_ticket ) { + # first ticket template + $current_ticket = $ticket_name; + $current_section{name} = $ticket_name; + $current_section{action} = $ticket_action; + $current_section{active} = 1; + } + elsif ( $ticket_name ne $current_ticket ) { + # new ticket template + push @parsed, { %current_section }; + %current_section = (); + $current_ticket = $ticket_name; + $current_section{name} = $ticket_name; + $current_section{action} = $ticket_action; + } + } + elsif ( $line =~ /^===#.*$/ ) { # a comment + next; + } + elsif ( $line =~ /^(.*?):(?:\s+)(.*?)(?:\s*)$/ ) { + my $field = $1; + my $val = $2; + + # fields can have dashes and mixed case so normalize to no dash and lowercase + $field =~ s/-//g; + $field = lc $field; + + if ( $field eq 'content' ) { + while ( defined( my $l = shift @lines ) ) { + last if ( $l =~ /^ENDOFCONTENT\s*$/ ); + $val .= "\n" . $l; + } + $current_section{$field} = $val; + } + elsif ( $field =~ /(CustomField|CF)(.*)/i ) { + $current_section{CustomFields} = [] + unless $current_section{CustomFields}; + push @{ $current_section{CustomFields} }, [ $2, $val ]; + } + else { + $current_section{$field} = $val; + } + } + else { + # if there is a line of perl code after the initial perl code block we cannot parse it correctly + # in that case we need to return an error that the template is "too advanced" for the GUI and + # they can edit it on the Advanced tab + $line =~ s/^\s+//g; + if ( exists( $current_section{perlcode} ) && ( $line =~ /^{/ ) ) { + # we have a line opening a perl code block but we already have our perlcode block + return ( undef, 'Template content is too advanced to parse correctly' ); + } + else { + $current_section{perlcode} .= "$line\n"; + } + } + } + # push the last template on to array + push @parsed, { %current_section }; + + return ( \@parsed, '' ); +} + RT::Base->_ImportOverlays(); 1; diff --git a/share/html/Admin/Elements/ModifyCreateTemplate b/share/html/Admin/Elements/ModifyCreateTemplate new file mode 100644 index 00000000000..9aabed55789 --- /dev/null +++ b/share/html/Admin/Elements/ModifyCreateTemplate @@ -0,0 +1,346 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +% if ( $Error ) { +
+

<% $Error %>

+
+% } +% else { +<&| /Widgets/TitleBox, title => loc("Create Ticket Templates"), class => 'template-info-basics', content_class => 'mx-auto width-lg' &> +
+

+ Each Create Ticket Section in the template has its own tab below. + Click on the tab to change field values for that section. +

+

+ Click on the Add New Section tab to add a new Create Ticket Section to the template. + The Section Name field is required when adding a new Create Ticket Section to the template. +

+

+ Each Section can start with a block of Perl Code that allows you to initialize and set variables or add some logic to determine if you should create the ticket or not. + The Skip Create field allows you to skip creating a ticket for that section programatically. See here for details: Skip Create +

+

+ All fields accept a string value or you can enter Perl Code by wrapping it in brackets: { PERL CODE HERE } +
+ Make sure you end the Perl code with a value to set a value for that field: { my $val = 'Value'; $val; } +

+

+ See here for more documentation on the format of the Create Ticket Templates: Create Tickets +

+
+ +% if ( @sections ) { +
+ +
+% for my $section ( @sections ) { +
{name} %>"> +<&| /Widgets/TitleBox, title => loc("Perl Code"), class=>'ticket-info-basics' &> +% if ( $section->{name} eq 'ADD-NEW-SECTION' ) { + <&| /Elements/LabeledValue, Label => loc('Section Name'), Class => 'edit-custom-field' &> +
+
+ 1 ? '' : 'required' %> class="form-control" /> +
+
+ +% } +% else { + + <&| /Elements/LabeledValue, Label => loc('Section Name'), Class => 'edit-custom-field' &> +
+
+ +
+
+
+
+

+
+
+ +% } + + <&| /Elements/LabeledValue, Label => loc('Perl Code'), Class => 'edit-custom-field' &> +
+
+% my $perlcode = $section->{perlcode} || ''; +% $perlcode =~ s/^\s?{//; +% $perlcode =~ s/}\s?$//; + +
+
+ + + <&| /Elements/LabeledValue, Label => loc('Skip Create'), Class => 'edit-custom-field' &> +
+
+ +
+
+ + + +<&| /Widgets/TitleBox, title => loc("Content"), class=>'ticket-info-basics' &> +% foreach my $field ( qw( UpdateType ContentType Content ) ) { + <& /Elements/CreateTemplate/FieldInput, + Section => $section->{name}, + Field => $field, + Value => $section->{ lc $field } || '', + &> +% } + + +
+
+<&| /Widgets/TitleBox, title => loc("The Basics"), class=>'ticket-info-basics' &> +% foreach my $field ( qw( Type Subject Status Queue SLA TimeEstimated TimeWorked TimeLeft InitialPriority FinalPriority ) ) { + <& /Elements/CreateTemplate/FieldInput, + Section => $section->{name}, + Field => $field, + Value => $section->{ lc $field } || '', + &> +% } + + +<&| /Widgets/TitleBox, title => loc("People"), class=>'ticket-info-people' &> +% foreach my $field ( qw( Owner Requestor Cc AdminCc RequestorGroup CcGroup AdminCcGroup ) ) { + <& /Elements/CreateTemplate/FieldInput, + Section => $section->{name}, + Field => $field, + Value => $section->{ lc $field } || '', + &> +% } + +
+
+<&| /Widgets/TitleBox, title => loc("Dates"), class=>'ticket-info-dates' &> +% foreach my $field ( qw( Starts Started Due Resolved ) ) { + <& /Elements/CreateTemplate/FieldInput, + Section => $section->{name}, + Field => $field, + Value => $section->{ lc $field } || '', + &> +% } + + +<&| /Widgets/TitleBox, title => loc("Links"), class=>'ticket-info-links' &> +% foreach my $field ( qw( DependsOn DependedOnBy RefersTo ReferredToBy Members MemberOf ) ) { + <& /Elements/CreateTemplate/FieldInput, + Section => $section->{name}, + Field => $field, + Value => $section->{ lc $field } || '', + &> +% } + + +<&| /Widgets/TitleBox, title => loc("Custom Fields"), class=>'ticket-info-cfs' &> + <&| /Elements/LabeledValue, Label => loc('Custom Fields'), Class => 'edit-custom-field' &> +
+% foreach my $cf ( @{ $section->{CustomFields} || [] } ) { +% my ( $cf_id, $value ) = @$cf; +
+
+ +
+
+ +
+
+ +
+
+% } + +
+
+
+ " onclick="AddCustomField('<% $section->{name} %>'); return false;"> +
+
+ +
+
+% unless ( $section->{name} eq 'ADD-NEW-SECTION' ) { +
+ +
+% } +
+% } +
+% } + + +% } +<%INIT> +my ( @sections, $Template, $Error ); +if ( $TemplateObj && $TemplateObj->Id ) { + $Template = $TemplateObj->Name; + + my ( $sections, $error ) = $TemplateObj->ParseContentAsCreateTicket; + if ( $sections ) { + @sections = @$sections; + } + else { + RT->Logger->error( "Unable to parse '$Template': $error" ); + if ( $error =~ /too advanced/ ) { + $Error = "Unable to parse '$Template': This template has multiple Perl Code blocks and cannot be parsed. Please use the Advanced tab."; + } + else { + $Error = "Unable to parse '$Template': $error"; + } + } + + # add a blank section for new templates or for adding a new ticket section + push @sections, { name => 'ADD-NEW-SECTION', active => ( @sections ? 0 : 1 ) }; +} + +<%ARGS> +$TemplateObj +$QueueObj => undef + \ No newline at end of file diff --git a/share/html/Admin/Elements/ModifyTemplate b/share/html/Admin/Elements/ModifyTemplate index 53ddc794ccc..29ce6bcc9c1 100644 --- a/share/html/Admin/Elements/ModifyTemplate +++ b/share/html/Admin/Elements/ModifyTemplate @@ -46,63 +46,106 @@ %# %# END BPS TAGGED BLOCK }}} <&| /Widgets/TitleBox, class => 'template-info-basics', content_class => 'mx-auto width-lg' &> -
-
- <&|/l&>Name: -
-
- -
-
- -
-
- <&|/l&>Description: +% if ( $Page eq 'Basics' ) { +
+
+ <&|/l&>Name: +
+
+ +
-
- +
+
+ <&|/l&>Description: +
+
+ +
-
- -
-
- <&|/l&>Type: +
+
+ <&|/l&>Type: +
+
+ +
-
-
- > -
+
+
+ <&|/l&>Applied to:
-
- > -
+
+% if ( $AppliedTo ) { + + <% $AppliedToName %> + +% } +% else { + + <&|/l&>Global + +% }
-
- +% } +% else { + + + +% }
+% if ( ( $Page eq 'Content' ) && ( $Type eq 'Create' ) ) { +
+ <& /Admin/Elements/ModifyCreateTemplate, + TemplateObj => $TemplateObj, + QueueObj => $QueueObj, + &> +
+% } +% elsif ( ( $Page eq 'Content' ) || ( $Page eq 'Advanced' ) ) {
<&|/l&>Content:
- +
+% }
- <%INIT> +my $Name = $TemplateObj->Name // $ARGS{Name}; +my $Description = $TemplateObj->Description // $ARGS{Description}; +my $Content = $TemplateObj->Content // $ARGS{Content}; +my $Type = $TemplateObj->Type // $ARGS{Type}; unless ($Type) { $Type = $session{'CurrentUser'}->HasRight(Right => 'ExecuteCode', Object => $RT::System) ? 'Perl' : 'Simple'; } - +my $AppliedTo; +$AppliedTo = $QueueObj->id + if $QueueObj; +if ( $AppliedTo ) { + $AppliedToName = $QueueObj->Name; +} + + <%ARGS> -$Name => '' -$Description => '' -$Content => '' -$Type => '' +$TemplateObj +$QueueObj => undef +$Page => 'Basics' +$AppliedToName => '' diff --git a/share/html/Admin/Elements/ModifyTemplatePage b/share/html/Admin/Elements/ModifyTemplatePage new file mode 100644 index 00000000000..d1ee7191858 --- /dev/null +++ b/share/html/Admin/Elements/ModifyTemplatePage @@ -0,0 +1,89 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +
+ +%# hang onto the queue id and tab setting + +<& /Admin/Elements/ModifyTemplate, + ARGSRef => \%ARGS, + QueueObj => $QueueObj, + TemplateObj => $TemplateObj, + Page => $Page, +&> +
+
+ <& /Elements/Submit, Label => $SubmitLabel, Reset => 1 &> +
+
+
+<%INIT> +my $TemplateObj = RT::Template->new($session{'CurrentUser'}); +my ( $title, @results, $SubmitLabel, $QueueObj ); + +$TemplateObj->Load($Template) || Abort( loc('No Template') ); + +if ( $TemplateObj->Id() ) { + $QueueObj = $TemplateObj->QueueObj + if $Queue; + + push @results, ProcessTemplateUpdate( TemplateObj => $TemplateObj, ARGSRef => \%ARGS ); +} + +$title = ( $QueueObj && $QueueObj->id ) ? loc( 'Modify template [_1] for queue [_2]', loc( $TemplateObj->Name() ), $QueueObj->Name ) + : loc( 'Modify template [_1]', loc( $TemplateObj->Name() ) ); +$SubmitLabel = loc('Save Changes'); + +<%ARGS> +$Queue => '' +$Template => '' +$Page => 'Basics' + \ No newline at end of file diff --git a/share/html/Admin/Templates/Advanced.html b/share/html/Admin/Templates/Advanced.html new file mode 100644 index 00000000000..8d0a2899211 --- /dev/null +++ b/share/html/Admin/Templates/Advanced.html @@ -0,0 +1,48 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/ModifyTemplatePage, %ARGS, Page => 'Advanced' &> \ No newline at end of file diff --git a/share/html/Admin/Templates/Basics.html b/share/html/Admin/Templates/Basics.html new file mode 100644 index 00000000000..ec3b521c08e --- /dev/null +++ b/share/html/Admin/Templates/Basics.html @@ -0,0 +1,48 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/ModifyTemplatePage, %ARGS &> \ No newline at end of file diff --git a/share/html/Admin/Templates/Content.html b/share/html/Admin/Templates/Content.html new file mode 100644 index 00000000000..7d5e202d590 --- /dev/null +++ b/share/html/Admin/Templates/Content.html @@ -0,0 +1,48 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/ModifyTemplatePage, %ARGS, Page => 'Content' &> \ No newline at end of file diff --git a/share/html/Admin/Templates/Create.html b/share/html/Admin/Templates/Create.html new file mode 100644 index 00000000000..edb84be4085 --- /dev/null +++ b/share/html/Admin/Templates/Create.html @@ -0,0 +1,109 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/Header, Title => $title &> +<& /Elements/Tabs &> +<& /Elements/ListActions, actions => \@results &> + +
+ + +%# hang onto the queue id and tab setting + +<& /Admin/Elements/ModifyTemplate, + ARGSRef => \%ARGS, + TemplateObj => $TemplateObj, + QueueObj => $QueueObj, +&> +
+
+ <& /Elements/Submit, Label => $SubmitLabel, Reset => 1 &> +
+
+
+<%INIT> +my $TemplateObj = RT::Template->new( $session{'CurrentUser'} ); +my ( $title, @results, $SubmitLabel, $QueueObj ); + +if ( defined($Template) && $Template eq 'new' ) { + my ( $val, $msg ) = $TemplateObj->Create( Queue => $Queue, Name => $Name, Type => $Type ); + push @results, $msg; +} + +if ( $TemplateObj->Id() ) { + $QueueObj = $TemplateObj->QueueObj + if $Queue; + + push @results, ProcessTemplateUpdate( TemplateObj => $TemplateObj, ARGSRef => \%ARGS ); + + # if this was a new template need to reload the page so the Basics, Content, and Advanced menu options show + if ( defined($Template) && $Template eq 'new' ) { + my $request_path = $HTML::Mason::Commands::r->path_info; + MaybeRedirectForResults( + Actions => \@results, + Path => '/Admin/Templates/Basics.html', + Arguments => { Queue => $Queue, Template => $TemplateObj->Id }, + ); + } +} +else { + if ( $Queue ) { + $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); + $QueueObj->Load($Queue) + } +} + +$title = ( $QueueObj && $QueueObj->id ) ? loc( 'Create a new template for queue [_1]', $QueueObj->Name ) + : loc("Create a template"); +$SubmitLabel = loc('Create'); + +<%ARGS> +$Queue => '' +$Template => '' +$Name => '' +$Type => '' + \ No newline at end of file diff --git a/share/html/Admin/Templates/index.html b/share/html/Admin/Templates/index.html new file mode 100644 index 00000000000..4f00b597da0 --- /dev/null +++ b/share/html/Admin/Templates/index.html @@ -0,0 +1,57 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<& /Admin/Elements/Header, Title => $title, FeedURI => 'templates' &> +<& /Elements/Tabs &> +<& /Admin/Elements/EditTemplates, title => $title, %ARGS &> +<%init> +my $title = loc("Modify templates which apply to all queues"); +my (@actions); + +<%ARGS> +$id => undef + diff --git a/share/html/Elements/CreateTemplate/FieldInput b/share/html/Elements/CreateTemplate/FieldInput new file mode 100644 index 00000000000..46577f5ba2a --- /dev/null +++ b/share/html/Elements/CreateTemplate/FieldInput @@ -0,0 +1,73 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC +%# +%# +%# (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 }}} +<&| /Elements/LabeledValue, Label => $Label, Class => 'edit-custom-field' &> +
+
+ +
+
+ +<%INIT> +my %LabelForField = ( + Members => 'Members (Children)', + MemberOf => 'Member Of (Parents)', +); + +my $Label = $LabelForField{$Field}; +if ( ! $Label ) { + $Label = $Field; + # split CamelCase to Camel Case + $Label =~ s/([A-Z][a-z]+)(?=[A-Z])/$1 /g; +} +$Label = loc($Label); + +<%ARGS> +$Section +$Field +$Value + \ No newline at end of file diff --git a/t/web/html_template.t b/t/web/html_template.t index abb895c75a5..7d071da3702 100644 --- a/t/web/html_template.t +++ b/t/web/html_template.t @@ -15,6 +15,7 @@ my $content = Encode::decode("UTF-8", "测试"); { $m->follow_link_ok( { id => 'admin-global-templates' }, '-> Templates' ); $m->follow_link_ok( { text => 'Autoreply in HTML' }, '-> Autoreply in HTML' ); + $m->follow_link_ok( { text => 'Content' }, '-> Content' ); $m->submit_form( form_name => 'ModifyTemplate', diff --git a/t/web/template.t b/t/web/template.t index 4bca733c65b..69a570fef9b 100644 --- a/t/web/template.t +++ b/t/web/template.t @@ -60,10 +60,12 @@ $m->form_name('ModifyTemplate'); is($m->value('Type'), 'Perl', 'now that we have ExecuteCode we can update Type to Perl'); { # 21152: Each time you save a Template a newline is chopped off the front + # go to Content tab + $m->follow_link( text => 'Content' ); + $m->form_name('ModifyTemplate'); my $content; - TODO: { local $TODO = "WWW::Mechanize doesn't strip newline following