Feature Requests: Queuespecific Keyword Layout

D) Queuespecific but globally defined KeywordSelects

The following requirement was quite troubling to me:
When moving Tickets from one queue to another, they should keep their
Keywords (-> So I use global Keywords) - but on the other hand there
are
some queues (like the FAQ queue) that need only a subset of the global
keywords. (-> So I don’t display all global keywords in some queues)

  • So: Here is a little HowTo for a queuespecific keyword-layout.
    (Based on version 2.0.15)

First, add the desired Layout of the keyword-selects to your
config-script:

########################################## FILE: etc/config.pm

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

added by Andreas.Warnke @3SOFT.de

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

Layout of the Keyword Selections for the Create, Search and Modify

Forms

Key-Syntax: : or QueueName:* or *:FormName or QueueName:FormName

List-Syntax: pairs of ‘HTML’,HTMLCode or

‘KeywordSelect’,KeywordSelectName or

‘IgnoreKeySelect’,KeywordSelectName

%KeywordLayout = (
:’ => [
‘HTML’, ‘

Type’,
‘KeywordSelect’, ‘Motion’,
‘HTML’, ‘’,
‘KeywordSelect’,‘Position’,
‘HTML’, ‘’,
‘KeywordSelect’,‘Verified’,
‘HTML’, ‘
’,
‘KeywordSelect’, ‘Type’,
‘HTML’, ‘
Motion
Signals ’,
‘KeywordSelect’, ‘Signals’,
‘HTML’, ‘
Position
Verified

],
:Create’ => [
‘HTML’, ‘Type’,
‘KeywordSelect’, ‘Motion’,
‘HTML’, ‘’,
‘KeywordSelect’,‘Position’,
‘HTML’, ‘
’,
‘KeywordSelect’, ‘Type’,
‘HTML’, ‘
Motion
Signals ’,
‘KeywordSelect’, ‘Signals’,
‘HTML’, ‘
Position
’,
‘IgnoreKeySelect’,‘Verified’,
],
'FAQ:
’ => [
‘IgnoreKeySelect’,‘Type’,
‘IgnoreKeySelect’,‘Signals’,
‘IgnoreKeySelect’,‘Motion’,
‘IgnoreKeySelect’,‘Position’,
‘IgnoreKeySelect’,‘Verified’,
],
);

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

########################################## /FILE: etc/config.pm

Then change the files that display the keyword-selections:

########################################## FILE:
webrt/Ticket/Create.html

%# Run the config layout script:
% my $actiontype;
% while ($actiontype = shift @LayoutScript ) {
% if ( $actiontype eq ‘HTML’ ) {
% print (shift @LayoutScript);
% }
% elsif ( $actiontype eq ‘IgnoreKeySelect’ ) {
% delete $AllSelects{shift @LayoutScript};
% }
% elsif ( $actiontype eq ‘KeywordSelect’ ) {
% my $KSName = shift @LayoutScript;
% if ( defined $AllSelects{$KSName}) {
% my ($KSID,$KSSingle,$Descendents) = @{delete
$AllSelects{$KSName}};

% # Popup Menus if single selects, checkboxes if multiple:
% if ($KSSingle) {
<SELECT NAME=“KeywordSelect-<% $KSID %>” SIZE=1">
% foreach my $kid ( keys %{$Descendents} ) {
<% $Descendents->{$kid}
%>
% }
(empty)

% }
% else {


% foreach my $kid ( keys %{$Descendents} ) {

<% $Descendents->{$kid} %>

% }

% }
% }
% }
% else {shift @LayoutScript;}
% }

%# Display the keywords that are not yet handled:

% foreach my $KSName (keys %AllSelects) {
% my ($KSID,$KSSingle,$Descendents) = @{$AllSelects{$KSName}};

<TR><TD ALIGN=RIGHT>
<% $KSName %></TD><TD>

  <INPUT TYPE="hidden" NAME="KeywordSelectMagic<% $KSID %>"

VALUE=“1”>
%# Popup Menus if single selects, checkboxes if multiple:
% if ($KSSingle) {
<SELECT NAME=“KeywordSelect-<% $KSID %>” SIZE=1">

% foreach my $kid ( keys %{$Descendents} ) {
<% $Descendents->{$kid}
%>
% }

(empty) % } % else {
% foreach my $kid ( keys %{$Descendents} ) {
<% $Descendents->{$kid} %>
% }
% } % }
<& /Elements/TitleBoxEnd &>

<& /Elements/Submit, Label => “Create”&>






















<%INIT>
my $QueueObj = new RT::Queue($session{‘CurrentUser’});
$QueueObj->Load($Queue) || Abort(“Queue could not be loaded.”);
my $KeywordSelects = $QueueObj->KeywordSelects;

Get all Keyword selects from the Database:

my %AllSelects = ();
while ( my $KeywordSelect = $KeywordSelects->Next ) {
my $KSDescendentsRef = $KeywordSelect->KeywordObj->Descendents;
my $KSName = $KeywordSelect->Name;
my $KSID = $KeywordSelect->id;
my $KSSingle = $KeywordSelect->Single;
$AllSelects{$KSName}=[($KSID,$KSSingle,$KSDescendentsRef)];
}

Find the appropriate config.pm Layout script:

my @LayoutScript = ();
if (exists $RT::KeywordLayout{$QueueObj->Name.’:Create’}) {
@LayoutScript=@{$RT::KeywordLayout{$QueueObj->Name.’:Create’}};}
elsif (exists $RT::KeywordLayout{$QueueObj->Name.’:’}) {
@LayoutScript=@{$RT::KeywordLayout{$QueueObj->Name.’:
’}};}
elsif (exists $RT::KeywordLayout{’:Create’}) {
@LayoutScript=@{$RT::KeywordLayout{’
:Create’}};}
elsif (exists $RT::KeywordLayout{’:’}) {
@LayoutScript=@{$RT::KeywordLayout{’:’}};}

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

</%INIT>

########################################## FILE:
webrt/Ticket/Elements/EditKeywordSelects

%# ----------------------------------------
%# modified by andreas warnke @3SOFT.de
%# ----------------------------------------

%# Run the config layout script:
% my $actiontype;
% while ($actiontype = shift @LayoutScript ) {
% if ( $actiontype eq ‘HTML’ ) {
% print (shift @LayoutScript);
% }
% elsif ( $actiontype eq ‘IgnoreKeySelect’ ) {
% delete $AllSelects{shift @LayoutScript};
% }
% elsif ( $actiontype eq ‘KeywordSelect’ ) {
% my $KSName = shift @LayoutScript;
% if ( defined $AllSelects{$KSName}) {
% my ($KSID,$KSSingle,$Descendents) = @{delete
$AllSelects{$KSName}};
% my $selected_keywords = 0;
% my $CurrentKeywords = $TicketObj->KeywordsObj($KSID);

% # Popup Menus if single selects, checkboxes if multiple:
% if ($KSSingle) {
<SELECT NAME=“KeywordSelect<% $KSID %>” SIZE=1">
% foreach my $kid ( keys %{$Descendents} ) {
% my $selected = 0;
% if ($CurrentKeywords->HasEntry($kid)) {
$selected_keywords++; $selected=1;}
<OPTION VALUE="<% $kid %>" <% $selected && ‘SELECTED’%>

<% $Descendents->{$kid} %>
% }
<OPTION VALUE="" <% ($selected_keywords == 0) && ‘SELECTED’
%> >(empty)

% }
% else {


% foreach my $kid ( keys %{$Descendents} ) {
% my $selected = 0;
% if ($CurrentKeywords->HasEntry($kid)) { $selected=1;}

<INPUT TYPE=“checkbox” NAME=“KeywordSelect<% $KSID %>“
VALUE=”<% $kid %>” <% $selected && ‘CHECKED’%> /><% $Descendents->{$kid}
%>

% }

% }
% }
% }
% else {shift @LayoutScript;}
% }

%# Display the keywords that are not yet handled:

% foreach my $KSName (keys %AllSelects) {
% my ($KSID,$KSSingle,$Descendents) = @{$AllSelects{$KSName}};
% my $CurrentKeywords = $TicketObj->KeywordsObj($KSID);
% my $selected_keywords = 0;

<TR><TD ALIGN=RIGHT>
<% $KSName %></TD><TD>

  <INPUT TYPE="hidden" NAME="KeywordSelectMagic<% $KSID %>"

VALUE=“1”>
% # Popup Menus if single selects, checkboxes if multiple:
% if ($KSSingle) {
<SELECT NAME=“KeywordSelect<% $KSID %>” SIZE=1">

% foreach my $kid ( keys %{$Descendents} ) {
% my $selected = 0;
% if ($CurrentKeywords->HasEntry($kid)) {
$selected_keywords++; $selected=1;}
<OPTION VALUE="<% $kid %>"
<% $selected && ‘SELECTED’%>>
<% $Descendents->{$kid} %>

% }
<OPTION VALUE="" <% ($selected_keywords == 0) && ‘SELECTED’ %>

(empty)

% }
% else {


% foreach my $kid ( keys %{$Descendents} ) {
% my $selected = 0;
% if ($CurrentKeywords->HasEntry($kid)) { $selected=1;}

<INPUT TYPE=“checkbox” NAME=“KeywordSelect<% $KSID %>“
VALUE=”<% $kid %>” <% $selected && ‘CHECKED’%> /><% $Descendents->{$kid}
%>

% }

% }
% }

<%INIT>
my $KeywordSelects = $TicketObj->QueueObj->KeywordSelects;

Get all Keyword selects from the Database:

my %AllSelects = ();
while ( my $KeywordSelect = $KeywordSelects->Next ) {
my $KSDescendentsRef = $KeywordSelect->KeywordObj->Descendents;
my $KSName = $KeywordSelect->Name;
my $KSID = $KeywordSelect->id;
my $KSSingle = $KeywordSelect->Single;
$AllSelects{$KSName}=[($KSID,$KSSingle,$KSDescendentsRef)];
}

Find the appropriate config.pm Layout script:

my @LayoutScript = ();
if (exists $RT::KeywordLayout{$TicketObj->QueueObj->Name.’:Modify’}) {

@LayoutScript=@{$RT::KeywordLayout{$TicketObj->QueueObj->Name.’:Modify’}
};}
elsif (exists $RT::KeywordLayout{$TicketObj->QueueObj->Name.’:*’}) {

@LayoutScript=@{$RT::KeywordLayout{$TicketObj->QueueObj->Name.’:’}};}
elsif (exists $RT::KeywordLayout{’
:Modify’}) {
@LayoutScript=@{$RT::KeywordLayout{’:Modify’}};}
elsif (exists $RT::KeywordLayout{’
:’}) {
@LayoutScript=@{$RT::KeywordLayout{’
:*’}};}

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

</%INIT>

<%ARGS>
$TicketObj => undef
</%ARGS>

########################################## FILE:
webrt/Ticket/Elements/ShowKeywordSelects

%# ----------------------------------------
%# modified by andreas warnke @3SOFT.de
%# ----------------------------------------

%# Run the config layout script:
% my $actiontype;
% while ($actiontype = shift @LayoutScript ) {
% if ( $actiontype eq ‘HTML’ ) {
% print (shift @LayoutScript);
% }
% elsif ( $actiontype eq ‘IgnoreKeySelect’ ) {
% delete $AllSelects{shift @LayoutScript};
% }
% elsif ( $actiontype eq ‘KeywordSelect’ ) {
% my $KSName = shift @LayoutScript;
% if ( defined $AllSelects{$KSName}) {
% my ($KSID,$KSSingle,$Descendents) = @{delete
$AllSelects{$KSName}};
% my $CurrentKeywords = $Ticket->KeywordsObj($KSID);


    % foreach my $kid ( keys %{$Descendents} ) {
    % if ($CurrentKeywords->HasEntry($kid)) {
  • <% $Descendents->{$kid} %>

  • % }
    % }

% }
% }
% else {shift @LayoutScript;}
% }

%# Display the keywords that are not yet handled:

% foreach my $KSName (keys %AllSelects) {
% my ($KSID,$KSSingle,$Descendents) = @{$AllSelects{$KSName}};
% my $CurrentKeywords = $Ticket->KeywordsObj($KSID);
% my $selected_keywords = 0;

<TR><TD ALIGN=RIGHT>
<% $KSName %></TD><TD>
      <ul>

% foreach my $kid ( keys %{$Descendents} ) {
% if ($CurrentKeywords->HasEntry($kid)) {

  • <% $Descendents->{$kid} %>

  • % }
    % }


    % }

    <%INIT>
    my $KeywordSelects = $Ticket->QueueObj->KeywordSelects;

    Get all Keyword selects from the Database:

    my %AllSelects = ();
    while ( my $KeywordSelect = $KeywordSelects->Next ) {
    my $KSDescendentsRef = $KeywordSelect->KeywordObj->Descendents;
    my $KSName = $KeywordSelect->Name;
    my $KSID = $KeywordSelect->id;
    my $KSSingle = $KeywordSelect->Single;
    $AllSelects{$KSName}=[($KSID,$KSSingle,$KSDescendentsRef)];
    }

    Find the appropriate config.pm Layout script:

    my @LayoutScript = ();
    if (exists $RT::KeywordLayout{$Ticket->QueueObj->Name.’:Display’}) {

    @LayoutScript=@{$RT::KeywordLayout{$Ticket->QueueObj->Name.’:Display’}};
    }
    elsif (exists $RT::KeywordLayout{$Ticket->QueueObj->Name.’:’}) {
    @LayoutScript=@{$RT::KeywordLayout{$Ticket->QueueObj->Name.’:
    ’}};}
    elsif (exists $RT::KeywordLayout{’:Display’}) {
    @LayoutScript=@{$RT::KeywordLayout{’
    :Display’}};}
    elsif (exists $RT::KeywordLayout{’:’}) {
    @LayoutScript=@{$RT::KeywordLayout{’:’}};}

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

    </%INIT>

    <%ARGS>
    $Ticket => undef
    </%ARGS>

    ########################################## FILE:
    webrt/Search/PickRestriction

    %# $Header: /pro/CVS/rt/rt-2-0-15/webrt-rtee/Search/PickRestriction,v
    1.3 2002/12/11 15:49:58 anwa2219 Exp $

    <& /Elements/TitleBoxStart, title => 'Refine Search'&>

    %# ----------------------------------------
    %# modified by andreas.warnke @3SOFT.de
    %# ----------------------------------------
    <-- Add these criteria to the current search.

    Owner <& /Elements/SelectBoolean, Name => "OwnerOp", TrueVal=> '=', FalseVal => '!=' &> <& /Elements/SelectOwner, Name => "ValueOfOwner" &>
    Requestor email address <& /Elements/SelectMatch, Name => "RequestorOp" &>
    Subject <& /Elements/SelectMatch, Name => "SubjectOp" &>
    Queue <& /Elements/SelectBoolean, Name => "QueueOp" , True => "is", False => "isn't", TrueVal=> '=', FalseVal => '!=' &> <& /Elements/SelectQueue, Name => "ValueOfQueue" &>
    Priority <& /Elements/SelectEqualityOperator, Name => "PriorityOp" &>
    <& /Elements/SelectDateType, Name => 'DateType' &> <& /Elements/SelectDateRelation, Name=>"DateOp" &> <& /Elements/SelectDate, Name => "ValueOfDate", ShowTime => 0, Default => '' &>
    Ticket content <& /Elements/SelectBoolean, Name => "ContentOp", True => "matches", False => "does not match", TrueVal => 'LIKE', FalseVal => 'NOT LIKE' &>
    Status <& /Elements/SelectBoolean, Name => "StatusOp", True => "is", False => "isn't", TrueVal=> '=', FalseVal => '!=' &> <& /Elements/SelectStatus, Name => "ValueOfStatus" &>

    %# Run the config layout script:
    % my $actiontype;
    % while ($actiontype = shift @LayoutScript ) {
    % if ( $actiontype eq ‘HTML’ ) {
    % print (shift @LayoutScript);
    % }
    % elsif ( $actiontype eq ‘IgnoreKeySelect’ ) {
    % delete $AllSelects{shift @LayoutScript};
    % }
    % elsif ( $actiontype eq ‘KeywordSelect’ ) {
    % my $KSName = shift @LayoutScript;
    % if ( defined $AllSelects{$KSName}) {
    % my ($KSID,$KSSingle,$Descendents) = @{delete
    $AllSelects{$KSName}};
    <& /Elements/SelectBoolean, Name => “KeywordSelectOp”. $KSID,
    True => “is”, False => “isn’t”,
    TrueVal=> ‘=’, FalseVal => ‘!=’ &>

    -
    (empty)
    % foreach my $kid ( keys %{$Descendents} ) {
    <% $Descendents->{$kid} %>
    % }

    % }
    % }
    % else {shift @LayoutScript;}
    % }

    %# Display the keywords that are not yet handled:


    % }

    % foreach my $KSName (keys %AllSelects) {
    % my ($KSID,$KSSingle,$Descendents) = @{$AllSelects{$KSName}};

    <TR><TD ALIGN=RIGHT>
    <% $KSName %></TD><TD>
    <& /Elements/SelectBoolean, Name => "KeywordSelectOp". $KSID, 
    			    True => "is", False => "isn't", 
    			    TrueVal=> '=', FalseVal => '!=' &>
    </TD><TD>
          <SELECT NAME="KeywordSelect<%$KSID%>" SIZE="1">
        <OPTION VALUE="">-</OPTION>
        <OPTION VALUE="NULL">(empty)</OPTION>
    

    % foreach my $kid ( keys %{$Descendents} ) {
    <% $Descendents->{$kid} %>
    % }

    <& /Elements/TitleBoxEnd &>

    <& /Elements/TitleBoxStart, title => ‘Ordering and sorting’&>

    Results per page

    <& /Elements/SelectResultsPerPage, Name =>
    “RowsPerPage”,
    Default =>
    $session{‘tickets_rows_per_page’} || ‘50’
    &>
    Sort results by <& /Elements/SelectTicketSortBy, Name => "TicketsSortBy", Default => $session{'tickets_sort_by'} &> <& /Elements/SelectSortOrder, Name => 'TicketsSortOrder', Default => $session{'tickets_sort_order'} &>
    <& /Elements/Refresh, Name => 'RefreshSearchInterval' , Default => $session{'tickets_refresh_interval'} &>
    %# ----------------------------------------

    <& /Elements/TitleBoxEnd &>
    %# ----------------------------------------
    %# modified by andreas.warnke @3SOFT.de
    %# ----------------------------------------
    %#<& /Elements/Submit, Label => ‘Show Results’, AlternateLabel =>
    ‘Refine’, Name => ‘Action’&>
    <& /Elements/Submit, Label => ‘Show Results’, Name => ‘Action’&>
    %# ----------------------------------------

    <%INIT>
    my $KeywordSelects = new RT::KeywordSelects $session{‘CurrentUser’};
    foreach ( $session{‘tickets’}->RestrictionValues(‘Queue’) ) {
    $KeywordSelects->LimitToQueue($_);
    }

    $KeywordSelects->IncludeGlobals;

    Get all Keyword selects from the Database:

    my %AllSelects = ();
    while ( my $KeywordSelect = $KeywordSelects->Next ) {
    my $KSDescendentsRef = $KeywordSelect->KeywordObj->Descendents;
    my $KSName = $KeywordSelect->Name;
    my $KSID = $KeywordSelect->id;
    my $KSSingle = $KeywordSelect->Single;
    $AllSelects{$KSName}=[($KSID,$KSSingle,$KSDescendentsRef)];
    }

    get the queue-name:

    my ($QueueName,$QueueCount) = (undef,0);
    my %descrList = $session{‘tickets’}->DescribeRestrictions();
    foreach my $descr ( values %descrList ) {
    if ( $descr =~ /^Queue = / ) {
    $QueueName = substr $descr, 8;
    $QueueCount ++;
    }
    }

    Find the appropriate config.pm Layout script:

    my @LayoutScript = ();
    if (exists $RT::KeywordLayout{’:Search’}) {
    @LayoutScript=@{$RT::KeywordLayout{’
    :Search’}};}
    elsif (exists $RT::KeywordLayout{’:’}) {
    @LayoutScript=@{$RT::KeywordLayout{’:’}};}
    if ( $QueueCount == 1 ) {
    if (exists $RT::KeywordLayout{$QueueName.’:Search’}) {
    @LayoutScript=@{$RT::KeywordLayout{$QueueName.’:Search’}};}
    elsif (exists $RT::KeywordLayout{$QueueName.’:’}) {
    @LayoutScript=@{$RT::KeywordLayout{$QueueName.’:
    ’}};}
    }
    </%INIT>

    ########################################## /FILE

    Regards
    Andi

    Andreas Warnke
    3SOFT GmbH, Frauenweiherst. 14, 91058 Erlangen
    Tel.: +49-9131-7701-274 mailto:Andreas.Warnke@3SOFT.de
    Fax: +49-9131-7701-333 http://www.3SOFT.de