Skip to content

Commit

Permalink
Add new Description core ticket field
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrandtbuffalo committed Aug 2, 2024
1 parent f45d3f9 commit 507f6c3
Show file tree
Hide file tree
Showing 19 changed files with 417 additions and 5 deletions.
11 changes: 10 additions & 1 deletion etc/RT_Config.pm.in
Original file line number Diff line number Diff line change
Expand Up @@ -2015,7 +2015,7 @@ ordering of these standard groupings cannot be modified. You may also
only append Custom Fields to the list in these boxes, not reorder or
remove core fields.

For C<RT::Ticket>, these groupings are: C<Basics>, C<Dates>, C<Links>, C<People>, C<QuickCreate>
For C<RT::Ticket>, these groupings are: C<Basics>, C<Dates>, C<Links>, C<People>, C<Description>, C<QuickCreate>

For C<RT::User>: C<Identity>, C<Access control>, C<Location>, C<Phones>

Expand Down Expand Up @@ -3282,6 +3282,15 @@ Set this option to C<0> to disable this feature.

Set($QuoteSelectedText, 1);

=item C<$TicketDescriptionRows>

Set the height of the edit box for the optional Description field
on tickets. One row translates roughly to one line of text.

=cut

Set($TicketDescriptionRows, 20);

=back

=head2 Group Summary Configuration
Expand Down
2 changes: 2 additions & 0 deletions etc/schema.Pg
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ CREATE TABLE Tickets (
Type varchar(16) NULL ,
Owner integer NOT NULL DEFAULT 0 ,
Subject varchar(200) NULL DEFAULT '[no subject]' ,
Description text NULL ,
InitialPriority integer NOT NULL DEFAULT 0 ,
FinalPriority integer NOT NULL DEFAULT 0 ,
Priority integer NOT NULL DEFAULT 0 ,
Expand All @@ -431,6 +432,7 @@ CREATE TABLE Tickets (
CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
CREATE INDEX Tickets2 ON Tickets (Owner) ;
CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
CREATE INDEX Tickets7 ON Tickets USING GIN(to_tsvector('english', Description));


--
Expand Down
1 change: 1 addition & 0 deletions etc/schema.SQLite
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ CREATE TABLE Tickets (
Type varchar(16) collate NOCASE NULL ,
Owner integer NULL DEFAULT 0 ,
Subject varchar(200) collate NOCASE NULL DEFAULT '[no subject]' ,
Description text collate NOCASE NULL ,
InitialPriority integer NULL DEFAULT 0 ,
FinalPriority integer NULL DEFAULt 0 ,
Priority integer NULL DEFAULT 0 ,
Expand Down
2 changes: 2 additions & 0 deletions etc/schema.mysql
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ CREATE TABLE Tickets (
Type varchar(16) CHARACTER SET ascii NULL ,
Owner integer NOT NULL DEFAULT 0 ,
Subject varchar(200) NULL DEFAULT '[no subject]' ,
Description TEXT NULL ,
InitialPriority integer NOT NULL DEFAULT 0 ,
FinalPriority integer NOT NULL DEFAULT 0 ,
Priority integer NOT NULL DEFAULT 0 ,
Expand All @@ -290,6 +291,7 @@ CREATE TABLE Tickets (
CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
CREATE INDEX Tickets2 ON Tickets (Owner) ;
CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type) ;
CREATE FULLTEXT INDEX Tickets7 ON Tickets (Description) ;



Expand Down
2 changes: 2 additions & 0 deletions etc/upgrade/5.9.1/schema.Pg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE Tickets ADD COLUMN Description tsvector NULL;
CREATE INDEX Tickets7 ON Tickets USING GIN(Description);
2 changes: 2 additions & 0 deletions etc/upgrade/5.9.1/schema.mysql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE Tickets ADD COLUMN Description TEXT NULL;
CREATE INDEX Tickets7 ON Tickets USING GIN(to_tsvector('english', Description));
10 changes: 10 additions & 0 deletions lib/RT/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,16 @@ our %META;
Description => 'Quote selected text on ticket update', # loc
}
},
TicketDescriptionRows => {
Section => 'Ticket display',
Overridable => 1,
SortOrder => 15,
Widget => '/Widgets/Form/Integer',
WidgetArguments => {
Description => 'Ticket Description Rows', # loc
Hints => 'Rows for the Description edit box on tickets', # loc
}
},

# User overridable locale options
DateTimeFormat => {
Expand Down
5 changes: 5 additions & 0 deletions lib/RT/Handle.pm
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ sub Connect {
# statement_timeout is defined in milliseconds
$self->dbh->do( "SET statement_timeout = " . int( $timeout * 1000 ) )
if defined $timeout && length $timeout;

my $text_search_config = $self->dbh->selectrow_hashref('show default_text_search_config');
# Looks like "pg_catalog.english", we just want the "english" part
my ($pg_prefix, $search_language) = split /\./, $text_search_config->{'default_text_search_config'};
RT->Config->Set('DefaultTextSearchConfig', $search_language);
}
elsif ( $db_type eq 'SQLite' ) {
$self->dbh->{sqlite_see_if_its_a_number} = 1;
Expand Down
29 changes: 29 additions & 0 deletions lib/RT/Interface/Web.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,35 @@ sub ProcessTicketBasics {
return (@results);
}

=head2 ProcessTicketDescription ( TicketObj => $Ticket, ARGSRef => \%ARGS );
Returns an array of results messages.
=cut

sub ProcessTicketDescription {

my %args = (
TicketObj => undef,
ARGSRef => undef,
@_
);

my $TicketObj = $args{'TicketObj'};
my $ARGSRef = $args{'ARGSRef'};

# Set basic fields
my @attribs = qw( Description );

my @results = UpdateRecordObject(
AttributesRef => \@attribs,
Object => $TicketObj,
ARGSRef => $ARGSRef,
);

return (@results);
}

sub ProcessTicketReminders {
my %args = (
TicketObj => undef,
Expand Down
5 changes: 5 additions & 0 deletions lib/RT/Ticket.pm
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ Arguments: ARGS is a hash of named parameters. Valid parameters are:
Type -- The ticket's type. ignore this for now
Owner -- This ticket's owner. either an RT::User object or this user's id
Subject -- A string describing the subject of the ticket
Description -- More detailed information about the purpose of this ticket
Priority -- an integer from 0 to 99
InitialPriority -- an integer from 0 to 99
FinalPriority -- an integer from 0 to 99
Expand Down Expand Up @@ -274,6 +275,7 @@ sub Create {
Type => 'ticket',
Owner => undef,
Subject => '',
Description => undef,
InitialPriority => undef,
FinalPriority => undef,
Priority => undef,
Expand Down Expand Up @@ -432,6 +434,7 @@ sub Create {
my %params = (
Queue => $QueueObj->Id,
Subject => $args{'Subject'},
Description => $args{'Description'},
InitialPriority => $args{'InitialPriority'},
FinalPriority => $args{'FinalPriority'},
Priority => $args{'Priority'},
Expand Down Expand Up @@ -3703,6 +3706,8 @@ sub _CoreAccessible {
{read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
Subject =>
{read => 1, write => 1, sql_type => 12, length => 200, is_blob => 0, is_numeric => 0, type => 'varchar(200)', default => '[no subject]'},
Description =>
{read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'text', default => ''},
InitialPriority =>
{read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
FinalPriority =>
Expand Down
91 changes: 91 additions & 0 deletions lib/RT/Tickets.pm
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ our %FIELD_METADATA = (
LastUpdated => [ 'DATE' => 'LastUpdated', ], #loc_left_pair
Created => [ 'DATE' => 'Created', ], #loc_left_pair
Subject => [ 'STRING', ], #loc_left_pair
Description => [ 'FULLTEXTSTRING', ], #loc_left_pair
Content => [ 'TRANSCONTENT', ], #loc_left_pair
ContentType => [ 'TRANSFIELD', ], #loc_left_pair
Filename => [ 'TRANSFIELD', ], #loc_left_pair
Expand Down Expand Up @@ -189,6 +190,7 @@ our %dispatch = (
LINK => \&_LinkLimit,
DATE => \&_DateLimit,
STRING => \&_StringLimit,
FULLTEXTSTRING => \&_FullTextStringLimit,
QUEUE => \&_QueueLimit,
TRANSFIELD => \&_TransLimit,
TRANSCONTENT => \&_TransContentLimit,
Expand Down Expand Up @@ -746,6 +748,95 @@ sub _StringLimit {
);
}

=head2 _FullTextStringLimit
Handle strings with a full text index like Description
Meta Data:
None
=cut

sub _FullTextStringLimit {
my ( $self, $field, $op, $value, %rest ) = @_;

my $db_type = RT->Config->Get('DatabaseType');

if ( $db_type eq 'Oracle'
&& (!defined $value || !length $value)
&& lc($op) ne 'is' && lc($op) ne 'is not'
) {
if ($op eq '!=' || $op =~ /^NOT\s/i) {
$op = 'IS NOT';
} else {
$op = 'IS';
}
$value = 'NULL';
}

if ( $db_type eq 'Oracle' ) {
my $dbh = $RT::Handle->dbh;
$self->Limit(
%rest,
FUNCTION => "CONTAINS( $field, ".$dbh->quote($value) .")",
OPERATOR => '>',
VALUE => 0,
QUOTEVALUE => 0,
CASESENSITIVE => 1,
);
# this is required to trick DBIx::SB's LEFT JOINS optimizer
# into deciding that join is redundant as it is
$self->Limit(
ENTRYAGGREGATOR => 'AND',
FIELD => 'Description',
OPERATOR => 'IS NOT',
VALUE => 'NULL',
);
}
elsif ( $db_type eq 'Pg' ) {
my $dbh = $RT::Handle->dbh;

$self->Limit(
%rest,
FIELD => $field,
OPERATOR => '@@',
VALUE => 'plainto_tsquery(\'' . RT->Config->Get('DefaultTextSearchConfig') . '\', '. $dbh->quote($value) .')',
QUOTEVALUE => 0,
);
}
elsif ( $db_type eq 'mysql' ) {
my $dbh = $RT::Handle->dbh;
$self->Limit(
%rest,
FUNCTION => "MATCH(Description)",
OPERATOR => 'AGAINST',
VALUE => "(". $dbh->quote($value) ." IN BOOLEAN MODE)",
QUOTEVALUE => 0,
);
# As with Oracle, above, this forces the LEFT JOINs into
# JOINS, which allows the FULLTEXT index to be used.
# Orthogonally, the IS NOT NULL clause also helps the
# optimizer decide to use the index.
$self->Limit(
ENTRYAGGREGATOR => 'AND',
FIELD => "Description",
OPERATOR => 'IS NOT',
VALUE => 'NULL',
QUOTEVALUE => 0,
);
}
else {
# SQLite
$self->Limit(
FIELD => $field,
OPERATOR => $op,
VALUE => $value,
CASESENSITIVE => 0,
%rest,
);
}
}

=head2 _QueueLimit
Handle Queue field supporting both "is" and "match".
Expand Down
6 changes: 4 additions & 2 deletions share/html/Helpers/TicketUpdate
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ my @message_changes = ProcessUpdateMessage(

my @watchers_changes = ProcessTicketWatchers( ARGSRef => \%ARGS, TicketObj => $TicketObj );
my @basics_changes = ProcessTicketBasics( ARGSRef => \%ARGS, TicketObj => $TicketObj );
my @description_changes = ProcessTicketDescription( ARGSRef => \%ARGS, TicketObj => $TicketObj );
my @links_changes = ProcessTicketLinks( ARGSRef => \%ARGS, TicketObj => $TicketObj );
my @dates_changes = ProcessTicketDates( ARGSRef => \%ARGS, TicketObj => $TicketObj );
my @cfs_changes = ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $TicketObj );
Expand All @@ -93,13 +94,14 @@ push @events, 'ticketOwnerChanged' if @owner_changes;
push @events, 'ticketMessageChanged' if @message_changes;
push @events, 'ticketWatchersChanged' if @watchers_changes;
push @events, 'ticketBasicsChanged' if @basics_changes;
push @events, 'ticketDescriptionChanged' if @description_changes;
push @events, 'ticketLinksChanged' if @links_changes;
push @events, 'ticketDatesChanged' if @dates_changes;
push @events, 'ticketCustomFieldsChanged' if @cfs_changes;
push @events, 'ticketRemindersChanged' if @reminders_changes;

push @Actions, @owner_changes, @message_changes, @watchers_changes, @basics_changes, @links_changes, @dates_changes,
@cfs_changes, @reminders_changes;
push @Actions, @owner_changes, @message_changes, @watchers_changes, @basics_changes, @description_changes, @links_changes,
@dates_changes, @cfs_changes, @reminders_changes;

for my $txn (@{ $TicketObj->{_TransactionBatch} || [] }) {
if ( $txn->Type eq 'Set' ) {
Expand Down
13 changes: 13 additions & 0 deletions share/html/Search/Elements/PickBasics
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,19 @@ else {
},
Value => { Type => 'text', Size => 20 },
},
{
Name => 'Description',
Field => loc('Description'),
Op => {
Type => 'component',
Path => '/Elements/SelectBoolean',
Arguments => {
True => loc("matches"),
TrueVal => 'LIKE',
},
},
Value => { Type => 'text', Size => 20 },
},
{
Name => 'Queue',
Field => loc('Queue'),
Expand Down
70 changes: 70 additions & 0 deletions share/html/Ticket/Elements/EditDescription
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
%# BEGIN BPS TAGGED BLOCK {{{
%#
%# COPYRIGHT:
%#
%# This software is Copyright (c) 1996-2024 Best Practical Solutions, LLC
%# <[email protected]>
%#
%# (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 }}}

% unless ($InTable) {
<div>
% }

<&| /Elements/LabeledValue, Label => loc(''), LabelFor => 'Description', LabelTooltip => loc('Additional details about this ticket'), ReadOnly => 0 &>
<input type="text" class="hidden" name="DescriptionType" id="DescriptionType" value="text/html" />
<textarea class="form-control richtext signature" name="Description" wrap="hard" rows="<% $DescriptionRows %>"><% $TicketObj->Description |n %></textarea>
</&>

% $m->callback( CallbackName => 'EndOfList', TicketObj => $TicketObj, %ARGS );
% unless ($InTable) {
</div>
% }
<%init>
</%init>
<%args>
$TicketObj => undef
$InTable => 0
%defaults => ()
$ReadOnly => 0
$DescriptionRows => RT->Config->Get('TicketDescriptionRows') || 20
</%args>
Loading

0 comments on commit 507f6c3

Please sign in to comment.