[Rt-commit] rt branch, 4.6/custom-date-ranges-ui, repushed

? sunnavy sunnavy at bestpractical.com
Mon Jun 24 18:41:17 EDT 2019


The branch 4.6/custom-date-ranges-ui was deleted and repushed:
       was 48d29d677c6931ec25faf893087b69b7634be1ea
       now e4501f5cef801d305e090549eb5f5cc8472c70b1

1: a3424c04d = 1: a3424c04d Abstract RT::Record::CustomDateRanges to cover both config and attribute
2: 6d5446e80 ! 2: d79f6735a Refactor custom date range code to make it easier to expand
    @@ -71,8 +71,8 @@
     -    my ($end, $op, $start) = @matches;
     -
     -    return ($end, $op, $start, $format, $business_time);
    -+    my %parsed = ( from => $matches[1], to => $matches[0], ref $spec ? %$spec : () );
    -+    return %parsed;
    ++    my %date_range_spec= ( from => $matches[1], to => $matches[0], ref $spec ? %$spec : () );
    ++    return %date_range_spec;
      }
      
      =head2 CustomDateRange name, spec
    @@ -81,16 +81,16 @@
          my $spec = shift;
      
     -    my ($end, $op, $start, $format, $business_time) = $self->_ParseCustomDateRangeSpec($name, $spec);
    -+    my %parsed = $self->_ParseCustomDateRangeSpec($name, $spec);
    ++    my %date_range_spec = $self->_ParseCustomDateRangeSpec($name, $spec);
      
          # parse failed; render no value
     -    return unless $start && $end;
    -+    return unless $parsed{from} && $parsed{to};
    ++    return unless $date_range_spec{from} && $date_range_spec{to};
      
     -    my $end_dt = $self->_DateForCustomDateRangeField($end, $name);
     -    my $start_dt = $self->_DateForCustomDateRangeField($start, $name);
    -+    my $end_dt = $self->_DateForCustomDateRangeField($parsed{to}, $name);
    -+    my $start_dt = $self->_DateForCustomDateRangeField($parsed{from}, $name);
    ++    my $end_dt = $self->_DateForCustomDateRangeField($date_range_spec{to}, $name);
    ++    my $start_dt = $self->_DateForCustomDateRangeField($date_range_spec{from}, $name);
      
          # RT::Date instantiation failed; render no value
          return unless $start_dt && $start_dt->IsSet
    @@ -123,7 +123,7 @@
     -                $duration *= -1 if $start_dt->Unix > $end_dt->Unix;
     -            }
     -
    -+    if ( $parsed{business_time} && !$self->QueueObj->SLADisabled && $self->SLA ) {
    ++    if ( $date_range_spec{business_time} && !$self->QueueObj->SLADisabled && $self->SLA ) {
     +        my $config    = RT->Config->Get('ServiceAgreements');
     +        my $agreement = $config->{Levels}{ $self->SLA };
     +        my $timezone
    @@ -163,8 +163,8 @@
          # _ParseCustomDateRangeSpec guarantees $format is a coderef
     -    if ($format) {
     -        return $format->($duration, $end_dt, $start_dt, $self);
    -+    if ($parsed{format}) {
    -+        return $parsed{format}->($duration, $end_dt, $start_dt, $self);
    ++    if ($date_range_spec{format}) {
    ++        return $date_range_spec{format}->($duration, $end_dt, $start_dt, $self);
          }
          else {
              # "x days ago" is strongly suggestive of comparing with the current
3: 323a46cdc ! 3: a8ddc2512 Support fallback dates for custom date ranges
    @@ -20,6 +20,7 @@
              return;
          }
      
    +-    my %date_range_spec= ( from => $matches[1], to => $matches[0], ref $spec ? %$spec : () );
     +    if ( ref $spec ) {
     +        for my $type ( qw/from to/ ) {
     +            if ( $spec->{"${type}_fallback"} && $spec->{"${type}_fallback"} !~ /^$field_parser$/ ) {
    @@ -29,12 +30,13 @@
     +        }
     +    }
     +
    -     my %parsed = ( from => $matches[1], to => $matches[0], ref $spec ? %$spec : () );
    -     return %parsed;
    ++    my %date_range_spec = ( from => $matches[1], to => $matches[0], ref $spec ? %$spec : () );
    +     return %date_range_spec;
      }
    + 
     @@
    -     my $end_dt = $self->_DateForCustomDateRangeField($parsed{to}, $name);
    -     my $start_dt = $self->_DateForCustomDateRangeField($parsed{from}, $name);
    +     my $end_dt = $self->_DateForCustomDateRangeField($date_range_spec{to}, $name);
    +     my $start_dt = $self->_DateForCustomDateRangeField($date_range_spec{from}, $name);
      
     +    unless ( $start_dt && $start_dt->IsSet ) {
     +        if ( ref $spec && $parsed{from_fallback} ) {
4: 37117635c < -:  ------- Support autocomplete for custom date range fields
5: 436bbbb56 ! 4: c6ddf74f9 Web UI for custom date ranges
    @@ -14,6 +14,108 @@
              if ($has_query) {
                  $current_search_menu->child( results => title => loc('Show Results'), path => "/Search/Results.html$args" );
              }
    +
    +diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
    +--- a/lib/RT/Record.pm
    ++++ b/lib/RT/Record.pm
    +@@
    +     return %ranges;
    + }
    + 
    ++=head2 CustomDateRangeFields
    ++
    ++Return all of the fields custom date range could use for current class.
    ++
    ++=cut
    ++
    ++sub CustomDateRangeFields {
    ++    my $self = shift;
    ++    my $type = ref $self || $self;
    ++
    ++    my @fields = 'now';
    ++
    ++    for my $column ( keys %{ $_TABLE_ATTR->{ ref $self || $self } } ) {
    ++        my $entry = $_TABLE_ATTR->{ ref $self || $self }{$column};
    ++        next unless $entry->{read} && ( $entry->{type} // '' ) eq 'datetime';
    ++        push @fields, $column;
    ++    }
    ++
    ++    my $cfs = RT::CustomFields->new( ref $self ? $self->CurrentUser : RT->SystemUser );
    ++    $cfs->Limit( FIELD => 'Type', VALUE => [ 'Date', 'DateTime' ], OPERATOR => 'IN' );
    ++    while ( my $cf = $cfs->Next ) {
    ++        push @fields, 'CF.{' . $cf->Name . '}';
    ++    }
    ++    return sort { lc $a cmp lc $b } @fields;
    ++}
    ++
    + sub UID {
    +     my $self = shift;
    +     return undef unless defined $self->Id;
    +
    +diff --git a/share/html/Elements/SelectCustomDateRangeField b/share/html/Elements/SelectCustomDateRangeField
    +new file mode 100644
    +--- /dev/null
    ++++ b/share/html/Elements/SelectCustomDateRangeField
    +@@
    ++%# BEGIN BPS TAGGED BLOCK {{{
    ++%#
    ++%# COPYRIGHT:
    ++%#
    ++%# This software is Copyright (c) 1996-2019 Best Practical Solutions, LLC
    ++%#                                          <sales at bestpractical.com>
    ++%#
    ++%# (Except where explicitly superseded by other copyright notices)
    ++%#
    ++%#
    ++%# LICENSE:
    ++%#
    ++%# This work is made available to you under the terms of Version 2 of
    ++%# the GNU General Public License. A copy of that license should have
    ++%# been provided with this software, but in any event can be snarfed
    ++%# from www.gnu.org.
    ++%#
    ++%# This work is distributed in the hope that it will be useful, but
    ++%# WITHOUT ANY WARRANTY; without even the implied warranty of
    ++%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    ++%# General Public License for more details.
    ++%#
    ++%# You should have received a copy of the GNU General Public License
    ++%# along with this program; if not, write to the Free Software
    ++%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    ++%# 02110-1301 or visit their web page on the internet at
    ++%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
    ++%#
    ++%#
    ++%# CONTRIBUTION SUBMISSION POLICY:
    ++%#
    ++%# (The following paragraph is not intended to limit the rights granted
    ++%# to you to modify and distribute this software under the terms of
    ++%# the GNU General Public License and is only of importance to you if
    ++%# you choose to contribute your changes and enhancements to the
    ++%# community by submitting them to Best Practical Solutions, LLC.)
    ++%#
    ++%# By intentionally submitting any modifications, corrections or
    ++%# derivatives to this work, or any other work intended for use with
    ++%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
    ++%# you are the copyright holder for those contributions and you grant
    ++%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
    ++%# royalty-free, perpetual, license to use, copy, create derivative
    ++%# works based on those contributions, and sublicense and distribute
    ++%# those contributions and any derivatives thereof.
    ++%#
    ++%# END BPS TAGGED BLOCK }}}
    ++<select name="<% $Name %>" id="<% $Name %>" class="chosen custom-date-range-field">
    ++<option value="" >-</option>
    ++% for my $field ( $ObjectType->new( $session{CurrentUser} )->CustomDateRangeFields ) {
    ++<option <% $field eq ($Default//'') ? 'selected="selected"' : '' |n %> value="<% $field %>" ><% $field %></option>
    ++% }
    ++</select>
    ++
    ++<%ARGS>
    ++$Name => ''
    ++$Default => ''
    ++$ObjectType => 'RT::Ticket'
    ++</%ARGS>
     
     diff --git a/share/html/Search/CustomDateRanges.html b/share/html/Search/CustomDateRanges.html
     new file mode 100644
    @@ -89,12 +191,12 @@
     +    <tr class="<% $i % 2 ? 'oddline' : 'evenline' %>">
     +      <td class="collection-as-table"><% $name %></td>
     +%     my $spec = $config->{'RT::Ticket'}{$name};
    -+%     my %parsed = RT::Ticket->_ParseCustomDateRangeSpec($name, $spec);
    -+      <td class="collection-as-table"><% $parsed{from} %></td>
    -+      <td class="collection-as-table"><% $parsed{from_fallback} || '' %></td>
    -+      <td class="collection-as-table"><% $parsed{to} %></td>
    -+      <td class="collection-as-table"><% $parsed{to_fallback} || '' %></td>
    -+      <td class="collection-as-table"><% $parsed{business_time} ? loc('Yes') : loc('No') %></td>
    ++%     my %date_range_spec = RT::Ticket->_ParseCustomDateRangeSpec($name, $spec);
    ++      <td class="collection-as-table"><% $date_range_spec{from} %></td>
    ++      <td class="collection-as-table"><% $date_range_spec{from_fallback} || '' %></td>
    ++      <td class="collection-as-table"><% $date_range_spec{to} %></td>
    ++      <td class="collection-as-table"><% $date_range_spec{to_fallback} || '' %></td>
    ++      <td class="collection-as-table"><% $date_range_spec{business_time} ? loc('Yes') : loc('No') %></td>
     +    </tr>
     +% }
     +  </table>
    @@ -126,16 +228,15 @@
     +% $i++;
     +      <tr class="<% $i % 2 ? 'oddline' : 'evenline' %>">
     +        <td class="collection-as-table"><input type="text" name="<% $id %>-name" value="<% $name %>" /></td>
    -+%       my %parsed = RT::Ticket->_ParseCustomDateRangeSpec($name, $content->{'RT::Ticket'}{$name});
    -+        
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="<% $id %>-from" value="<% $parsed{from} %>" /></td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="<% $id %>-from_fallback" value="<% $parsed{from_fallback} || '' %>"</td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="<% $id %>-to" value="<% $parsed{to} %>" /></td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="<% $id %>-to_fallback" value="<% $parsed{to_fallback} || '' %>"</td>
    ++%       my %date_range_spec = RT::Ticket->_ParseCustomDateRangeSpec($name, $content->{'RT::Ticket'}{$name});
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => "$id-from", Default => $date_range_spec{from} &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => "$id-from_fallback", Default => $date_range_spec{from_fallback} &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => "$id-to", Default => $date_range_spec{to} &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => "$id-to_fallback", Default => $date_range_spec{to_fallback} &></td>
     +        <td class="collection-as-table">
     +          <select name="<% $id %>-business_time">
    -+            <option value="1" <% $parsed{business_time} ? 'selected="selected"' : '' |n%>><&|/l&>Yes</&></option>
    -+            <option value="0" <% $parsed{business_time} ? '': 'selected="selected"' |n%>><&|/l&>No</&></option>
    ++            <option value="1" <% $date_range_spec{business_time} ? 'selected="selected"' : '' |n%>><&|/l&>Yes</&></option>
    ++            <option value="0" <% $date_range_spec{business_time} ? '': 'selected="selected"' |n%>><&|/l&>No</&></option>
     +          </select>
     +        </td>
     +        <td class="collection-as-table"><input type="checkbox" name="<% $id %>-Delete" value="1" /></td>
    @@ -147,11 +248,11 @@
     +% for ( 1 .. 3 ) {
     +% $i++;
     +      <tr class="<% $i % 2 ? 'oddline' : 'evenline' %>">
    -+        <td class="collection-as-table"><input type="text" name="name" value="" /></td>        
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="from" value="" /></td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="from_fallback" value="" /></td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="to" value="" /></td>
    -+        <td class="collection-as-table"><input type="text" class="custom-date-range-field" name="to_fallback" value="" /></td>
    ++        <td class="collection-as-table"><input type="text" name="name" value="" /></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => 'from' &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => 'from_fallback' &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => 'to' &></td>
    ++        <td class="collection-as-table"><& /Elements/SelectCustomDateRangeField, Name => 'to_fallback' &></td>
     +        <td class="collection-as-table">
     +          <select name="business_time">
     +            <option value="1"><&|/l&>Yes</&></option>
    @@ -167,10 +268,8 @@
     +</form>
     +
     +<script type="text/javascript">
    -+jQuery( function() {
    -+    jQuery('.custom-date-range-field').autocomplete({
    -+        source: RT.Config.WebHomePath + "/Helpers/Autocomplete/CustomDateRanges?Class=RT::Ticket"
    -+    });
    ++jQuery(function() {
    ++    jQuery('select.chosen.custom-date-range-field').chosen({ width: '12em', no_results_text: ' ', search_contains: true });
     +});
     +</script>
     +
6: 00332ef56 = 5: 165001f27 Fix supported ticket fields for custom date ranges in the doc
7: 293cdc08f ! 6: 6c62b1f0c Try harder to calculate business time for custom date ranges
    @@ -12,23 +12,45 @@
     --- a/lib/RT/Record.pm
     +++ b/lib/RT/Record.pm
     @@
    +     my $start_dt = $self->_DateForCustomDateRangeField($date_range_spec{from}, $name);
    + 
    +     unless ( $start_dt && $start_dt->IsSet ) {
    +-        if ( ref $spec && $parsed{from_fallback} ) {
    +-            $start_dt = $self->_DateForCustomDateRangeField( $parsed{from_fallback}, $name );
    ++        if ( ref $spec && $date_range_spec{from_fallback} ) {
    ++            $start_dt = $self->_DateForCustomDateRangeField( $date_range_spec{from_fallback}, $name );
    +         }
    +     }
    + 
    +     unless ( $end_dt && $end_dt->IsSet ) {
    +-        if ( ref $spec && $parsed{to_fallback} ) {
    +-            $end_dt = $self->_DateForCustomDateRangeField( $parsed{to_fallback}, $name );
    ++        if ( ref $spec && $date_range_spec{to_fallback} ) {
    ++            $end_dt = $self->_DateForCustomDateRangeField( $date_range_spec{to_fallback}, $name );
    +         }
    +     }
    + 
    +@@
                     && $end_dt && $end_dt->IsSet;
      
          my $duration;
    --    if ( $parsed{business_time} && !$self->QueueObj->SLADisabled && $self->SLA ) {
    +-    if ( $date_range_spec{business_time} && !$self->QueueObj->SLADisabled && $self->SLA ) {
     -        my $config    = RT->Config->Get('ServiceAgreements');
     -        my $agreement = $config->{Levels}{ $self->SLA };
     -        my $timezone
     -          = $config->{QueueDefault}{ $self->QueueObj->Name }{Timezone}
     -          || $agreement->{Timezone}
     -          || RT->Config->Get('Timezone');
    -+    if ( $parsed{business_time} ) {
    ++    if ( $date_range_spec{business_time} ) {
     +        my $schedule;
     +        my $timezone;
     +
    ++        # Prefer the schedule/timezone specified in %ServiceAgreements for current object
     +        if ( $self->isa('RT::Ticket') && !$self->QueueObj->SLADisabled && $self->SLA ) {
     +            if ( my $config = RT->Config->Get('ServiceAgreements') ) {
     +                $timezone = $config->{QueueDefault}{ $self->QueueObj->Name }{Timezone};
    ++
    ++                # Each SLA could have its own schedule and timezone
     +                if ( my $agreement = $config->{Levels}{ $self->SLA } ) {
     +                    $schedule = $agreement->{BusinessHours};
     +                    $timezone ||= $agreement->{Timezone};
8: 48d29d677 ! 7: e4501f5ce Document more config items for custom date ranges
    @@ -44,7 +44,7 @@
     +=item from and to
     +
     +When value is not set, C<from/to> will be used to calculate instead.
    -+Technically, C<Resolved - Created"> is euqal to:
    ++Technically, C<Resolved - Created"> is equal to:
     +
     +    { from => 'Created', to => 'Resolved' }
     +
    @@ -63,8 +63,8 @@
     +
     +A boolean value to indicate if it's a business time or not.
     +
    -+When the schedule can't be decuted from corresponding object, the C<Default>
    -+one defined in C<%ServiceBusinessHours> will be used instead.
    ++When the schedule can't be deducted from corresponding object, the
    ++C<Default> one defined in C<%ServiceBusinessHours> will be used instead.
     +
     +=item format
     +



More information about the rt-commit mailing list