diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Config/Files/DefaultTo.xml | 20 | ||||
-rw-r--r-- | Kernel/Modules/AdminDefaultTo.pm | 351 | ||||
-rw-r--r-- | Kernel/Output/HTML/Standard/AdminDefaultTo.tt | 212 |
3 files changed, 583 insertions, 0 deletions
diff --git a/Kernel/Config/Files/DefaultTo.xml b/Kernel/Config/Files/DefaultTo.xml index 9dd0f64..2a075a5 100644 --- a/Kernel/Config/Files/DefaultTo.xml +++ b/Kernel/Config/Files/DefaultTo.xml @@ -15,6 +15,26 @@ </Hash> </Setting> </ConfigItem> + <ConfigItem Name="Frontend::Module###AdminDefaultTo" Required="0" Valid="1"> + <Description Translatable="1">Frontend module registration for the agent interface.</Description> + <Group>Ticket</Group> + <SubGroup>Frontend::Admin::ModuleRegistration</SubGroup> + <Setting> + <FrontendModuleReg> + <Group>admin</Group> + <Description>Admin</Description> + <Title Translatable="1">DefaultTo</Title> + <NavBarName>Admin</NavBarName> + <NavBarModule> + <Module>Kernel::Output::HTML::NavBarModuleAdmin</Module> + <Name Translatable="1">DefaultTo</Name> + <Description Translatable="1">Create and manage DefaultTo entries.</Description> + <Block>Queue</Block> + <Prio>300</Prio> + </NavBarModule> + </FrontendModuleReg> + </Setting> + </ConfigItem> <ConfigItem Name="Frontend::Module###AdminDefaultToTemplates" Required="0" Valid="1"> <Description Translatable="1">Frontend module registration for the agent interface.</Description> <Group>Ticket</Group> diff --git a/Kernel/Modules/AdminDefaultTo.pm b/Kernel/Modules/AdminDefaultTo.pm new file mode 100644 index 0000000..042c55c --- /dev/null +++ b/Kernel/Modules/AdminDefaultTo.pm @@ -0,0 +1,351 @@ +# -- +# Kernel/Modules/AdminTemplate.pm - provides admin DefaultTo module +# Copyright (C) 2015 Alexander Sulfrian <alex@spline.inf.fu-berlin.de> +# -- +# This software comes with ABSOLUTELY NO WARRANTY. For details, see +# the enclosed file COPYING for license information (AGPL). If you +# did not receive this file, see http://www.gnu.org/licenses/agpl.txt. +# -- + +package Kernel::Modules::AdminTemplate; + +use strict; +use warnings; + +use Kernel::System::DefaultTo; + +sub new { + my ( $Type, %Param ) = @_; + + # allocate new hash for object + my $Self = {%Param}; + bless( $Self, $Type ); + + # check all needed objects + for my $Needed (qw(ParamObject DBObject LayoutObject ConfigObject LogObject)) { + if ( !$Self->{$Needed} ) { + $Self->{LayoutObject}->FatalError( Message => "Got no $Needed!" ); + } + } + $Self->{DefaultToObject} = Kernel::System::DefaultTo->new(%Param); + + return $Self; +} + +sub Run { + my ( $Self, %Param ) = @_; + + # ------------------------------------------------------------ # + # change + # ------------------------------------------------------------ # + if ( $Self->{Subaction} eq 'Change' ) { + my $ID = $Self->{ParamObject}->GetParam( Param => 'ID' ) || ''; + my %Data = $Self->{DefaultToObject}->Get( + ID => $ID, + ); + + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Self->_Edit( + Action => 'Change', + %Data, + ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + + # ------------------------------------------------------------ # + # change action + # ------------------------------------------------------------ # + elsif ( $Self->{Subaction} eq 'ChangeAction' ) { + + # challenge token check for write action + $Self->{LayoutObject}->ChallengeTokenCheck(); + + my @NewIDs = $Self->{ParamObject}->GetArray( Param => 'IDs' ); + my ( %GetParam, %Errors ); + for my $Parameter (qw(ID Title RemoveDefault AddNew NewAddress + Comment)) { + $GetParam{$Parameter} = $Self->{ParamObject}->GetParam( + Param => $Parameter + ) || ''; + } + + # check needed data + $Errors{ 'TitleInvalid' } = 'ServerError' if !$GetParam{Title}; + + # check if a DefaultTo entry exist with this title + my $TitleExists = $Self->{DefaultToObject}->TitleExistsCheck( + Title => $GetParam{Title}, + ID => $GetParam{ID} + ); + + if ($TitleExists) { + $Errors{TitleExists} = 1; + $Errors{'TitleInvalid'} = 'ServerError'; + } + + # if no errors occurred + if ( !%Errors ) { + + if ( $Self->{DefaultToObject}->Update( + %GetParam, + UserID => $Self->{UserID}, + ) + ) + { + $Self->_Overview(); + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Output .= $Self->{LayoutObject}->Notify( Info => 'Template updated!' ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + } + + # something has gone wrong + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Output .= $Self->{LayoutObject}->Notify( Priority => 'Error' ); + $Self->_Edit( + Action => 'Change', + Errors => \%Errors, + %GetParam, + ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + + # ------------------------------------------------------------ # + # add + # ------------------------------------------------------------ # + elsif ( $Self->{Subaction} eq 'Add' ) { + my %GetParam; + $GetParam{Title} = $Self->{ParamObject}->GetParam( Param => 'Title' ); + + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Self->_Edit( + Action => 'Add', + %GetParam, + ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + + # ------------------------------------------------------------ # + # add action + # ------------------------------------------------------------ # + elsif ( $Self->{Subaction} eq 'AddAction' ) { + + # challenge token check for write action + $Self->{LayoutObject}->ChallengeTokenCheck(); + + my @NewIDs = $Self->{ParamObject}->GetArray( Param => 'IDs' ); + my ( %GetParam, %Errors ); + + for my $Parameter (qw(ID Title RemoveDefault AddNew NewAddress + Comment)) { + $GetParam{$Parameter} = $Self->{ParamObject}->GetParam( Param => $Parameter ) || ''; + } + + # check needed data + $Errors{ 'TitleInvalid' } = 'ServerError' if !$GetParam{Title}; + + # check if a DefaultTo entry exists with this title + my $TitleExists = $Self->{DefaultToObject}->TitleExistsCheck( Title => $GetParam{Title} ); + if ($TitleExists) { + $Errors{TitleExists} = 1; + $Errors{'TitleInvalid'} = 'ServerError'; + } + + # if no errors occurred + if ( !%Errors ) { + + # add DefaultTo entry + my $ID = $Self->{DefaultToObject}->Add + %GetParam, + UserID => $Self->{UserID}, + ); + + if ($ID) { + $Self->_Overview(); + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Output .= $Self->{LayoutObject}->Notify( Info => 'Template added!' ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + } + + # something has gone wrong + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Output .= $Self->{LayoutObject}->Notify( Priority => 'Error' ); + $Self->_Edit( + Action => 'Add', + Errors => \%Errors, + %GetParam, + ); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } + + # ------------------------------------------------------------ # + # delete action + # ------------------------------------------------------------ # + elsif ( $Self->{Subaction} eq 'Delete' ) { + + # challenge token check for write action + $Self->{LayoutObject}->ChallengeTokenCheck(); + + my $ID = $Self->{ParamObject}->GetParam( Param => 'ID' ); + + my $Delete = $Self->{DefaultToObject}->Delete( + ID => $ID, + ); + if ( !$Delete ) { + return $Self->{LayoutObject}->ErrorScreen(); + } + + return $Self->{LayoutObject}->Redirect( OP => "Action=$Self->{Action}" ); + } + + # ------------------------------------------------------------ + # overview + # ------------------------------------------------------------ + else { + $Self->_Overview(); + my $Output = $Self->{LayoutObject}->Header(); + $Output .= $Self->{LayoutObject}->NavigationBar(); + $Output .= $Self->{LayoutObject}->Output( + TemplateFile => 'AdminDefaultTo', + Data => \%Param, + ); + $Output .= $Self->{LayoutObject}->Footer(); + return $Output; + } +} + +sub _Edit { + my ( $Self, %Param ) = @_; + + $Self->{LayoutObject}->Block( + Name => 'Overview', + Data => \%Param, + ); + + $Self->{LayoutObject}->Block( Name => 'ActionList' ); + $Self->{LayoutObject}->Block( Name => 'ActionOverview' ); + + $Param{DefaultToTitleString} = ''; + + $Param{DefaultToRemoveDefaultOption} = $Self->{LayoutObject}->BuildSelection( + Data => $Self->{ConfigObject}->Get('YesNoOptions'), + Name => 'RemoveDefault', + SelectedID => $Param{RemoveDefault} || 0, + ); + + $Param{DefaultToAddNewOption} = $Self->{LayoutObject}->BuildSelection( + Data => $Self->{ConfigObject}->Get('YesNoOptions'), + Name => 'AddNew', + SelectedID => $Param{AddNew} || 0, + ); + + $Param{DefaultToNewAddressString} = ''; + + $Self->{LayoutObject}->Block( + Name => 'OverviewUpdate', + Data => { + %Param, + %{ $Param{Errors} }, + }, + ); + + # shows header + if ( $Param{Action} eq 'Change' ) { + $Self->{LayoutObject}->Block( Name => 'HeaderEdit' ); + } + else { + $Self->{LayoutObject}->Block( Name => 'HeaderAdd' ); + } + + # show appropriate messages for ServerError + if ( defined $Param{Errors}->{TitleExists} && $Param{Errors}->{TitleExists} == 1 ) { + $Self->{LayoutObject}->Block( Name => 'ExistTitleServerError' ); + } + else { + $Self->{LayoutObject}->Block( Name => 'TitleServerError' ); + } + + return 1; +} + +sub _Overview { + my ( $Self, %Param ) = @_; + + $Self->{LayoutObject}->Block( + Name => 'Overview', + Data => \%Param, + ); + + $Self->{LayoutObject}->Block( Name => 'ActionList' ); + $Self->{LayoutObject}->Block( Name => 'ActionAdd' ); + $Self->{LayoutObject}->Block( Name => 'Filter' ); + + $Self->{LayoutObject}->Block( + Name => 'OverviewResult', + Data => \%Param, + ); + my %List = $Self->{DefaultToObject}->List(); + + for my $ID ( sort { $List{$a} cmp $List{$b} } keys %List ) + { + my %DefaultTo = $Self->{DefaultToObject}->Get( + ID => $ID, + ); + + $Self->{LayoutObject}->Block( + Name => 'OverviewResultRow', + Data => { + %DefaultTo, + }, + ); + } + + # otherwise it displays a no data found message + else { + $Self->{LayoutObject}->Block( + Name => 'NoDataFoundMsg', + Data => {}, + ); + } + + return 1; +} + +1; diff --git a/Kernel/Output/HTML/Standard/AdminDefaultTo.tt b/Kernel/Output/HTML/Standard/AdminDefaultTo.tt new file mode 100644 index 0000000..04e4c91 --- /dev/null +++ b/Kernel/Output/HTML/Standard/AdminDefaultTo.tt @@ -0,0 +1,212 @@ +# -- +# AdminDefaultTo.tt - provides HTML form for AdminDefaultTo +# Copyright (C) 2015 Alexander Sulfrian <alex@spline.inf.fu-berlin.de> +# -- +# This software comes with ABSOLUTELY NO WARRANTY. For details, see +# the enclosed file COPYING for license information (AGPL). If you +# did not receive this file, see http://www.gnu.org/licenses/agpl.txt. +# -- + +[% RenderBlockStart("Overview") %] +<div class="MainBox ARIARoleMain LayoutFixedSidebar SidebarFirst"> + <h1>[% Translate("Manage DefaultTo") | html %]</h1> + + <div class="SidebarColumn"> +[% RenderBlockStart("ActionList") %] + <div class="WidgetSimple"> + <div class="Header"><h2>[% Translate("Actions") | html %]</h2></div> + <div class="Content"> + <ul class="ActionList"> +[% RenderBlockStart("ActionOverview") %] + <li> + <a href="[% Env("Baselink") %]Action=[% Env("Action") %]" class="CallForAction Fullsize Center"><span><i class="fa fa-caret-left"></i>[% Translate("Go to overview") | html %]</span></a> + </li> +[% RenderBlockEnd("ActionOverview") %] +[% RenderBlockStart("ActionAdd") %] + <li> + <a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=Add" class="CallForAction Fullsize Center"><span><i class="fa fa-plus-square"></i>[% Translate("Add DefaultTo") | html %]</span></a> + </li> +[% RenderBlockEnd("ActionAdd") %] + </ul> + </div> + </div> +[% RenderBlockStart("Filter") %] + <div class="WidgetSimple"> + <div class="Header"> + <h2><label for="Filter">[% Translate("Filter") | html %]</label></h2> + </div> + <div class="Content"> + <input type="text" id="Filter" class="FilterBox" placeholder="[% Translate("Just start typing to filter...") | html %]" name="Filter" value="" title="[% Translate("Filter") | html %]" /> + </div> + </div> +[% RenderBlockEnd("Filter") %] +[% RenderBlockEnd("ActionList") %] + + <div class="WidgetSimple"> + <div class="Header"> + <h2>[% Translate("Hint") | html %]</h2> + </div> + <div class="Content"> + + <p class="FieldExplanation"> + [% Translate("With DefaultTo you could change or extend the default To address in a ticket response dependent on the used template.") | html %] + </p> + <p> + [% Translate("Attention") | html %]: + <a href="[% Env("Baselink") %]Action=AdminDefaultToTemplates">[% Translate("Don't forget to add new DefaultTo entries to templates.") | html %]</a> + </p> + </div> + </div> + </div> + <div class="ContentColumn"> + +[% RenderBlockStart("OverviewResult") %] + <div class="WidgetSimple"> + <div class="Header"> + <h2>[% Translate("List") | html %]</h2> + </div> + <div class="Content"> + <table class="DataTable" id="DefaultTo"> + <thead> + <tr> + <th>[% Translate("Title") | html %]</th> + <th>[% Translate("Remove default") | html %]</th> + <th>[% Translate("Add new") | html %]</th> + <th>[% Translate("New address") | html %]</th> + <th>[% Translate("Comment") | html %]</th> + <th>[% Translate("Changed") | html %]</th> + <th>[% Translate("Created") | html %]</th> + <th>[% Translate("Delete") | html %]</th> + </tr> + </thead> + <tbody> + <tr class="FilterMessage Hidden"> + <td colspan="7">[% Translate("No matches found.") | html %]</td> + </tr> +[% RenderBlockStart("NoDataFoundMsg") %] + <tr> + <td colspan="7"> + [% Translate("No data found.") | html %] + </td> + </tr> +[% RenderBlockEnd("NoDataFoundMsg") %] +[% RenderBlockStart("OverviewResultRow") %] + <tr> + <td> + <a class="AsBlock" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=Change;ID=[% Data.ID | uri %]">[% Data.Name | html %]</a> + </td> + <td>[% Translate(Data.RemoveDefault) | html %]</td> + <td>[% Translate(Data.AddNew) | html %]</td> + <td>[% Data.NewAddress | html %]</td> + <td title="[% Data.Comment | html %]">[% Data.Comment | truncate(26) | html %]</td> + <td>[% Data.ChangeTime | Localize("TimeShort") %]</td> + <td>[% Data.CreateTime | Localize("TimeShort") %]</td> + <td class="Center"> + <a class="TrashCan" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=Delete;ID=[% Data.ID | uri %];[% Env("ChallengeTokenParam") | html %]" title="[% Translate("Delete this entry") | html %]"> + [% Translate("Delete this entry") | html %] + <i class="fa fa-trash-o"></i> + </a> + </td> + </tr> +[% RenderBlockEnd("OverviewResultRow") %] + </tbody> + </table> + </div> + </div> +[% WRAPPER JSOnDocumentComplete %] +<script type="text/javascript">//<![CDATA[ + Core.UI.Table.InitTableFilter($('#Filter'), $('#DefaultTo')); +//]]></script> +[% END %] +[% RenderBlockEnd("OverviewResult") %] +[% RenderBlockStart("OverviewUpdate") %] + + <div class="WidgetSimple"> + <div class="Header"> +[% RenderBlockStart("HeaderAdd") %] + <h2>[% Translate("Add DefaultTo") | html %]</h2> +[% RenderBlockEnd("HeaderAdd") %] +[% RenderBlockStart("HeaderEdit") %] + <h2>[% Translate("Edit DefaultTo") | html %]</h2> +[% RenderBlockEnd("HeaderEdit") %] + </div> + <div class="Content"> + <form action="[% Env("CGIHandle") %]" method="post" class="Validate PreventMultipleSubmits"> + <input type="hidden" name="Action" value="[% Env("Action") %]"/> + <input type="hidden" name="Subaction" value="[% Data.Action | uri %]Action"/> + <input type="hidden" name="ID" value="[% Data.ID | html %]"/> + <fieldset class="TableLike"> + <label class="Mandatory" for="TemplateType"><span class="Marker">*</span> [% Translate("Title") | html %]:</label> + <div class="Field"> + <input type="text" name="Title" id="Title" value="[% Data.Title | html %]" class="W50pc Validate_Required [% Date.TitleInvalid | html %]" maxlength="200"/> + <div id="DefaultToTitleError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + <div id="DefaultToTitleServerError" class="TooltipErrorMessage"> +[% RenderBlockStart("TitleServerError") %] + <p>[% Translate("This field is required.") | html %]</p> +[% RenderBlockEnd("TitleServerError") %] +[% RenderBlockStart("ExistTitleServerError") %] + <p>[% Translate("A DefaultTo entry with this title already exists!") | html %]</p> +[% RenderBlockEnd("TitleServerError") %] + </div> + </div> + <div class="Clear"></div> + + <label class="Mandatory" for="Name"><span class="Marker">*</span> [% Translate("Remove default") | html %]:</label> + <div class="Field"> + [% Data.DefaultToRemoveDefaultOption %] + <div id="RemoveDefaultError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + <div id="RemoveDefaultServerError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + </div> + <div class="Clear"></div> + + <label class="Mandatory" for="Name"><span class="Marker">*</span> [% Translate("Add new") | html %]:</label> + <div class="Field"> + [% Data.DefaultToAddNewOption %] + <div id="AddNewError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + <div id="AddNewServerError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + </div> + <div class="Clear"></div> + + <label class="Mandatory" for="Name"><span class="Marker">*</span> [% Translate("New address") | html %]:</label> + <div class="Field"> + <input type="text" name="NewAddress" id="NewAddress" value="[% Data.NewAddress | html %]" class="W50pc Validate_Required" maxlength="200"/> + <div id="NewAddressError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + <div id="NewAddressServerError" class="TooltipErrorMessage"> + <p>[% Translate("This field is required.") | html %]</p> + </div> + </div> + <div class="Clear"></div> + + <label for="Comment">[% Translate("Comment") | html %]:</label> + <div class="Field"> + <input type="text" name="Comment" id="Comment" value="[% Data.Comment | html %]" class="W50pc" maxlength="250"/> + </div> + <div class="Clear"></div> + + <div class="Field"> + <button class="Primary CallForAction" type="submit" value="[% Translate("Submit") | html %]"><span>[% Translate("Submit") | html %]</span></button> + [% Translate("or") | html %] + <a href="[% Env("Baselink") %]Action=AdminDefaultTo">[% Translate("Cancel") | html %]</a> + </div> + <div class="Clear"></div> + </fieldset> + </form> + </div> + </div> +[% RenderBlockEnd("OverviewUpdate") %] + </div> + <div class="Clear"></div> +</div> +[% RenderBlockEnd("Overview") %] |