diff options
Diffstat (limited to 'rt/share/html/Elements')
35 files changed, 1028 insertions, 180 deletions
diff --git a/rt/share/html/Elements/AddCustomers b/rt/share/html/Elements/AddCustomers new file mode 100644 index 000000000..aaf8ca8ba --- /dev/null +++ b/rt/share/html/Elements/AddCustomers @@ -0,0 +1,59 @@ +%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am> +%# Copyright (c) 2008 Freeside Internet Services, Inc. +%# +%# 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. +<BR> +<%$msg%><br> + +% if (@Customers) { + +<br><i>(Check box to link)<i> +<table> +% foreach my $customer (@Customers) { +<tr> + <td> + <input type="checkbox" name="Object-AddCustomer-<% $customer->{'custnum'} %>" VALUE="1" <% scalar(@Customers) == 1 ? 'CHECKED' : '' %>> + <A HREF="<%$freeside_url%>/view/cust_main.cgi?<% $customer->{'custnum'} %>"><% &RT::URI::freeside::small_custview($customer->{'custnum'}, &RT::URI::freeside::FreesideGetConfig('countrydefault'), 1) |n %> + </td> +</tr> +% } +</table> + +% } + +<%INIT> +my ($msg); + +my $freeside_url = &RT::URI::freeside::FreesideURL(); + +warn "/Elements/AddCustomers called with CustomerString $CustomerString\n" + if $Debug; + +my @Customers = (); +if ( $CustomerString ) { + @Customers = &RT::URI::freeside::smart_search( 'search' => $CustomerString ); +} + +my @Services = (); +if ($ServiceString) { + @Services = (); #service_search(); +} + +warn "/Elements/AddCustomers displaying ". scalar(@Customers). " customers\n" + if $Debug; + +</%INIT> + +<%ARGS> +$CustomerString => undef +$ServiceString => undef +$Debug => 0 +</%ARGS> diff --git a/rt/share/html/Elements/CalendarEvent b/rt/share/html/Elements/CalendarEvent new file mode 100644 index 000000000..3a6b00bb8 --- /dev/null +++ b/rt/share/html/Elements/CalendarEvent @@ -0,0 +1,129 @@ +<%args> +$Date => undef +$Object => undef +$DateTypes => undef +</%args> +<div class="tooltip"> +<small> + +% if ($IsReminder and RTx::Calendar::LocalDate($Object->DueObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/reminder.png" /> + +% } elsif ($DateTypes->{Resolved} +% and RTx::Calendar::LocalDate($Object->ResolvedObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/resolved.png" /> + +% } elsif ($DateTypes->{Starts} and $DateTypes->{Due} +% and RTx::Calendar::LocalDate($Object->StartsObj->Unix) eq $today and RTx::Calendar::LocalDate($Object->DueObj->Unix) eq $today ) { + <img src="<%$RT::WebImagesURL%>/starts_due.png" /> + +% } elsif ($DateTypes->{Due} and $DateTypes->{Created} +% and RTx::Calendar::LocalDate($Object->DueObj->Unix) eq $today and RTx::Calendar::LocalDate($Object->CreatedObj->Unix) eq $today ) { + <img src="<%$RT::WebImagesURL%>/created_due.png" /> + +% } elsif ($DateTypes->{Starts} +% and RTx::Calendar::LocalDate($Object->StartsObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/starts.png" /> + +% } elsif ($DateTypes->{Due} +% and RTx::Calendar::LocalDate($Object->DueObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/due.png" /> + +% } elsif ($DateTypes->{Created} +% and RTx::Calendar::LocalDate($Object->CreatedObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/created.png" /> + +% } elsif ($DateTypes->{Started} +% and RTx::Calendar::LocalDate($Object->StartedObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/started.png" /> + +% } elsif ($DateTypes->{LastUpdated} +% and RTx::Calendar::LocalDate($Object->LastUpdatedObj->Unix) eq $today) { + <img src="<%$RT::WebImagesURL%>/updated.png" /> + +% } + + <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$TicketId%>"> + <% $Object->QueueObj->Name %> #<% $TicketId %> + <% $display_owner ? 'by ' . $Object->OwnerObj->Name : '' %> + <% length($Object->Subject) > 80 ? substr($Object->Subject, 0, 77) . "..." : $Object->Subject %></a></small><br /> + <span class="tip"> + <a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$TicketId%>"> + <% $Object->QueueObj->Name %> #<% $TicketId %> + </a> + :</strong> <% $subject%><br /> + <br /> + +%# logic taken from Ticket/Search/Results.tsv +% foreach my $attr (@display_fields) { +% my $value; +% +% if ($attr =~ /(.*)->ISO$/ and $Object->$1->Unix <= 0) { +% $value = '-'; +% } else { +% my $method = '$Object->'.$attr.'()'; +% $method =~ s/->ISO\(\)$/->ISO( Timezone => 'user' )/; +% $value = eval $method; +% if ($@) {die "<b>Check your CalendarPopupFields config in etc/RT_SiteConfig.pm</b>.<br /><br />Failed to find \"$attr\" - ". $@}; +% } + <strong><&|/l&><% $label_of{$attr} %></&>:</strong> <% $value %><br /> +% } + +<br /> + </span> +</div> + +<%init> +use RTx::Calendar; + +my $today = $Date->strftime("%F"); + +my $TicketId; + +my $ticket; +my $subject; +my $IsReminder; + +if ($Object->Type eq 'reminder') { + $IsReminder = 1; + if ($Object->RefersTo->First) { + $ticket = $Object->RefersTo->First->TargetObj; + $TicketId = $ticket->Id; + $subject = $Object->Subject . " (" . $ticket->Subject . ")"; + } +} else { + $TicketId = $Object->Id; + $subject = $Object->Subject; +} + +my $display_owner = $RT::CalendarDisplayOwner; +$display_owner ||= RT->Config->Get('CalendarDisplayOwner') + if RT->can('Config'); + + +# 3.6 config +my @display_fields = @RT::CalendarPopupFields; + +# 3.8 config +# the if condition is weird but it doesn't work with 3.8.0 without the last part +@display_fields = RT->Config->Get('CalendarPopupFields') + if 0 == @display_fields and RT->can('Config') and RT->Config->Get('CalendarPopupFields'); + +# default +if (0 == @display_fields) { + @display_fields = qw(OwnerObj->Name CreatedObj->ISO StartsObj->ISO + StartedObj->ISO LastUpdatedObj->ISO DueObj->ISO + ResolvedObj->ISO Status Priority + Requestors->MemberEmailAddressesAsString); +} + + +my %label_of; +for my $field (@display_fields) { + my $label = $field; + $label =~ s'Obj-.(?:AsString|Name|ISO)''g; + $label =~ s'-\>MemberEmailAddressesAsString''g; + $label_of{$field} = $label; +} + +</%init> diff --git a/rt/share/html/Elements/CollectionAsTable/Row b/rt/share/html/Elements/CollectionAsTable/Row index fa7474b6c..a1af9f383 100644 --- a/rt/share/html/Elements/CollectionAsTable/Row +++ b/rt/share/html/Elements/CollectionAsTable/Row @@ -54,9 +54,10 @@ $Depth => undef $Warning => undef $ColumnMap => {} $Class => 'RT__Ticket' +$Classes => '' </%ARGS> <%init> -$m->out( '<tr class="' +$m->out( '<tr class="' . $Classes . ' ' . ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' ) . '" >' . "\n" ); use HTML::Entities; diff --git a/rt/share/html/Elements/CollectionList b/rt/share/html/Elements/CollectionList index 6f21420f5..4e06e3f0a 100644 --- a/rt/share/html/Elements/CollectionList +++ b/rt/share/html/Elements/CollectionList @@ -54,7 +54,9 @@ if (!$Collection && $Class eq 'RT::Tickets') { my $TotalFound = $Collection->CountAll(); return '' if !$TotalFound && !$ShowEmpty; -if ( @OrderBy ) { +# XXX: ->{'order_by'} is hacky, but there is no way to check if +# collection is ordered or not +if ( @OrderBy && ($AllowSorting || !$Collection->{'order_by'}) ) { if ( $OrderBy[0] =~ /\|/ ) { @OrderBy = split /\|/, $OrderBy[0]; @Order = split /\|/,$Order[0]; @@ -121,14 +123,30 @@ if ( $ShowHeader ) { my ($i, $column_map) = (0, {}); while ( my $record = $Collection->Next ) { # Every ten rows, flush the buffer and put something on the page. - $m->flush_buffer unless ++$i % 10; + #broken w/FS, causes rows to be output prematurely + #$m->flush_buffer unless ++$i % 10; + ++$i; + + my $warning = 0; + my $Classes = ''; + + $m->callback( + CallbackName => 'EachRow', + Record => $record, + Warning => \$warning, + Classes => \$Classes, + Format => \@Format, + ); + $m->comp('/Elements/CollectionAsTable/Row', - i => $i, - Format => \@Format, - record => $record, - maxitems => $maxitems, + i => $i, + Format => \@Format, + record => $record, + maxitems => $maxitems, ColumnMap => $column_map, Class => $Class, + Warning => $warning, + Classes => $Classes, ); } diff --git a/rt/share/html/Elements/ColumnMap b/rt/share/html/Elements/ColumnMap index 71517e063..a1475a99d 100644 --- a/rt/share/html/Elements/ColumnMap +++ b/rt/share/html/Elements/ColumnMap @@ -92,6 +92,26 @@ my $COLUMN_MAP = { value => sub { return $_[0]->LastUpdatedByObj->Name } }, + CustomField => { + attribute => sub { return shift @_ }, + title => sub { return pop @_ }, + value => sub { + # Display custom field contents, separated by newlines. + # For Image custom fields we also show a thumbnail here. + + my $values = $_[0]->CustomFieldValues( $_[-1] ); + my @values = map { + ( + ($_->CustomFieldObj->Type eq 'Image') + ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ )) + : $_->Content + ), + \'<br />', + } @{ $values->ItemsArrayRef }; + pop @values; # Remove that last <br /> + return @values; + }, + }, CheckBox => { title => sub { @@ -136,8 +156,12 @@ my $COLUMN_MAP = { $_ => { value => sub { return \$value } }; } qw(WebPath WebBaseURL WebURL)), + WebRequestPath => { value => sub { substr( $m->request_path, 1 ) } }, + WebRequestPathDir => { value => sub { substr( $m->request_comp->dir_path, 1 ) } }, }; +$COLUMN_MAP->{'CF'} = $COLUMN_MAP->{'CustomField'}; + </%ONCE> <%INIT> $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 ); diff --git a/rt/share/html/Elements/CreateTicket b/rt/share/html/Elements/CreateTicket index 9c8f3aadf..fd2ba9e53 100755 --- a/rt/share/html/Elements/CreateTicket +++ b/rt/share/html/Elements/CreateTicket @@ -45,6 +45,9 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<form action="<% RT->Config->Get('WebPath') %>/Ticket/Create.html" name="CreateTicketInQueue" id="CreateTicketInQueue"> -<&|/l, $m->scomp('/Elements/SelectNewTicketQueue', OnChange => 'document.CreateTicketInQueue.submit()')&><input type="submit" class="button" value="New ticket in" /> [_1]</&> +<form action="<% RT->Config->Get('WebPath') %><% $SendTo %>" name="CreateTicketInQueue" id="CreateTicketInQueue"> +<&|/l, $m->scomp('/Elements/SelectNewTicketQueue', OnChange => 'document.CreateTicketInQueue.submit()', SendTo => $SendTo ) &><input type="submit" class="button" value="New ticket in" /> [_1]</&> </form> +<%ARGS> +$SendTo => '/Ticket/Create.html', +</%ARGS> diff --git a/rt/share/html/Elements/EditCustomFieldDate b/rt/share/html/Elements/EditCustomFieldDate new file mode 100644 index 000000000..b6359d7e0 --- /dev/null +++ b/rt/share/html/Elements/EditCustomFieldDate @@ -0,0 +1,62 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2008 Best Practical Solutions, LLC +%# <jesse@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/copyleft/gpl.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 }}} +% my $name = $NamePrefix.$CustomField->Id.'-Values'; +<& /Elements/SelectDate, Name => "$name", ShowTime => 0, current => 0 &> (<%$DateObj->AsString%>) + +<%INIT> +my $DateObj = new RT::Date ( $session{'CurrentUser'} ); +$DateObj->Set( Format => 'ISO', Value => $Default ); +</%INIT> +<%ARGS> +$Object => undef +$CustomField => undef +$NamePrefix => undef +$Default => undef +$Values => undef +$MaxValues => 1 +</%ARGS> diff --git a/rt/share/html/Elements/EditCustomFieldSelect b/rt/share/html/Elements/EditCustomFieldSelect index 8fe79f9f9..30b06dbd1 100644 --- a/rt/share/html/Elements/EditCustomFieldSelect +++ b/rt/share/html/Elements/EditCustomFieldSelect @@ -52,7 +52,7 @@ % my @category; % my $id = $NamePrefix . $CustomField->Id; % my $out = $m->scomp('SELF:options', %ARGS, SelectedRef => \$selected, CategoryRef => \@category); -% if (@category and not $CustomField->BasedOnObj->id) { +% if (!$HideCategory and @category and not $CustomField->BasedOnObj->id) { <script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/NoAuth/js/cascaded.js"></script> %# XXX - Hide this select from w3m? <select onchange="filter_cascade('<% $id %>-Values', this.value)" name="<% $id %>-Category" class="CF-<%$CustomField->id%>-Edit"> @@ -108,6 +108,7 @@ $Default => undef $Values => undef $Multiple => 0 $Rows => undef +$HideCategory => 0 </%ARGS> <%METHOD options> diff --git a/rt/share/html/Elements/EditCustomers b/rt/share/html/Elements/EditCustomers new file mode 100644 index 000000000..68efb5f40 --- /dev/null +++ b/rt/share/html/Elements/EditCustomers @@ -0,0 +1,63 @@ +%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am> +%# Copyright (c) 2008 Freeside Internet Services, Inc. +%# +%# 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. +<TABLE width=100%> + <TR> + <TD VALIGN=TOP WIDTH=50%> + <h3><&|/l&>Current Customers</&></h3> + +<table> + <tr> + <td><i><&|/l&>(Check box to disassociate)</&></i></td> + </tr> + <tr> + <td class="value"> +% foreach my $link ( @{ $Object->Customers->ItemsArrayRef } ) { + + <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>"> +%# <& ShowLink, URI => $link->TargetURI &><br> + <A HREF="<% $link->TargetURI->Resolver->HREF %>"><% $link->TargetURI->Resolver->AsStringLong |n %></A> + <BR> +% } + </td> + </tr> +</table> + +</TD> + +<TD VALIGN=TOP> +<h3><&|/l&>New Customer Links</&></h3> +<&|/l&>Find customer</&><BR> +<input name="CustomerString"> +<input type=submit name="OnlySearchForCustomers" value="<&|/l&>Go!</&>"> +<br><i>cust #, name, company or phone</i> +<BR> +%#<BR> +%#<&|/l&>Find service</&><BR> +%#<input name="ServiceString"> +%#<input type=submit name="OnlySearchForServices" value="<&|/l&>Go!</&>"> +%#<br><i>username, username@domain, domain, or IP address</i> +%#<BR> + +<& AddCustomers, Object => $Object, + CustomerString => $CustomerString, + ServiceString => $ServiceString, &> + +</TD> +</TR> +</TABLE> + +<%ARGS> +$CustomerString => undef +$ServiceString => undef +$Object => undef +</%ARGS> diff --git a/rt/share/html/Elements/EditLinks b/rt/share/html/Elements/EditLinks index 637762e1b..90acb4692 100755 --- a/rt/share/html/Elements/EditLinks +++ b/rt/share/html/Elements/EditLinks @@ -52,7 +52,7 @@ <table> <tr> - <td class="labeltop"><&|/l&>Depends on</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>:</td> <td class="value"> % while (my $link = $Object->DependsOn->Next) { <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" /> @@ -61,7 +61,7 @@ </td> </tr> <tr> - <td class="labeltop"><&|/l&>Depended on by</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>:</td> <td class="value"> % while (my $link = $Object->DependedOnBy->Next) { <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" /> @@ -70,7 +70,7 @@ </td> </tr> <tr> - <td class="labeltop"><&|/l&>Parents</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>:</td> <td class="value"> % while (my $link = $Object->MemberOf->Next) { <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" /> @@ -79,7 +79,7 @@ </td> </tr> <tr> - <td class="labeltop"><&|/l&>Children</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>:</td> <td class="value"> % while (my $link = $Object->Members->Next) { <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" /> @@ -88,7 +88,7 @@ </td> </tr> <tr> - <td class="labeltop"><&|/l&>Refers to</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>:</td> <td class="value"> % while (my $link = $Object->RefersTo->Next) { <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" /> @@ -97,7 +97,7 @@ </td> </tr> <tr> - <td class="labeltop"><&|/l&>Referred to by</&>:</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:</td> <td class="value"> % while (my $link = $Object->ReferredToBy->Next) { % # Skip reminders @@ -134,27 +134,27 @@ </tr> % } <tr> - <td class="label"><&|/l&>Depends on</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>:</td> <td class="entry"><input name="<%$id%>-DependsOn" /></td> </tr> <tr> - <td class="label"><&|/l&>Depended on by</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>:</td> <td class="entry"><input name="DependsOn-<%$id%>" /></td> </tr> <tr> - <td class="label"><&|/l&>Parents</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>:</td> <td class="entry"><input name="<%$id%>-MemberOf" /></td> </tr> <tr> - <td class="label"><&|/l&>Children</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>:</td> <td class="entry"> <input name="MemberOf-<%$id%>" /></td> </tr> <tr> - <td class="label"><&|/l&>Refers to</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>:</td> <td class="entry"><input name="<%$id%>-RefersTo" /></td> </tr> <tr> - <td class="label"><&|/l&>Referred to by</&>:</td> + <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:</td> <td class="entry"> <input name="RefersTo-<%$id%>" /></td> </tr> % $m->callback( CallbackName => 'NewLink' ); diff --git a/rt/share/html/Elements/EditPassword b/rt/share/html/Elements/EditPassword new file mode 100644 index 000000000..3b0ec0b32 --- /dev/null +++ b/rt/share/html/Elements/EditPassword @@ -0,0 +1,34 @@ +% unless ( $cond{'CanSet'} ) { +<% $cond{'Reason'} %><br /> +% } else { +<table> + +% if ( $cond{'RequireCurrent'} ) { +<tr> +<td><&|/l&>Your current password</&>:</td> +<td><input type="password" name="<% $Name[0] %>" size="16" autocomplete="off" /></td> +</tr> +% } + +<tr> +<td><&|/l&>New password</&>:</td> +<td><input type="password" name="<% $Name[1] %>" size="16" autocomplete="off" /></td> +</tr> + +<tr> +<td><&|/l&>Retype Password</&>:</td> +<td><input type="password" name="<% $Name[2] %>" size="16" autocomplete="off" /></td> +</tr> + +</table> +% } + +<%ARGS> +$User +@Name => qw(CurrentPass NewPass1 NewPass2) +</%ARGS> +<%INIT> + +my %cond = $User->CurrentUserRequireToSetPassword; + +</%INIT> diff --git a/rt/share/html/Elements/Footer b/rt/share/html/Elements/Footer index 2fcdee949..59547e238 100755 --- a/rt/share/html/Elements/Footer +++ b/rt/share/html/Elements/Footer @@ -48,25 +48,6 @@ %# End of div#body from /Elements/PageLayout </div> % $m->callback( %ARGS ); -<div id="footer"> -% if ($m->{'rt_base_time'}) { - <p id="time"> - <span><&|/l&>Time to display</&>: <%Time::HiRes::tv_interval( $m->{'rt_base_time'} )%></span> - </p> -%} - <p id="bpscredits"> - <span> -<&|/l, '»|«', $RT::VERSION, '2009', '<a href="http://www.bestpractical.com?rt='.$RT::VERSION.'">Best Practical Solutions, LLC</a>', &>[_1] RT [_2] Copyright 1996-[_3] [_4].</&> -</span> -</p> -% if (!$Menu) { - <p id="legal"> -<&|/l&>Distributed under version 2 <a href="http://www.gnu.org/copyleft/gpl.html"> of the GNU GPL.</a></&><br /> -<&|/l, '<a href="mailto:sales@bestpractical.com">sales@bestpractical.com</a>' &>To inquire about support, training, custom development or licensing, please contact [_1].</&><br /> - </p> -% } - -</div> % if ($Debug >= 2 ) { % require Data::Dumper; % my $d = Data::Dumper->new([\%ARGS], [qw(%ARGS)]); diff --git a/rt/share/html/Elements/Header b/rt/share/html/Elements/Header index 953efcb22..72e3e7220 100755 --- a/rt/share/html/Elements/Header +++ b/rt/share/html/Elements/Header @@ -45,61 +45,67 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<& /elements/header.html, { + 'title' => $Title, + 'head' => $head, + 'etc' => $etc, + 'nobr' => 1, + 'nocss' => 1, + } +&> +<%INIT> +$r->headers_out->{'Pragma'} = 'no-cache'; +$r->headers_out->{'Cache-control'} = 'no-cache'; -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> -<title><%$Title%></title> +my $id = $m->request_comp->path; +$id =~ s|^/||g; +$id =~ s|/|-|g; +$id =~ s|\.html$||g; +$id =~ s|index$||g + if $id ne 'index'; +$id =~ s|-$||g; +my $head = ''; -% if ($Refresh && $Refresh =~ /^(\d+)/ && $1 > 0) { - <meta http-equiv="refresh" content="<% $Refresh %>" /> -% } +if ($Refresh && $Refresh =~ /^(\d+)/ && $1 > 0) { + $head .= '<meta http-equiv="refresh" content="$Refresh" />'; +} -<link rel="shortcut icon" href="<%RT->Config->Get('WebImagesURL')%>/favicon.png" type="image/png" /> -<link rel="stylesheet" href="<%RT->Config->Get('WebPath')%>/NoAuth/css/<% RT->Config->Get( 'WebDefaultStylesheet', $session{'CurrentUser'} ) %>/main<% RT->Config->Get('DevelMode')? '' : '-squished' %>.css" type="text/css" media="all" /> -<link rel="stylesheet" href="<%RT->Config->Get('WebPath')%>/NoAuth/css/print.css" type="text/css" media="print" /> +my $WebPath = RT->Config->Get('WebPath'); +my $WebImagesURL = RT->Config->Get('WebImagesURL'); +my $WebDefaultStylesheet = + RT->Config->Get('WebDefaultStylesheet', $session{'CurrentUser'}); +my $squished = RT->Config->Get('DevelMode') ? '' : '-squished'; -% for (keys %{$LinkRel || {}}) { - <link rel="<% $_ %>" href="<% RT->Config->Get('WebPath') . $LinkRel->{$_} %>" /> -% } +$head .= <<END; +<link rel="shortcut icon" href="$WebImagesURL/favicon.png" type="image/png" /> +<link rel="stylesheet" href="$WebPath/NoAuth/css/$WebDefaultStylesheet/main$squished.css" type="text/css" media="all" /> +<link rel="stylesheet" href="$WebPath/NoAuth/css/print.css" type="text/css" media="print" /> +END -% if ( $RSSAutoDiscovery ) { - <link rel="alternate" href="<%$RSSAutoDiscovery%>" type="application/rss+xml" title="RSS RT Search" /> -% } +for (keys %{$LinkRel || {}}) { + $head .= qq(<link rel="$_" href="$WebPath) . $LinkRel->{$_} . '" />'; +} -% if ($JavaScript) { -<& HeaderJavascript, focus => $Focus, onload => $onload &> -% } +if ( $RSSAutoDiscovery ) { + $head .= qq(<link rel="alternate" href="$RSSAutoDiscovery" type="application/rss+xml" title="RSS RT Search" />); +} -% my $stylesheet_plugin = "/NoAuth/css/". RT->Config->Get( 'WebDefaultStylesheet', $session{'CurrentUser'} )."/InHeader"; -% if ($m->comp_exists($stylesheet_plugin) ) { -<& $stylesheet_plugin &> -% } -% $m->callback( %ARGS, CallbackName => 'Head' ); +if ($JavaScript) { + $head .= $m->scomp('HeaderJavascript', focus => $Focus, onload => $onload); +} -</head> - <body<% $id && qq[ id="comp-$id"] |n %>> +my $stylesheet_plugin = "/NoAuth/css/$WebDefaultStylesheet/InHeader"; +if ($m->comp_exists($stylesheet_plugin) ) { + $head .= $m->scomp($stylesheet_plugin); +} -% if ($ShowBar) { -<& /Elements/Logo, %ARGS &> +# $m->callback( %ARGS, CallbackName => 'Head' ); +$head .= $m->scomp( '/Elements/Callback', _CallbackName => 'Head', %ARGS ); -<div id="quickbar"> - <& /Elements/PersonalQuickbar, %ARGS &> -% } +my $etc = ''; +$etc .= qq[ id="comp-$id"] if $id; -<%INIT> -$r->headers_out->{'Pragma'} = 'no-cache'; -$r->headers_out->{'Cache-control'} = 'no-cache'; - -my $id = $m->request_comp->path; -$id =~ s|^/||g; -$id =~ s|/|-|g; -$id =~ s|\.html$||g; -$id =~ s|index$||g - if $id ne 'index'; -$id =~ s|-$||g; </%INIT> <%ARGS> diff --git a/rt/share/html/Elements/HeaderJavascript b/rt/share/html/Elements/HeaderJavascript index 6ee88a13b..c4eb17504 100644 --- a/rt/share/html/Elements/HeaderJavascript +++ b/rt/share/html/Elements/HeaderJavascript @@ -111,7 +111,7 @@ $onload => undef typeField.setAttribute('value', 'text/html'); textArea.parentNode.appendChild(typeField); - var oFCKeditor = new FCKeditor( textArea.name, '100%', <% RT->Config->Get('MessageBoxRichTextHeight') %> ); + var oFCKeditor = new FCKeditor( textArea.name, '100%', <% RT->Config->Get('MessageBoxRichTextHeight', $session{CurrentUser} ) %> ); oFCKeditor.BasePath = "<%RT->Config->Get('WebPath')%>/NoAuth/RichText/"; oFCKeditor.ReplaceTextarea(); } diff --git a/rt/share/html/Elements/Login b/rt/share/html/Elements/Login index 8dfbe51d1..e768b0e7a 100755 --- a/rt/share/html/Elements/Login +++ b/rt/share/html/Elements/Login @@ -64,6 +64,21 @@ my $form_action = defined $goto ? $goto : defined $req_uri ? $req_uri : RT->Config->Get('WebPath') ; + +# sanitize $form_action +my $uri = URI->new($form_action); + +# You get undef scheme with a relative uri like "/Search/Build.html" +unless (!defined($uri->scheme) || $uri->scheme eq 'http' || $uri->scheme eq 'https') { + $form_action = RT->Config->Get('WebPath'); +} + +# Make sure we're logging in to the same domain +# You can get an undef authority with a relative uri like "index.html" +my $uri_base_url = URI->new(RT->Config->Get('WebBaseURL')); +unless (!defined($uri->authority) || $uri->authority eq $uri_base_url->authority) { + $form_action = RT->Config->Get('WebPath'); +} </%INIT> % $m->callback( %ARGS, CallbackName => 'Header' ); diff --git a/rt/share/html/Elements/Logo b/rt/share/html/Elements/Logo index 359738b5e..e6cb1ad4b 100644 --- a/rt/share/html/Elements/Logo +++ b/rt/share/html/Elements/Logo @@ -46,10 +46,11 @@ %# %# END BPS TAGGED BLOCK }}} <div id="logo"> -<a href="http://bestpractical.com"><img +<a href="<%$ARGS{'LogoLinkURL'}||RT->Config->Get('LogoLinkURL')%>"><img src="<%$ARGS{'LogoURL'}||RT->Config->Get('LogoURL')%>" - alt="<% loc("Best Practical Solutions, LLC corporate logo") %>" - width="177" height="33" /></a> + alt="<%loc($ARGS{'LogoAltText'}||RT->Config->Get('LogoAltText'))%>" + width="<%$ARGS{'LogoImageWidth'}||RT->Config->Get('LogoImageWidth')%>" + height="<%$ARGS{'LogoImageHeight'}||RT->Config->Get('LogoImageHeight')%>" /></a> % if ( $ShowName ) { <span class="rtname"><% $Name || loc("RT for [_1]", RT->Config->Get('rtname')) %></span> % } diff --git a/rt/share/html/Elements/MessageBox b/rt/share/html/Elements/MessageBox index 4985b23e3..854528c23 100755 --- a/rt/share/html/Elements/MessageBox +++ b/rt/share/html/Elements/MessageBox @@ -46,7 +46,7 @@ %# %# END BPS TAGGED BLOCK }}} <textarea class="messagebox" cols="<% $Width %>" rows="<% $Height %>" <% $wrap_type |n %> name="<% $Name %>" id="<% $Name %>">\ -% $m->callback( %ARGS ); +% $m->callback( %ARGS, SignatureRef => \$signature ); <% $Default || '' %><% $message %><% $signature %></textarea> % $m->callback( %ARGS, CallbackName => 'AfterTextArea' ); <%INIT> diff --git a/rt/share/html/Elements/MyCalendar b/rt/share/html/Elements/MyCalendar new file mode 100644 index 000000000..a54ab39d6 --- /dev/null +++ b/rt/share/html/Elements/MyCalendar @@ -0,0 +1,78 @@ +<&|/Widgets/TitleBox, + title => loc("Calendar"), + title_href => "Search/Calendar.html" &> + +<table class="rtxcalendar"> +<thead> +<tr> +% my $date = $begin->clone; +% while ( $date <= $end ) { +<th width="14%"><%$rtdate->GetWeekday($date->day_of_week % 7)%></th> +% $date = $set->next($date); +% } +</tr> +</thead> +<tbody> +<tr> +% $date = $begin->clone; +% while ($date <= $end) { +<td> +<p class="date"><%$date->day%></p> +% for my $t (@{ $Tickets{$date->strftime("%F")} }) { +<& /Elements/CalendarEvent, Object => $t, Date => $date, DateTypes => \%DateTypes &> +% } +</td> +% $date = $set->next($date); +% } +</tr> +</tbody> +</table> + + </&> + +<%INIT> + +use RTx::Calendar; + +my $title = loc("Calendar"); + +my $rtdate = RT::Date->new($session{'CurrentUser'}); + +my @DateTypes = qw/Created Starts Started Due LastUpdated Resolved/; + +my $today = DateTime->today; + +# this line is used to debug MyCalendar +# $today = DateTime->new(year => 2007, month => 4, day => 11); + +my $begin = $today->clone->subtract( days => 3); +my $end = $today->clone->add( days => 3); + +# use this to loop over days until $end +my $set = DateTime::Set->from_recurrence( + next => sub { $_[0]->truncate( to => 'day' )->add( days => 1 ) } +); + +my $Query = "( Status = 'new' OR Status = 'open' OR Status = 'stalled') + AND ( Owner = '" . $session{CurrentUser}->Id ."' OR Owner = 'Nobody' ) + AND ( Type = 'reminder' OR 'Type' = 'ticket' )"; +my $Format = "__Starts__ __Due__"; + +if ( my $Search = RTx::Calendar::SearchDefaultCalendar($session{CurrentUser}) ) { + $Format = $Search->SubValue('Format'); + $Query = $Search->SubValue('Query'); +} + +# we search all date types in Format string +my @Dates = grep { $Format =~ m/__${_}(Relative)?__/ } @DateTypes; + +# used to display or not a date in Element/CalendarEvent +my %DateTypes = map { $_ => 1 } @Dates; + +$Query .= RTx::Calendar::DatesClauses(\@Dates, $begin->strftime("%F"), $end->strftime("%F")); + +# print STDERR $Query, "\n"; + +my %Tickets = RTx::Calendar::FindTickets($session{'CurrentUser'}, $Query, \@Dates); + +</%INIT> diff --git a/rt/share/html/Elements/MyReminders b/rt/share/html/Elements/MyReminders index 25fdf5d48..53e3f99c7 100755 --- a/rt/share/html/Elements/MyReminders +++ b/rt/share/html/Elements/MyReminders @@ -47,6 +47,7 @@ %# END BPS TAGGED BLOCK }}} %# DEPRECATED <&|/Widgets/TitleBox, + class => 'reminders', title => loc("Reminders") &> <table width="100%"> % my $i =0; diff --git a/rt/share/html/Elements/PageLayout b/rt/share/html/Elements/PageLayout index 981e58a3c..f30d815a5 100755 --- a/rt/share/html/Elements/PageLayout +++ b/rt/share/html/Elements/PageLayout @@ -45,23 +45,27 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} + +<% include('/elements/init_calendar.html') |n %> + +% if (0) { ## new ticket via customer, and we already have a ticket search box <div id="topactions"> % foreach my $action (reverse sort keys %{$topactions}) { <span class="topaction" id="topaction-<%$action%>"><% $topactions->{"$action"}->{'html'} |n %></span> % } </div> +% } -%# End of div#quickbar from /Elements/Header -</div> - +% if (0) { ##FREESIDE MENUS INSTEAD## if ( $show_menu ) { % if ( $show_menu ) { <div id="nav"> <& /Elements/Menu, toptabs => $toptabs, current_toptab => $current_toptab &> </div> % } +% } <div id="header"> -<h1><% $title %></h1> +%#already shown <h1><% $title %></h1> <div id="page-navigation"> % my $sep = 0; % my $postsep = 0; diff --git a/rt/share/html/Elements/RT__CustomField/ColumnMap b/rt/share/html/Elements/RT__CustomField/ColumnMap new file mode 100644 index 000000000..6d8d76a4c --- /dev/null +++ b/rt/share/html/Elements/RT__CustomField/ColumnMap @@ -0,0 +1,178 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC +%# <jesse@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 }}} +<%ARGS> +$Name => undef +$Attr => undef +</%ARGS> +<%ONCE> +my $COLUMN_MAP = { + id => { + title => '#', # loc + attribute => 'id', + align => 'right', + value => sub { return $_[0]->id }, + }, + Disabled => { + title => \' ', + attribute => 'Disabled', + value => sub { return $_[0]->Disabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') }, + }, + + map( + { my $c = $_; $c => { + title => $c, attribute => $c, + value => sub { return $_[0]->$c() }, + } } + qw(Name Description Type LookupType Pattern) + ), + map( + { my $c = $_; my $short = $c; $short =~ s/^Friendly//; + $c => { + title => $short, attribute => $short, + value => sub { return $_[0]->$c() }, + } } + qw(FriendlyLookupType FriendlyType FriendlyPattern) + ), + MaxValues => { + title => 'MaxValues', # loc + attribute => 'MaxValues', + value => sub { + my $v = $_[0]->MaxValues; + return !$v ? $_[0]->loc('unlimited') : $v == 0 ? $_[0]->loc('one') : $v; + }, + }, + AppliedTo => { + title => 'Applied', # loc + value => sub { + if ( $_[0]->IsApplied ) { + return $_[0]->loc('Global'); + } + + my $collection = $_[0]->AppliedTo; + return '' unless $collection; + + $collection->RowsPerPage(10); + + my $found = 0; + my $res = ''; + while ( my $record = $collection->Next ) { + $res .= ', ' if $res; + + my $id = ''; + $id = $record->Name if $record->can('Name'); + $id ||= "#". $record->id; + $res .= $id; + + $found++; + } + $res .= ', ...' if $found >= 10; + return $res; + }, + + }, + RemoveCheckBox => { + title => sub { + my $name = 'RemoveCustomField'; + my $checked = $m->request_args->{ $name .'All' }? 'checked="checked"': ''; + + return \qq{<input type="checkbox" name="${name}All" value="1" $checked + onclick="setCheckbox(this.form, '$name', this.checked)" />}; + }, + value => sub { + my $id = $_[0]->id; + return '' if $_[0]->IsApplied; + + my $name = 'RemoveCustomField'; + my $arg = $m->request_args->{ $name }; + + my $checked = ''; + if ( $arg && ref $arg ) { + $checked = 'checked="checked"' if grep $_ == $id, @$arg; + } + elsif ( $arg ) { + $checked = 'checked="checked"' if $arg == $id; + } + return \qq{<input type="checkbox" name="$name" value="$id" $checked />} + }, + }, + MoveCF => { + title => 'Move', + value => sub { + my $id = $_[0]->id; + + my $context = $_[2] || 0; + return '' unless $_[0]->IsApplied( $context ); + + my $name = 'MoveCustomField'; + my $args = $m->caller_args( 1 ); + my @pass = ref $args->{'PassArguments'} + ? @{$args->{'PassArguments'}} + : ($args->{'PassArguments'}); + my %pass = map { $_ => $args->{$_} } grep exists $args->{$_}, @pass; + + my $uri = RT->Config->Get('WebPath') . $m->request_path; + + my @res = ( + \'<a href="', + $uri .'?'. $m->comp("/Elements/QueryString", %pass, MoveCustomFieldUp => $id ), + \'">', loc('[Up]'), \'</a>', + \' <a href="', + $uri .'?'. $m->comp("/Elements/QueryString", %pass, MoveCustomFieldDown => $id ), + \'">', loc('[Down]'), \'</a>' + ); + + return @res; + }, + }, +}; + +</%ONCE> +<%INIT> +$m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'ColumnMap', CallbackOnce => 1 ); +return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr ); +</%INIT> diff --git a/rt/share/html/Elements/RT__Queue/ColumnMap b/rt/share/html/Elements/RT__Queue/ColumnMap index 5c56004d1..f44ab32c3 100644 --- a/rt/share/html/Elements/RT__Queue/ColumnMap +++ b/rt/share/html/Elements/RT__Queue/ColumnMap @@ -70,43 +70,33 @@ my $COLUMN_MAP = { title => 'Address', # loc value => sub { return ($_[0]->CorrespondAddress||'-') .'/'. ($_[0]->CommentAddress||'-') }, }, - Name => { - title => 'Name', # loc - attribute => 'Name', - value => sub { return $_[0]->Name() }, - }, - Description => { - title => 'Description', # loc - attribute => 'Description', - value => sub { return $_[0]->Description() }, - }, - CorrespondAddress => { - title => 'CorrespondAddress', # loc - attribute => 'CorrespondAddress', - value => sub { return $_[0]->CorrespondAddress() }, - }, - CommentAddress => { - title => 'CommentAddress', # loc - attribute => 'CommentAddress', - value => sub { return $_[0]->CommentAddress() }, - }, - InitialPriority => { - title => 'InitialPriority', # loc - attribute => 'InitialPriority', - value => sub { return $_[0]->InitialPriority() }, + + # SubjectTag is special as we can not sort + SubjectTag => { + title => 'SubjectTag', # loc + value => sub { return $_[0]->SubjectTag }, }, - FinalPriority => { - title => 'FinalPriority', # loc - attribute => 'FinalPriority', - value => sub { return $_[0]->FinalPriority() }, + Sign => { + title => 'Sign', # loc + value => sub { return $_[0]->Sign? $_[0]->loc('yes') : $_[0]->loc('no') }, }, - DefaultDueIn => { - title => 'DefaultDueIn', # loc - attribute => 'DefaultDueIn', - value => sub { return $_[0]->DefaultDueIn() }, + Encrypt => { + title => 'Encrypt', # loc + value => sub { return $_[0]->Encrypt? $_[0]->loc('yes') : $_[0]->loc('no') }, }, }; +foreach my $field (qw( + Name Description CorrespondAddress CommentAddress + InitialPriority FinalPriority DefaultDueIn +)) { + $COLUMN_MAP->{$field} = { + title => $field, + attribute => $field, + value => sub { return $_[0]->$field() }, + }, +} + </%ONCE> <%INIT> $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'ColumnMap', CallbackOnce => 1 ); diff --git a/rt/share/html/Elements/RT__Scrip/ColumnMap b/rt/share/html/Elements/RT__Scrip/ColumnMap index 88b4c4bea..3e1d4074f 100644 --- a/rt/share/html/Elements/RT__Scrip/ColumnMap +++ b/rt/share/html/Elements/RT__Scrip/ColumnMap @@ -64,6 +64,10 @@ my $COLUMN_MAP = { return $_[0]->loc('Global'); }, }, + QueueId => { + title => 'Queue', # loc + value => sub { $_[0]->Queue }, + }, Condition => { title => 'Condition', # loc value => sub { return $_[0]->loc( $_[0]->ScripConditionObj->Name ) }, diff --git a/rt/share/html/Elements/RT__Template/ColumnMap b/rt/share/html/Elements/RT__Template/ColumnMap index 851cc9dec..e7c149575 100644 --- a/rt/share/html/Elements/RT__Template/ColumnMap +++ b/rt/share/html/Elements/RT__Template/ColumnMap @@ -67,6 +67,17 @@ my $COLUMN_MAP = { attribute => 'Description', value => sub { return $_[0]->Description() }, }, + Queue => { + title => 'Queue', # loc + value => sub { + return $_[0]->QueueObj->Name if $_[0]->Queue; + return $_[0]->loc('Global'); + }, + }, + QueueId => { + title => 'Queue', # loc + value => sub { $_[0]->Queue }, + }, }; </%ONCE> diff --git a/rt/share/html/Elements/RT__Ticket/ColumnMap b/rt/share/html/Elements/RT__Ticket/ColumnMap index 7df471009..e848939e1 100644 --- a/rt/share/html/Elements/RT__Ticket/ColumnMap +++ b/rt/share/html/Elements/RT__Ticket/ColumnMap @@ -303,26 +303,6 @@ $COLUMN_MAP = { value => sub { return \('<input type="checkbox" class="checkbox" name="UpdateTicket'.$_[0]->id.'" value="1" checked="checked" />') } }, - CustomField => { - attribute => sub { return shift @_ }, - title => sub { return pop @_ }, - value => sub { - # Display custom field contents, separated by newlines. - # For Image custom fields we also show a thumbnail here. - - my $values = $_[0]->CustomFieldValues( $_[-1] ); - my @values = map { - ( - ($_->CustomFieldObj->Type eq 'Image') - ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ )) - : $_->Content - ), - \'<br />', - } @{ $values->ItemsArrayRef }; - pop @values; # Remove that last <br /> - return @values; - }, - }, Bookmark => { title => ' ', value => sub { @@ -333,9 +313,26 @@ $COLUMN_MAP = { return \$bookmark; }, }, -}; -$COLUMN_MAP->{'CF'} = $COLUMN_MAP->{'CustomField'}; + Customer => { + title => 'Customer', #loc + attribute => 'Customer', #title/attribute/name... what does it all mean? + value => sub { + my $Ticket = shift; + my @Customers = @{ $Ticket->Customers->ItemsArrayRef }; + my @CustResolvers = map $_->TargetURI->Resolver, @Customers; + my @return = (); + for ( 0 .. $#CustResolvers ) { + my $c = @CustResolvers[$_]; + push @return, \'<A HREF="', $c->HREF, \'">', $c->AsString, \'</A>'; + push @return, \'<BR>' if scalar(@CustResolvers) > 1 + && $_ != $#CustResolvers; + } + @return; + }, + }, + +}; # if no GPG support, then KeyOwnerName and KeyRequestors fall back to the regular # versions diff --git a/rt/share/html/Elements/SelectDate b/rt/share/html/Elements/SelectDate index 32a173db4..46092ce23 100755 --- a/rt/share/html/Elements/SelectDate +++ b/rt/share/html/Elements/SelectDate @@ -45,10 +45,21 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<script type="text/javascript"><!-- - onLoadHook('createCalendarLink("<% $Name %>");'); ---></script> +%# in PageLayout instead, once <% include('/elements/init_calendar.html') |n %> <input type="text" id="<% $Name %>" name="<% $Name %>" value="<% $Value %>" size="<% $Size %>" /> +<IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $Name %>_date_button" STYLE="cursor: pointer" TITLE="Select date"> +<script type="text/javascript"> +Calendar.setup({ + inputField: <% $Name |n,js_string %>, +% if ( defined($ShowTime) && $ShowTime ) { + ifFormat: "%Y-%m-%d %H:%M", + showsTime: true, +% } else { + ifFormat: "%Y-%m-%d", +% } + button: <% $Name.'_date_button' |n,js_string %>, +}); +</script> <%init> unless ((defined $Default) or ($current <= 0)) { diff --git a/rt/share/html/Elements/SelectQueue b/rt/share/html/Elements/SelectQueue index 20a5b7d9d..c78afe9ce 100755 --- a/rt/share/html/Elements/SelectQueue +++ b/rt/share/html/Elements/SelectQueue @@ -51,7 +51,7 @@ <input name="<%$Name%>" size="25" value="<%$d->Name%>" class="<%$Class%>" /> % } % else { -<select name="<%$Name%>" <% ($OnChange) ? 'onchange="'.$OnChange.'"' : '' |n %> class="<%$Class%>"> +<select name="<%$Name%>" <% ($Multiple) ? 'multiple="multiple"' : '' %> <% ($OnChange) ? 'onchange="'.$OnChange.'"' : '' |n %> class="<%$Class%>"> % if ($ShowNullOption) { <option value="">-</option> % } @@ -82,6 +82,7 @@ $NamedValues => 0 $Default => 0 $Lite => 0 $OnChange => undef +$Multiple => 0 $Class => 'select-queue' </%args> <%init> diff --git a/rt/share/html/Elements/ShowCustomFieldDate b/rt/share/html/Elements/ShowCustomFieldDate new file mode 100644 index 000000000..4e8ad676c --- /dev/null +++ b/rt/share/html/Elements/ShowCustomFieldDate @@ -0,0 +1,57 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2008 Best Practical Solutions, LLC +%# <jesse@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 }}} +<%INIT> + my $content = $Object->Content; + my $DateObj = new RT::Date ( $session{'CurrentUser'} ); + $DateObj->Set( Format => 'ISO', Value => $content ); + $content = $DateObj->AsString; +</%INIT> +<%$content|n%> +<%ARGS> +$Object +</%ARGS> diff --git a/rt/share/html/Elements/ShowCustomFields b/rt/share/html/Elements/ShowCustomFields index ddb8b72e3..b60c49ae8 100644 --- a/rt/share/html/Elements/ShowCustomFields +++ b/rt/share/html/Elements/ShowCustomFields @@ -45,6 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +% $m->callback( CallbackName => 'BeforeCustomFields' ); % if ($Table) { <table> % } @@ -73,6 +74,7 @@ % if ($Table) { </table> % } +% $m->callback( CallbackName => 'AfterCustomFields', Object => $Object ); <%INIT> $m->callback( CallbackName => 'MassageCustomFields', @@ -82,9 +84,10 @@ $m->callback( my $print_value = sub { my ($cf, $value) = @_; - my $linked = $cf->LinkValueTo; - if ( $linked ) { - $m->out('<a href="'. $value->LinkValueTo .'" target="_new">'); + my $linked = $value->LinkValueTo; + if ( defined $linked && length $linked ) { + my $linked = $m->interp->apply_escapes( $linked, 'h' ); + $m->out('<a href="'. $linked .'" target="_new">'); } my $comp = "ShowCustomField". $cf->Type; $m->callback( @@ -98,7 +101,7 @@ my $print_value = sub { } else { $m->out( $m->interp->apply_escapes( $value->Content, 'h' ) ); } - $m->out('</a>') if $linked; + $m->out('</a>') if defined $linked && length $linked; # This section automatically populates a div with the "IncludeContentForValue" for this custom # field if it's been defined diff --git a/rt/share/html/Elements/ShowLink_Checklist b/rt/share/html/Elements/ShowLink_Checklist new file mode 100644 index 000000000..945305fb6 --- /dev/null +++ b/rt/share/html/Elements/ShowLink_Checklist @@ -0,0 +1,36 @@ +<a href="<%$URI->Resolver->HREF%>"> +% if ($URI->IsLocal) { +% my $member = $URI->Object; +% if (UNIVERSAL::isa($member, "RT::Ticket")) { +% my $inactive = 0; #$member->QueueObj->IsInactiveStatus($member->Status); + +<span class="<% $inactive ? 'ticket-inactive' : '' %>"> +<IMG SRC="<%$fsurl%>images/<% $status2image{$member->Status} %>.png" BORDER=0> +<%$member->Id%>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> +%# [<% loc($member->Status) %>] +</span> + +% } elsif ( UNIVERSAL::can($member, 'Name')) { +<%$URI->Resolver->AsString%>: <%$member->Name%> +% } else { +<%$URI->Resolver->AsString%> +% } +% } else { +<%$URI->Resolver->AsString%> +% } +</a> +<%ARGS> +$URI => undef +</%ARGS> +<%once> + +my %status2image = ( + 'new' => 'square_add', #'bullet_add', + 'open' => 'square', #'bullet_black', + 'stalled' => 'error', + 'resolved' => 'tick', + 'rejected' => 'cross', + #'deleted' => 'delete', +); + +</%once> diff --git a/rt/share/html/Elements/ShowLinks b/rt/share/html/Elements/ShowLinks index 569bad39c..e3b3ef509 100755 --- a/rt/share/html/Elements/ShowLinks +++ b/rt/share/html/Elements/ShowLinks @@ -47,7 +47,7 @@ %# END BPS TAGGED BLOCK }}} <table> <tr> - <td class="labeltop"><&|/l&>Depends on</&>: (<a href="<%$clone->{'DependsOn-new'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>: <span class="create">(<a href="<%$clone->{'DependsOn-new'}%>"><% loc('Create') %></a>)</span></td> <td class="value"> <%PERL> @@ -77,7 +77,7 @@ for my $link ( @{ $Ticket->DependsOn->ItemsArrayRef } ) { </td> </tr> <tr> - <td class="labeltop"><&|/l&>Depended on by</&>: (<a href="<%$clone->{'new-DependsOn'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>: <span class="create">(<a href="<%$clone->{'new-DependsOn'}%>"><% loc('Create') %></a>)</span></td> <td class="value"> <ul> % while (my $Link = $Ticket->DependedOnBy->Next) { @@ -87,15 +87,15 @@ for my $link ( @{ $Ticket->DependsOn->ItemsArrayRef } ) { </td> </tr> <tr> - <td class="labeltop"><&|/l&>Parents</&>: (<a href="<%$clone->{'MemberOf-new'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>: <span class="create">(<a href="<%$clone->{'MemberOf-new'}%>"><% loc('Create') %></a>)</span></td> <td class="value"><& /Ticket/Elements/ShowParents, Ticket => $Ticket &></td> </tr> <tr> - <td class="labeltop"><&|/l&>Children</&>: (<a href="<%$clone->{'new-MemberOf'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>: <span class="create">(<a href="<%$clone->{'new-MemberOf'}%>"><% loc('Create') %></a>)</span></td> <td class="value"><& /Ticket/Elements/ShowMembers, Ticket => $Ticket &></td> </tr> <tr> - <td class="labeltop"><&|/l&>Refers to</&>: (<a href="<%$clone->{'RefersTo-new'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>: <span class="create">(<a href="<%$clone->{'RefersTo-new'}%>"><% loc('Create') %></a>)</span></td> <td class="value"> <ul> % while (my $Link = $Ticket->RefersTo->Next) { @@ -105,7 +105,7 @@ for my $link ( @{ $Ticket->DependsOn->ItemsArrayRef } ) { </td> </tr> <tr> - <td class="labeltop"><&|/l&>Referred to by</&>: (<a href="<%$clone->{'new-RefersTo'}%>"><% loc('Create') %></a>)</td> + <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>: <span class="create">(<a href="<%$clone->{'new-RefersTo'}%>"><% loc('Create') %></a>)</span></td> <td class="value"> <ul> % while (my $Link = $Ticket->ReferredToBy->Next) { @@ -124,14 +124,15 @@ for my $link ( @{ $Ticket->DependsOn->ItemsArrayRef } ) { <%INIT> +my $id = $Ticket->id; + my $clone = {}; my $path = RT->Config->Get('WebPath') . '/Ticket/Create.html?Queue=' . $Ticket->Queue . '&CloneTicket=' - . $Ticket->id; - + . $id; for my $relation ( qw(RefersTo ReferredToBy)) { @@ -142,15 +143,14 @@ for my $relation ( $clone->{$field} = $path . "&$field=" . join( '%20', - ( map { $_->$other() } @{ $Ticket->$relation->ItemsArrayRef } ), - $Ticket->id ); + ( map { $_->$other() } @{ $Ticket->$relation->ItemsArrayRef } ), $id ); } for my $relation ( qw(MemberOf Members DependsOn DependedOnBy)) { my $mode = $RT::Ticket::LINKTYPEMAP{$relation}->{Mode}; my $type = $RT::Ticket::LINKTYPEMAP{$relation}->{Type}; my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new'; - $clone->{$field} = $path . "&$field=". $Ticket->id ; + $clone->{$field} = $path . "&$field=$id"; } </%INIT> diff --git a/rt/share/html/Elements/ShowRelationLabel b/rt/share/html/Elements/ShowRelationLabel new file mode 100644 index 000000000..3c1ed1514 --- /dev/null +++ b/rt/share/html/Elements/ShowRelationLabel @@ -0,0 +1,62 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC +%# <jesse@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 }}} +<a href="<%$SearchURL |n %>"><%$Label%></a> +<%INIT> +my $typemap = RT::Ticket->LINKTYPEMAP->{$Relation}; +my $search_mode = $typemap->{Mode}; +my $search_type = $typemap->{Type}; +my $search_relation = RT::Ticket->LINKDIRMAP->{$search_type}{$search_mode}; + +my $Query = $search_relation . ' = ' . $id; +my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query); +</%INIT> +<%ARGS> +$id +$Label +$Relation +</%ARGS> diff --git a/rt/share/html/Elements/ShowUser b/rt/share/html/Elements/ShowUser index 2fbdcbc3e..01de7256a 100644 --- a/rt/share/html/Elements/ShowUser +++ b/rt/share/html/Elements/ShowUser @@ -49,18 +49,20 @@ <%INIT> # $User is an RT::User object # $Address is Email::Address object -if ( !$User && $Address ) { - $User = RT::User->new( $session{'CurrentUser'} ); - $User->LoadByEmail( $Address->address ); - unless ( $User->Id ) { - $m->comp( '/Elements/ShowUserVerbose', Address => $Address ); - return; - } + +my $comp = '/Elements/ShowUser'. ucfirst lc $style; +unless ( $m->comp_exists( $comp ) ) { + $RT::Logger->error( + 'Either system config or user #' + . $session{'CurrentUser'}->id + . ' picked UsernameFormat '. $style + . ', but '. $comp . "doesn't exist" + ); + return $m->comp('/Elements/ShowUserConcise', + User => $User, Address => $Address, + ); } -if ( $style eq 'concise' ) { - $m->comp( '/Elements/ShowUserConcise', User => $User ); -} -else { $m->comp( '/Elements/ShowUserVerbose', User => $User ); } +return $m->comp( $comp, User => $User, Address => $Address ); </%INIT> <%ARGS> $User => undef diff --git a/rt/share/html/Elements/ShowUserConcise b/rt/share/html/Elements/ShowUserConcise index 3cdba10dd..c4cccca75 100644 --- a/rt/share/html/Elements/ShowUserConcise +++ b/rt/share/html/Elements/ShowUserConcise @@ -46,7 +46,19 @@ %# %# END BPS TAGGED BLOCK }}} %# Released under the terms of version 2 of the GNU Public License -<% $User->RealName || $User->Name %>\ +<% $Address || $User->RealName || $User->Name %>\ <%ARGS> -$User +$User => undef +$Address => undef </%ARGS> +<%INIT> +if ( !$User && $Address ) { + $User = RT::User->new( $session{'CurrentUser'} ); + $User->LoadByEmail( $Address->address ); + if ( $User->Id ) { + $Address = ''; + } else { + $Address = $Address->address; + } +} +</%INIT> diff --git a/rt/share/html/Elements/ShowUserVerbose b/rt/share/html/Elements/ShowUserVerbose index 82d65b0b3..9b61ea74a 100644 --- a/rt/share/html/Elements/ShowUserVerbose +++ b/rt/share/html/Elements/ShowUserVerbose @@ -46,7 +46,11 @@ %# %# END BPS TAGGED BLOCK }}} %# Released under the terms of version 2 of the GNU Public License -<%$Address->format%>\ +% if ( $Address->phrase || $Address->comment ) { +<% sprintf q{%s <%s> %s}, map $Address->$_, qw( phrase address comment ) %> +% } else { +<% $Address->address %> +% } <%INIT> my ($phrase, $address, $comment); |