[Rt-commit] rt branch, 4.4/include-article-queue, created. rt-4.4.2-74-g7458fbe66

Craig Kaiser craig at bestpractical.com
Tue Feb 20 20:14:00 EST 2018


The branch, 4.4/include-article-queue has been created
        at  7458fbe667da002c2135f9a87e001078c449bfb4 (commit)

- Log -----------------------------------------------------------------
commit 7177ac5c81bda0da708407fc0615c73e47bc2ab6
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Tue Dec 12 11:50:37 2017 -0500

    Add test for 'Order by' dropdown content
    
    Test the presence of both core and custom field sortable ticket values
    in the 'Order by' dropdown in search builder.

diff --git a/t/web/query_builder.t b/t/web/query_builder.t
index dbe909939..2c11801a0 100644
--- a/t/web/query_builder.t
+++ b/t/web/query_builder.t
@@ -3,7 +3,7 @@ use warnings;
 use HTTP::Request::Common;
 use HTTP::Cookies;
 use LWP;
-use RT::Test tests => 70;
+use RT::Test tests => undef;
 
 my $cookie_jar = HTTP::Cookies->new;
 my ($baseurl, $agent) = RT::Test->started_ok;
@@ -219,6 +219,7 @@ diag "click advanced, enter 'C1 OR ( C2 AND C3 )', apply, aggregators should sta
         "no changes, no duplicate condition with badly encoded text"
     );
 
+   $cf->SetDisabled(1);
 }
 
 diag "input a condition, select (several conditions), click delete";
@@ -324,3 +325,75 @@ diag "make sure skipped order by field doesn't break search";
         url_regex => qr{/Ticket/Display\.html},
     ), "link to the ticket" );
 }
+
+diag "make sure the list of columns available in the 'Order by' dropdowns are complete";
+{
+    $agent->get_ok($url . 'Search/Build.html');
+
+    my @orderby = qw(
+        AdminCc.EmailAddress
+        Cc.EmailAddress
+        Created
+        Creator
+        Custom.Ownership
+        Due
+        FinalPriority
+        InitialPriority
+        LastUpdated
+        LastUpdatedBy
+        Owner
+        Priority
+        Queue
+        Requestor.EmailAddress
+        Resolved
+        SLA
+        Started
+        Starts
+        Status
+        Subject
+        TimeEstimated
+        TimeLeft
+        TimeWorked
+        Told
+        Type
+        id
+    );
+
+    my $orderby = join(' ', sort @orderby);
+
+    my @scraped_orderbys = $agent->scrape_text_by_attr('name', 'OrderBy');
+
+    my $first_orderby = shift @scraped_orderbys;
+    is ($first_orderby, $orderby);
+
+    foreach my $scraped_orderby ( @scraped_orderbys ) {
+            is ($scraped_orderby, '[none] '.$orderby);
+    }
+
+    my $cf = RT::Test->load_or_create_custom_field(
+        Name  => 'Location',
+        Queue => 'General',
+        Type  => 'FreeformSingle', );
+    isa_ok( $cf, 'RT::CustomField' );
+
+    ok($agent->form_name('BuildQuery'), "found the form");
+    $agent->field("ValueOfQueue", "General");
+    $agent->submit;
+
+    push @orderby, 'CustomField.{Location}';
+
+    $orderby = join(' ', sort @orderby);
+
+    @scraped_orderbys = $agent->scrape_text_by_attr('name', 'OrderBy');
+
+    $first_orderby = shift @scraped_orderbys;
+    is ($first_orderby, $orderby);
+
+    foreach my $scraped_orderby ( @scraped_orderbys ) {
+        is ($scraped_orderby, '[none] '.$orderby);
+    }
+
+    $cf->SetDisabled(1);
+}
+
+done_testing;

commit 06d49b39398d06de666ee481b1bb914c64049b83
Author: Brian C. Duggan <brian at bestpractical.com>
Date:   Tue Dec 12 09:50:31 2017 -0500

    Re-add Queue to 'Order by' dropdown in Search Builder
    
    Commit 8d0e8cf80f added support for searching by LIKE and NOT LIKE on
    queue. /Search/Elements/EditSort filters ticket fields by whether they
    have an ENUM key, among others. This change removed the ENUM key from
    the value for Queue in %FIELD_METADATA in /lib/RT/Tickets.pm. As a
    side effect, EditSort filtered Queue out of the fields to display in
    'Order by' dropdown in the Search Builder.
    
    This change adds the 'QUEUE' key, which Queue has in Tickets.pm, to
    the list of keys EditSort selects from ticket fields. This makes Queue
    available in the 'Order by' dropdown again.

diff --git a/share/html/Search/Elements/EditSort b/share/html/Search/Elements/EditSort
index 4853e17f2..8b6467145 100644
--- a/share/html/Search/Elements/EditSort
+++ b/share/html/Search/Elements/EditSort
@@ -104,7 +104,7 @@ my %fields;
 
 for my $field (keys %FieldDescriptions) {
     next if $field eq 'EffectiveId';
-    next unless $FieldDescriptions{$field}->[0] =~ /^(?:ENUM|INT|DATE|STRING|ID)$/;
+    next unless $FieldDescriptions{$field}->[0] =~ /^(?:ENUM|QUEUE|INT|DATE|STRING|ID)$/;
     $fields{$field} = $field;
 }
 

commit 9fa17efe40ec794d0f29ec4b1c8226d94cf3cfae
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jan 26 23:36:27 2018 +0800

    find idle port for ldap test server
    
    previously we don't check if the ldap test server port is in use or not,
    and tests hang if the port is already in use. switch to the same
    strategy we find idle web server port in tests.

diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 7ff4d68ea..656cced22 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -109,6 +109,7 @@ problem in Perl that hides the top-level optree from L<Devel::Cover>.
 
 our $port;
 our @SERVERS;
+my @ports; # keep track of all the random ports we used
 
 BEGIN {
     delete $ENV{$_} for qw/LANGUAGE LC_ALL LC_MESSAGES LANG/;
@@ -146,7 +147,7 @@ sub import {
 
     $class->bootstrap_tempdir;
 
-    $class->bootstrap_port;
+    $port = $class->find_idle_port;
 
     $class->bootstrap_plugins_paths( %args );
 
@@ -229,7 +230,7 @@ sub db_requires_no_dba {
     return 1 if $db_type eq 'SQLite';
 }
 
-sub bootstrap_port {
+sub find_idle_port {
     my $class = shift;
 
     my %ports;
@@ -245,6 +246,7 @@ sub bootstrap_port {
 
     # Pick a random port, checking that the port isn't in our in-use
     # list, and that something isn't already listening there.
+    my $port;
     {
         $port = 1024 + int rand(10_000) + $$ % 1024;
         redo if $ports{$port};
@@ -271,6 +273,8 @@ sub bootstrap_port {
     truncate(PORTS, 0);
     print PORTS "$_\n" for sort {$a <=> $b} keys %ports;
     close(PORTS) or die "Can't close ports file: $!";
+    push @ports, $port;
+    return $port;
 }
 
 sub bootstrap_tempdir {
@@ -1809,7 +1813,7 @@ END {
 
     # Drop our port from t/tmp/ports; do this after dropping the
     # database, as our port lock is also a lock on the database name.
-    if ($port) {
+    if (@ports) {
         my %ports;
         my $portfile = "$tmp{'directory'}/../ports";
         sysopen(PORTS, $portfile, O_RDWR|O_CREAT)
@@ -1817,7 +1821,7 @@ END {
         flock(PORTS, LOCK_EX)
             or die "Can't write-lock ports file $portfile: $!";
         $ports{$_}++ for split ' ', join("",<PORTS>);
-        delete $ports{$port};
+        delete $ports{$_} for @ports;
         seek(PORTS, 0, 0);
         truncate(PORTS, 0);
         print PORTS "$_\n" for sort {$a <=> $b} keys %ports;
diff --git a/t/externalauth/ldap.t b/t/externalauth/ldap.t
index 5c148ad4e..1e0516fab 100644
--- a/t/externalauth/ldap.t
+++ b/t/externalauth/ldap.t
@@ -8,7 +8,7 @@ eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } o
 };
 
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port" );
 
diff --git a/t/externalauth/ldap_escaping.t b/t/externalauth/ldap_escaping.t
index 5598d6042..b46c3ffe6 100644
--- a/t/externalauth/ldap_escaping.t
+++ b/t/externalauth/ldap_escaping.t
@@ -8,7 +8,7 @@ eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } o
 };
 
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port" );
 
diff --git a/t/externalauth/ldap_group.t b/t/externalauth/ldap_group.t
index cc6b7bd45..168c37b07 100644
--- a/t/externalauth/ldap_group.t
+++ b/t/externalauth/ldap_group.t
@@ -13,7 +13,7 @@ eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } o
 };
 
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port" );
 
diff --git a/t/externalauth/ldap_privileged.t b/t/externalauth/ldap_privileged.t
index 544440996..02e760bf3 100644
--- a/t/externalauth/ldap_privileged.t
+++ b/t/externalauth/ldap_privileged.t
@@ -7,7 +7,7 @@ eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } o
     plan skip_all => 'Unable to test without Net::LDAP and Net::LDAP::Server::Test';
 };
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port" );
 
diff --git a/t/ldapimport/group-callbacks.t b/t/ldapimport/group-callbacks.t
index 8a7a689ec..272d32921 100644
--- a/t/ldapimport/group-callbacks.t
+++ b/t/ldapimport/group-callbacks.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 my $ldap = Net::LDAP->new("localhost:$ldap_port");
diff --git a/t/ldapimport/group-import.t b/t/ldapimport/group-import.t
index 76db1bb20..b87bc97c0 100644
--- a/t/ldapimport/group-import.t
+++ b/t/ldapimport/group-import.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 my $ldap = Net::LDAP->new("localhost:$ldap_port");
diff --git a/t/ldapimport/group-member-import.t b/t/ldapimport/group-member-import.t
index 4e0ce8f66..651f5ab6c 100644
--- a/t/ldapimport/group-member-import.t
+++ b/t/ldapimport/group-member-import.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 my $ldap = Net::LDAP->new("localhost:$ldap_port");
diff --git a/t/ldapimport/group-rename.t b/t/ldapimport/group-rename.t
index 06207d448..786533ef9 100644
--- a/t/ldapimport/group-rename.t
+++ b/t/ldapimport/group-rename.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 my $ldap = Net::LDAP->new("localhost:$ldap_port");
diff --git a/t/ldapimport/user-import-cfs.t b/t/ldapimport/user-import-cfs.t
index 6a157ab55..a0c723ee0 100644
--- a/t/ldapimport/user-import-cfs.t
+++ b/t/ldapimport/user-import-cfs.t
@@ -25,7 +25,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 
diff --git a/t/ldapimport/user-import-privileged.t b/t/ldapimport/user-import-privileged.t
index 44aeff359..4b155eea7 100644
--- a/t/ldapimport/user-import-privileged.t
+++ b/t/ldapimport/user-import-privileged.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 
diff --git a/t/ldapimport/user-import.t b/t/ldapimport/user-import.t
index c404bb556..aafbd954d 100644
--- a/t/ldapimport/user-import.t
+++ b/t/ldapimport/user-import.t
@@ -10,7 +10,7 @@ eval { require RT::LDAPImport; require Net::LDAP::Server::Test; 1; } or do {
 my $importer = RT::LDAPImport->new;
 isa_ok($importer,'RT::LDAPImport');
 
-my $ldap_port = 1024 + int rand(10000) + $$ % 1024;
+my $ldap_port = RT::Test->find_idle_port;
 ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
     "spawned test LDAP server on port $ldap_port");
 

commit 64676e64ab2f5b50f4c2dc070cb476005f065da8
Author: craig Kaiser <craig at bestpractical.com>
Date:   Tue Feb 20 20:02:08 2018 -0500

    Add support for Queue Default Article for web UI
    
    For the Defaults page for Queues, add an option for a Default Article.
    Where the content of the Article will be loaded into the message box of
    any Ticket, on create in that Queue.

diff --git a/share/html/Admin/Queues/DefaultValues.html b/share/html/Admin/Queues/DefaultValues.html
index aff93cc0b..ccb4fd5a5 100644
--- a/share/html/Admin/Queues/DefaultValues.html
+++ b/share/html/Admin/Queues/DefaultValues.html
@@ -71,6 +71,11 @@
         Grouping => 'Basics',
         InTable => 1,
     &>
+
+    <tr><td class="label"><&|/l&>Article</&>:</td>
+        <td><& /Elements/SelectArticle, QueueObj => $queue &>
+    </td></tr>
+
     </table>
     </&>
 </div>
@@ -149,7 +154,7 @@ if ( $ARGS{Reset} ) {
     }
 }
 elsif ( $ARGS{Update} ) {
-    for my $field ( qw/InitialPriority FinalPriority Starts Due/ ) {
+    for my $field ( qw/InitialPriority FinalPriority Starts Due Article/ ) {
         my ($ret, $msg) = $queue->SetDefaultValue(
             Name => $field,
             Value => $ARGS{$field},
diff --git a/share/html/Articles/Elements/IncludeArticle b/share/html/Articles/Elements/IncludeArticle
index 5307875cf..4cfd83f0e 100644
--- a/share/html/Articles/Elements/IncludeArticle
+++ b/share/html/Articles/Elements/IncludeArticle
@@ -55,6 +55,7 @@ $name_prefix = $ARGS{'Name'} .'-'
     && grep rindex($_, "$ARGS{'Name'}-Articles-", 0) == 0,
         keys %$parent_args;
 
+my $article_included = 0;
 foreach my $arg ( keys %$parent_args ) {
     next if $name_prefix && substr($arg, 0, length($name_prefix)) ne $name_prefix;
 
@@ -78,6 +79,21 @@ foreach my $arg ( keys %$parent_args ) {
         Value => $parent_args->{$arg},
         Queue => $Queue->Id,
     );
+
+    # Check if Ticket id is present, if it is not we know we are creating a Ticket
+    if ( !$article_included && !$parent_args->{id} or $parent_args->{id} eq 'new' && $article && $article->id ){
+        my $queue_id = $parent_args->{'Queue'};
+
+        my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+        $QueueObj->Load( $queue_id );
+
+        if ($QueueObj->DefaultValue('Article') ){
+            $article->Load( $QueueObj->DefaultValue('Article') );
+        }
+
+        $article_included = 1;
+    }
+
     next unless $article && $article->id;
 
     my $formatted_article = $m->scomp('/Articles/Article/Elements/Preformatted',
diff --git a/share/html/Articles/Elements/IncludeArticle b/share/html/Elements/SelectArticle
similarity index 56%
copy from share/html/Articles/Elements/IncludeArticle
copy to share/html/Elements/SelectArticle
index 5307875cf..d93022bf2 100644
--- a/share/html/Articles/Elements/IncludeArticle
+++ b/share/html/Elements/SelectArticle
@@ -45,55 +45,44 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<%INIT>
-
-my $parent_args = $m->caller_args(-1);
-
-my $name_prefix = '';
-$name_prefix = $ARGS{'Name'} .'-'
-    if $ARGS{'Name'}
-    && grep rindex($_, "$ARGS{'Name'}-Articles-", 0) == 0,
-        keys %$parent_args;
-
-foreach my $arg ( keys %$parent_args ) {
-    next if $name_prefix && substr($arg, 0, length($name_prefix)) ne $name_prefix;
-
-    my $Ticket = $ARGS{Ticket};
-    if ( !$Ticket and $parent_args->{id} and $parent_args->{id} ne 'new' ) {
-        $Ticket = RT::Ticket->new($session{'CurrentUser'});
-        $Ticket->Load($parent_args->{id});
-        unless ( $Ticket->id ) {
-            $RT::Logger->error("Couldn't load ticket ". $parent_args->{id} )
-        }
-    }
+% if ( $autocomplete ) {
+<& "SelectArticleAutocomplete", articles => $articles, QueueObj => $QueueObj, Default => $Default &>
+% } else {
+<select name='Article'>
+<option value="">-</option>
+% while (my $article = $articles->Next) {
+<option <% ( $article->Name eq $Default) ? qq[ selected="selected"] : '' |n %>
+    value="<%$article->Id%>"
+><% $article->Name %></option>
+% }
+</select>
+% }
 
-    my $Queue = RT::Queue->new($session{CurrentUser});
-    if ($Ticket && $Ticket->Id) {
-        $Queue = $Ticket->QueueObj;
-    }
+<%INIT>
+my $articles = RT::Articles->new( $session{'CurrentUser'} );
+$articles->LimitHotlistClasses;
+$articles->LimitAppliedClasses( Queue => $QueueObj );
 
-    my $article = RT::Article->new($session{'CurrentUser'});
-    $article->LoadByInclude(
-        Field => substr($arg, length($name_prefix)),
-        Value => $parent_args->{$arg},
-        Queue => $Queue->Id,
-    );
-    next unless $article && $article->id;
+my $dropdown_limit = 50;
+$m->callback( CallbackName => 'ModifyDropdownLimit', DropdownLimit => \$dropdown_limit );
 
-    my $formatted_article = $m->scomp('/Articles/Article/Elements/Preformatted',
-        Article => $article, Ticket => $Ticket
-    );
+my $Default = '';
 
-    $m->callback( Article => $article, Ticket => $Ticket, formatted_article => \$formatted_article );
+my $autocomplete =  $articles->Count > $dropdown_limit ? 1 : 0;
 
-    if (RT->Config->Get('MessageBoxRichText',  $session{'CurrentUser'})) {
-        $formatted_article =~ s/>/>/g;
-        $formatted_article =~ s/</</g;
-        $formatted_article =~ s/&/&/g;
-        $formatted_article =~ s/\n/\n<br \/>/g;
+my $default_article = RT::Article->new($session{'CurrentUser'});
+# Default Article is "" if no value selected
+if ( defined $QueueObj->DefaultValue('Article') && $QueueObj->DefaultValue($Name) ne "") {
+    my ($ret, $msg) = $default_article->Load( $QueueObj->DefaultValue('Article') );
+    if ($ret) {
+         $Default = $default_article->Name;
+        } else{
+        RT::Logger->error($msg);
     }
-    $m->print($formatted_article);
-
 }
-return;
 </%INIT>
+
+<%ARGS>
+$QueueObj
+$Name => 'Article'
+</%ARGS>
diff --git a/share/html/Articles/Elements/IncludeArticle b/share/html/Elements/SelectArticleAutocomplete
similarity index 55%
copy from share/html/Articles/Elements/IncludeArticle
copy to share/html/Elements/SelectArticleAutocomplete
index 5307875cf..456d98774 100644
--- a/share/html/Articles/Elements/IncludeArticle
+++ b/share/html/Elements/SelectArticleAutocomplete
@@ -45,55 +45,9 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<%INIT>
+<input data-autocomplete="Articles" data-autocomplete-limit_queue=<% $QueueObj %> data-autocomplete-return="Name" name='Article' value="<% $Default %>" selected>
 
-my $parent_args = $m->caller_args(-1);
-
-my $name_prefix = '';
-$name_prefix = $ARGS{'Name'} .'-'
-    if $ARGS{'Name'}
-    && grep rindex($_, "$ARGS{'Name'}-Articles-", 0) == 0,
-        keys %$parent_args;
-
-foreach my $arg ( keys %$parent_args ) {
-    next if $name_prefix && substr($arg, 0, length($name_prefix)) ne $name_prefix;
-
-    my $Ticket = $ARGS{Ticket};
-    if ( !$Ticket and $parent_args->{id} and $parent_args->{id} ne 'new' ) {
-        $Ticket = RT::Ticket->new($session{'CurrentUser'});
-        $Ticket->Load($parent_args->{id});
-        unless ( $Ticket->id ) {
-            $RT::Logger->error("Couldn't load ticket ". $parent_args->{id} )
-        }
-    }
-
-    my $Queue = RT::Queue->new($session{CurrentUser});
-    if ($Ticket && $Ticket->Id) {
-        $Queue = $Ticket->QueueObj;
-    }
-
-    my $article = RT::Article->new($session{'CurrentUser'});
-    $article->LoadByInclude(
-        Field => substr($arg, length($name_prefix)),
-        Value => $parent_args->{$arg},
-        Queue => $Queue->Id,
-    );
-    next unless $article && $article->id;
-
-    my $formatted_article = $m->scomp('/Articles/Article/Elements/Preformatted',
-        Article => $article, Ticket => $Ticket
-    );
-
-    $m->callback( Article => $article, Ticket => $Ticket, formatted_article => \$formatted_article );
-
-    if (RT->Config->Get('MessageBoxRichText',  $session{'CurrentUser'})) {
-        $formatted_article =~ s/>/>/g;
-        $formatted_article =~ s/</</g;
-        $formatted_article =~ s/&/&/g;
-        $formatted_article =~ s/\n/\n<br \/>/g;
-    }
-    $m->print($formatted_article);
-
-}
-return;
-</%INIT>
+<%ARGS>
+$QueueObj => ""
+$Default => ""
+</%ARGS>
\ No newline at end of file

commit 6704b240531f9d470012a7e4b0a388940abe318f
Author: craig Kaiser <craig at bestpractical.com>
Date:   Tue Feb 20 20:02:38 2018 -0500

    Add autocomplete for Articles

diff --git a/share/html/Helpers/Autocomplete/Articles b/share/html/Helpers/Autocomplete/Articles
new file mode 100644
index 000000000..665eb7a66
--- /dev/null
+++ b/share/html/Helpers/Autocomplete/Articles
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2017 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 }}}
+% $r->content_type('application/json; charset=utf-8');
+<% JSON( \@suggestions ) |n %>
+% $m->abort;
+<%ARGS>
+$term       => undef
+$max        => 10
+$op         => 'STARTSWITH'
+$right      => undef
+$return     => 'Name'
+$limit_queue => undef
+</%ARGS>
+<%INIT>
+# Only allow certain return fields
+$return = 'Name'
+    unless $return =~ /^(?:id|Name)$/;
+
+$m->abort unless defined $return
+             and defined $term
+             and length $term;
+
+# Sanity check the operator
+$op = 'STARTSWITH' unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i;
+
+$m->callback( CallbackName => 'ModifyMaxResults', max => \$max );
+
+my $articles = RT::Articles->new( $session{CurrentUser} );
+$articles->LimitHotlistClasses;
+if( $limit_queue ) {
+    $articles->LimitAppliedClasses( Queue => $limit_queue );
+}
+
+$articles->RowsPerPage( $max );
+$articles->Limit(
+    FIELD           => 'Name',
+    OPERATOR        => $op,
+    VALUE           => $term,
+    ENTRYAGGREGATOR => 'OR',
+    CASESENSITIVE   => 0,
+);
+
+my @suggestions;
+while (my $a = $articles->Next) {
+    next if $right and not $a->CurrentUserHasRight($right);
+    my $value = $a->$return;
+    push @suggestions, { label => $a->Name, value => $value };
+    $m->callback( CallbackName => "ModifySuggestion", suggestions => @suggestions, label => $a );
+}
+</%INIT>
\ No newline at end of file
diff --git a/share/static/js/autocomplete.js b/share/static/js/autocomplete.js
index cd8ab2b0d..f5d0b46e7 100644
--- a/share/static/js/autocomplete.js
+++ b/share/static/js/autocomplete.js
@@ -5,7 +5,8 @@ window.RT.Autocomplete.Classes = {
     Users: 'user',
     Groups: 'group',
     Tickets: 'tickets',
-    Queues: 'queues'
+    Queues: 'queues',
+    Articles: 'articles'
 };
 
 window.RT.Autocomplete.bind = function(from) {

commit 7458fbe667da002c2135f9a87e001078c449bfb4
Author: craig Kaiser <craig at bestpractical.com>
Date:   Tue Feb 20 20:04:45 2018 -0500

    Test Ticket create web UI when Default Article
    
    Test that when a Queue Default Value is selected for Article, the
    content of the Article is loaded on the Ticket create page.

diff --git a/t/web/ticket-create-utf8.t b/t/web/ticket-create-utf8.t
index ebb2d5eab..76a7360b7 100644
--- a/t/web/ticket-create-utf8.t
+++ b/t/web/ticket-create-utf8.t
@@ -2,7 +2,7 @@
 use strict;
 use warnings;
 
-use RT::Test tests => 43;
+use RT::Test tests => 49;
 
 my $ru_test = "\x{442}\x{435}\x{441}\x{442}";
 my $ru_support = "\x{43f}\x{43e}\x{434}\x{434}\x{435}\x{440}\x{436}\x{43a}\x{430}";
@@ -86,3 +86,23 @@ foreach my $test_str ( $ru_test, $l1_test ) {
     }
 }
 
+my $article = RT::Article->new($RT::SystemUser);
+my ( $id, $msg ) = $article->Create(
+    Class   => 'General',
+    Name    => 'My Article',
+    'CustomField-Content' => 'My Article Test Content',
+);
+ok( $id, $msg );
+(my $ret, $msg) = $article->Load(1);
+ok ($ret, $msg);
+
+my $queue = RT::Queue->new(RT->SystemUser);
+$queue->Load('General');
+ok( $queue, 'Loaded General Queue' );
+($ret, $msg) = $queue->SetDefaultValue( Name => 'Article', Value => $article->Id);
+ok( $ret, $msg );
+
+ok $m->login(root => 'password'), "logged in";
+$m->goto_create_ticket('General');
+$m->scraped_id_is('Content', '#1: My Article <br />-------------- <br />Content: <br />------- <br />My Article Test Content <br />');
+

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


More information about the rt-commit mailing list