Files
scripts/Perl OTRS/Kernel/Modules/AgentDashboardCommon.pm
2024-10-14 00:08:40 +02:00

1009 lines
33 KiB
Perl

# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::Modules::AgentDashboardCommon;
## nofilter(TidyAll::Plugin::OTRS::Perl::DBObject)
use strict;
use warnings;
use Kernel::Language qw(Translatable);
use Kernel::System::VariableCheck qw(:all);
our $ObjectManagerDisabled = 1;
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {%Param};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
my $BackendConfigKey = 'DashboardBackend';
my $MainMenuConfigKey = 'AgentDashboard::MainMenu';
my $UserSettingsKey = 'UserDashboard';
if ( $Self->{Action} eq 'AgentCustomerInformationCenter' ) {
$BackendConfigKey = 'AgentCustomerInformationCenter::Backend';
$MainMenuConfigKey = 'AgentCustomerInformationCenter::MainMenu';
$UserSettingsKey = 'UserCustomerInformationCenter';
}
elsif ( $Self->{Action} eq 'AgentCustomerUserInformationCenter' ) {
$BackendConfigKey = 'AgentCustomerUserInformationCenter::Backend';
$MainMenuConfigKey = 'AgentCustomerUserInformationCenter::MainMenu';
$UserSettingsKey = 'UserCustomerUserInformationCenter';
}
# get needed objects
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# load backends
my $Config = $ConfigObject->Get($BackendConfigKey);
if ( !$Config ) {
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}->Translate( 'No such config for %s', $BackendConfigKey ),
);
}
# Get all configured statistics from the system that should be shown as a dashboard widget
# and register them dynamically in the configuration.
my @StatsIDs;
if ( $Self->{Action} eq 'AgentDashboard' ) {
my $StatsHash = $Kernel::OM->Get('Kernel::System::Stats')->StatsListGet(
UserID => $Self->{UserID},
);
if ( IsHashRefWithData($StatsHash) ) {
STATID:
for my $StatID ( sort keys %{$StatsHash} ) {
next STATID if !$StatsHash->{$StatID}->{ShowAsDashboardWidget};
# check permissions
next STATID if !$StatsHash->{$StatID}->{Permission};
next STATID if !IsArrayRefWithData( $StatsHash->{$StatID}->{Permission} );
my @StatsPermissionGroupNames;
for my $GroupID ( @{ $StatsHash->{$StatID}->{Permission} } ) {
push @StatsPermissionGroupNames,
$Kernel::OM->Get('Kernel::System::Group')->GroupLookup( GroupID => $GroupID );
}
my $StatsPermissionGroups = join( ';', @StatsPermissionGroupNames );
# replace all line breaks with spaces (otherwise Translate() will not work correctly)
$StatsHash->{$StatID}->{Description} =~ s{\r?\n|\r}{ }msxg;
my $Description = $LayoutObject->{LanguageObject}->Translate( $StatsHash->{$StatID}->{Description} );
my $Title = $LayoutObject->{LanguageObject}->Translate( $StatsHash->{$StatID}->{Title} );
$Title = $LayoutObject->{LanguageObject}->Translate('Statistic') . ': '
. $Title . ' ('
. $ConfigObject->Get('Stats::StatsHook')
. $StatsHash->{$StatID}->{StatNumber} . ')';
$Config->{ ( $StatID + 1000 ) . '-Stats' } = {
'Block' => 'ContentLarge',
'Default' => 0,
'Module' => 'Kernel::Output::HTML::Dashboard::Stats',
'Title' => $Title,
'StatID' => $StatID,
'Description' => $Description,
'Group' => $StatsPermissionGroups,
};
push @StatsIDs, $StatID;
}
# send data to JS
$LayoutObject->AddJSData(
Key => 'DashboardStatsIDs',
Value => \@StatsIDs
);
}
}
# get needed objects
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
if ( $Self->{Action} eq 'AgentCustomerInformationCenter' ) {
$Self->{CustomerID} = $ParamObject->GetParam( Param => 'CustomerID' );
# check CustomerID presence for all subactions that need it
if ( $Self->{Subaction} ne 'UpdatePosition' ) {
if ( !$Self->{CustomerID} ) {
$LayoutObject->AddJSOnDocumentComplete(
Code => 'Core.Agent.CustomerInformationCenterSearch.OpenSearchDialog();'
);
my $Output = $LayoutObject->Header();
$Output .= $LayoutObject->NavigationBar();
$Output .= $LayoutObject->Footer();
return $Output;
}
}
}
elsif ( $Self->{Action} eq 'AgentCustomerUserInformationCenter' ) {
$Self->{CustomerUserID} = $ParamObject->GetParam( Param => 'CustomerUserID' );
# check CustomerUserID presence for all subactions that need it
if ( $Self->{Subaction} ne 'UpdatePosition' ) {
if ( !$Self->{CustomerUserID} ) {
$LayoutObject->AddJSOnDocumentComplete(
Code => 'Core.Agent.CustomerUserInformationCenterSearch.OpenSearchDialog();'
);
my $Output = $LayoutObject->Header();
$Output .= $LayoutObject->NavigationBar();
$Output .= $LayoutObject->Footer();
return $Output;
}
}
}
# get needed objects
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');
my $UserObject = $Kernel::OM->Get('Kernel::System::User');
# update/close item
if ( $Self->{Subaction} eq 'UpdateRemove' ) {
# challenge token check for write action
$LayoutObject->ChallengeTokenCheck();
my $Name = $ParamObject->GetParam( Param => 'Name' );
my $Key = $UserSettingsKey . $Name;
# Mandatory widgets can't be removed.
if ( $Config->{$Name} && $Config->{$Name}->{Mandatory} ) {
return $LayoutObject->Redirect(
OP => "Action=$Self->{Action}",
);
}
# update session
$SessionObject->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => $Key,
Value => 0,
);
# update preferences
if ( !$ConfigObject->Get('DemoSystem') ) {
$UserObject->SetPreferences(
UserID => $Self->{UserID},
Key => $Key,
Value => 0,
);
}
my $URL = "Action=$Self->{Action}";
if ( $Self->{CustomerID} ) {
$URL .= ";CustomerID=" . $LayoutObject->LinkEncode( $Self->{CustomerID} );
}
if ( $Self->{CustomerUserID} ) {
$URL .= ";CustomerUserID=" . $LayoutObject->LinkEncode( $Self->{CustomerUserID} );
}
return $LayoutObject->Redirect(
OP => $URL,
);
}
# update preferences
elsif ( $Self->{Subaction} eq 'UpdatePreferences' ) {
# challenge token check for write action
$LayoutObject->ChallengeTokenCheck();
my $Name = $ParamObject->GetParam( Param => 'Name' );
# get preferences settings
my @PreferencesOnly = $Self->_Element(
Name => $Name,
Configs => $Config,
PreferencesOnly => 1,
);
if ( !@PreferencesOnly ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'No preferences for %s!', $Name ),
);
}
# remember preferences
for my $Param (@PreferencesOnly) {
# get params
my $Value = $ParamObject->GetParam( Param => $Param->{Name} );
# update runtime vars
$LayoutObject->{ $Param->{Name} } = $Value;
# update session
$SessionObject->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => $Param->{Name},
Value => $Value,
);
# update preferences
if ( !$ConfigObject->Get('DemoSystem') ) {
$UserObject->SetPreferences(
UserID => $Self->{UserID},
Key => $Param->{Name},
Value => $Value,
);
}
}
# deliver new content page
my %ElementReload = $Self->_Element(
Name => $Name,
Configs => $Config,
AJAX => 1
);
if ( !%ElementReload ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Can\'t get element data of %s!', $Name ),
);
}
return $LayoutObject->Attachment(
ContentType => 'text/html',
Content => ${ $ElementReload{Content} },
Type => 'inline',
NoCache => 1,
);
}
# update settings
elsif ( $Self->{Subaction} eq 'UpdateSettings' ) {
# challenge token check for write action
$LayoutObject->ChallengeTokenCheck();
my @Backends = $ParamObject->GetArray( Param => 'Backend' );
for my $Name ( sort keys %{$Config} ) {
my $Active = 0;
BACKEND:
for my $Backend (@Backends) {
next BACKEND if $Backend ne $Name;
$Active = 1;
last BACKEND;
}
# Mandatory widgets can not be removed.
if ( $Config->{$Name}->{Mandatory} ) {
$Active = 1;
}
my $Key = $UserSettingsKey . $Name;
# update session
$SessionObject->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => $Key,
Value => $Active,
);
# update preferences
if ( !$ConfigObject->Get('DemoSystem') ) {
$UserObject->SetPreferences(
UserID => $Self->{UserID},
Key => $Key,
Value => $Active,
);
}
}
my $URL = "Action=$Self->{Action}";
if ( $Self->{CustomerID} ) {
$URL .= ";CustomerID=" . $LayoutObject->LinkEncode( $Self->{CustomerID} );
}
if ( $Self->{CustomerUserID} ) {
$URL .= ";CustomerUserID=" . $LayoutObject->LinkEncode( $Self->{CustomerUserID} );
}
return $LayoutObject->Redirect(
OP => $URL,
);
}
# update position
elsif ( $Self->{Subaction} eq 'UpdatePosition' ) {
# challenge token check for write action
$LayoutObject->ChallengeTokenCheck();
my @Backends = $ParamObject->GetArray( Param => 'Backend' );
# get new order
my $Key = $UserSettingsKey . 'Position';
my $Data = '';
for my $Backend (@Backends) {
$Backend =~ s{ \A Dashboard (.+?) -box \z }{$1}gxms;
$Data .= $Backend . ';';
}
# update session
$SessionObject->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => $Key,
Value => $Data,
);
# update preferences
if ( !$ConfigObject->Get('DemoSystem') ) {
$UserObject->SetPreferences(
UserID => $Self->{UserID},
Key => $Key,
Value => $Data,
);
}
# send successful response
return $LayoutObject->Attachment(
ContentType => 'text/html',
Charset => $LayoutObject->{UserCharset},
Content => '1',
);
}
# deliver element
elsif ( $Self->{Subaction} eq 'Element' ) {
my $Name = $ParamObject->GetParam( Param => 'Name' );
# get the column filters from the web request
my %ColumnFilter;
my %GetColumnFilter;
my %GetColumnFilterSelect;
COLUMNNAME:
for my $ColumnName (
qw(Owner Responsible State Queue Priority Type Lock Service SLA CustomerID CustomerUserID)
)
{
my $FilterValue = $ParamObject->GetParam( Param => 'ColumnFilter' . $ColumnName . $Name )
|| '';
next COLUMNNAME if $FilterValue eq '';
if ( $ColumnName eq 'CustomerID' ) {
push @{ $ColumnFilter{$ColumnName} }, $FilterValue;
push @{ $ColumnFilter{ $ColumnName . 'Raw' } }, $FilterValue;
}
elsif ( $ColumnName eq 'CustomerUserID' ) {
push @{ $ColumnFilter{CustomerUserLogin} }, $FilterValue;
push @{ $ColumnFilter{CustomerUserLoginRaw} }, $FilterValue;
}
else {
push @{ $ColumnFilter{ $ColumnName . 'IDs' } }, $FilterValue;
}
$GetColumnFilter{ $ColumnName . $Name } = $FilterValue;
$GetColumnFilterSelect{$ColumnName} = $FilterValue;
}
# get all dynamic fields
my $DynamicField = $DynamicFieldObject->DynamicFieldListGet(
Valid => 1,
ObjectType => ['Ticket'],
);
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
next DYNAMICFIELD if !$DynamicFieldConfig->{Name};
my $FilterValue = $ParamObject->GetParam(
Param => 'ColumnFilterDynamicField_' . $DynamicFieldConfig->{Name} . $Name
);
next DYNAMICFIELD if !defined $FilterValue;
next DYNAMICFIELD if $FilterValue eq '';
$ColumnFilter{ 'DynamicField_' . $DynamicFieldConfig->{Name} } = {
Equals => $FilterValue,
};
$GetColumnFilter{ 'DynamicField_' . $DynamicFieldConfig->{Name} . $Name } = $FilterValue;
$GetColumnFilterSelect{ 'DynamicField_' . $DynamicFieldConfig->{Name} } = $FilterValue;
}
my $SortBy = $ParamObject->GetParam( Param => 'SortBy' );
my $OrderBy = $ParamObject->GetParam( Param => 'OrderBy' );
my %Element = $Self->_Element(
Name => $Name,
Configs => $Config,
AJAX => 1,
SortBy => $SortBy,
OrderBy => $OrderBy,
ColumnFilter => \%ColumnFilter,
GetColumnFilter => \%GetColumnFilter,
GetColumnFilterSelect => \%GetColumnFilterSelect,
);
if ( !%Element ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Can\'t get element data of %s!', $Name ),
);
}
return $LayoutObject->Attachment(
ContentType => 'text/html',
Charset => $LayoutObject->{UserCharset},
Content => ${ $Element{Content} },
Type => 'inline',
NoCache => 1,
);
}
# deliver element
elsif ( $Self->{Subaction} eq 'AJAXFilterUpdate' ) {
my $ElementChanged = $ParamObject->GetParam( Param => 'ElementChanged' );
my ($Name) = $ElementChanged =~ m{ ( \d{4} - .*? ) \z }gxms;
my $Column = $ElementChanged;
$Column =~ s{ \A ColumnFilter }{}gxms;
$Column =~ s{ $Name }{}gxms;
my $FilterContent = $Self->_Element(
Name => $Name,
FilterContentOnly => 1,
FilterColumn => $Column,
ElementChanged => $ElementChanged,
Configs => $Config,
);
if ( !$FilterContent ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Can\'t get filter content data of %s!', $Name ),
);
}
return $LayoutObject->Attachment(
ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
Content => $FilterContent,
Type => 'inline',
NoCache => 1,
);
}
# store last queue screen
$SessionObject->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => 'LastScreenOverview',
Value => $Self->{RequestedURL},
);
my %ContentBlockData;
if ( $Self->{Action} eq 'AgentCustomerInformationCenter' ) {
$ContentBlockData{CustomerID} = $Self->{CustomerID};
# H1 title
$ContentBlockData{CustomerIDTitle} = $Self->{CustomerID};
my %CustomerCompanyData = $Kernel::OM->Get('Kernel::System::CustomerCompany')->CustomerCompanyGet(
CustomerID => $Self->{CustomerID},
);
if ( $CustomerCompanyData{CustomerCompanyName} ) {
$ContentBlockData{CustomerIDTitle} = "$CustomerCompanyData{CustomerCompanyName} ($Self->{CustomerID})";
}
}
elsif ( $Self->{Action} eq 'AgentCustomerUserInformationCenter' ) {
my %CustomerUserData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
User => $Self->{CustomerUserID},
);
$ContentBlockData{CustomerUserID} = $Self->{CustomerUserID};
# H1 title
$ContentBlockData{CustomerUserIDTitle} = "\"$CustomerUserData{UserFullname}\" <$CustomerUserData{UserEmail}>";
}
# show dashboard
$LayoutObject->Block(
Name => 'Content',
Data => \%ContentBlockData,
);
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
# get shown backends
my %Backends;
BACKEND:
for my $Name ( sort keys %{$Config} ) {
# check permissions
if ( $Config->{$Name}->{Group} ) {
my $PermissionOK = 0;
my @Groups = split /;/, $Config->{$Name}->{Group};
GROUP:
for my $Group (@Groups) {
my $HasPermission = $GroupObject->PermissionCheck(
UserID => $Self->{UserID},
GroupName => $Group,
Type => 'ro',
);
if ($HasPermission) {
$PermissionOK = 1;
last GROUP;
}
}
next BACKEND if !$PermissionOK;
}
my $Key = $UserSettingsKey . $Name;
if ( defined $Self->{$Key} ) {
$Backends{$Name} = $Self->{$Key};
}
else {
$Backends{$Name} = $Config->{$Name}->{Default};
}
# Always show widgets with mandatory flag.
if ( $Config->{$Name}->{Mandatory} ) {
$Backends{$Name} = $Config->{$Name}->{Mandatory};
}
}
# set order of plugins
my $Key = $UserSettingsKey . 'Position';
my @Order;
my $Value = $Self->{$Key};
if ($Value) {
@Order = split /;/, $Value;
# only use active backends
@Order = grep { $Config->{$_} } @Order;
}
if ( !@Order ) {
for my $Name ( sort keys %Backends ) {
push @Order, $Name;
}
}
# add not ordered plugins (e. g. new active)
NAME:
for my $Name ( sort keys %Backends ) {
my $Included = 0;
ITEM:
for my $Item (@Order) {
next ITEM if $Item ne $Name;
$Included = 1;
}
next NAME if $Included;
push @Order, $Name;
}
# get default columns
my $Columns = $Self->{Config}->{DefaultColumns} || $ConfigObject->Get('DefaultOverviewColumns') || {};
# try every backend to load and execute it
my @ContainerNames;
NAME:
for my $Name (@Order) {
# get element data
my %Element = $Self->_Element(
Name => $Name,
Configs => $Config,
Backends => \%Backends,
);
next NAME if !%Element;
# NameForm (to support IE, is not working with "-" in form names)
my $NameForm = $Name;
$NameForm =~ s{-}{}g;
my %JSData = (
Name => $Name,
NameForm => $NameForm,
);
push @ContainerNames, \%JSData;
# rendering
$LayoutObject->Block(
Name => $Element{Config}->{Block},
Data => {
%{ $Element{Config} },
Name => $Name,
NameForm => $NameForm,
Content => ${ $Element{Content} },
CustomerID => $Self->{CustomerID} || '',
CustomerUserID => $Self->{CustomerUserID} || '',
},
);
# show refresh link if refreshing is available
if ( $Element{Config}->{CanRefresh} ) {
my $NameHTML = $Name;
$NameHTML =~ s{-}{_}xmsg;
# send data to JS
$LayoutObject->AddJSData(
Key => 'CanRefresh-' . $Name,
Value => {
Name => $Name,
NameHTML => $NameHTML,
}
);
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'Refresh',
Data => {
%{ $Element{Config} },
Name => $Name,
NameHTML => $NameHTML,
},
);
}
# Do not show the delete link if the widget is mandatory.
if ( !$Config->{$Name}->{Mandatory} ) {
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'Remove',
Data => {
%{ $Element{Config} },
Name => $Name,
CustomerID => $Self->{CustomerID} || '',
CustomerUserID => $Self->{CustomerUserID} || '',
},
);
}
# if column is not a default column, add it for translation
for my $Column ( sort keys %{ $Element{Config}->{DefaultColumns} } ) {
if ( !defined $Columns->{$Column} ) {
$Columns->{$Column} = $Element{Config}->{DefaultColumns}->{$Column};
}
}
# show settings link if preferences are available
if ( $Element{Preferences} && @{ $Element{Preferences} } ) {
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'Preferences',
Data => {
%{ $Element{Config} },
Name => $Name,
NameForm => $NameForm,
},
);
PARAM:
for my $Param ( @{ $Element{Preferences} } ) {
# special parameters are added, which do not have a tt block,
# because the displayed fields are added with the output filter,
# so there is no need to call any block here
next PARAM if !$Param->{Block};
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'PreferencesItem',
Data => {
%{ $Element{Config} },
Name => $Name,
NameForm => $NameForm,
},
);
if ( $Param->{Block} eq 'Option' ) {
$Param->{Option} = $LayoutObject->BuildSelection(
Data => $Param->{Data},
Name => $Param->{Name},
SelectedID => $Param->{SelectedID},
Translation => $Param->{Translation},
Class => 'Modernize',
);
}
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'PreferencesItem' . $Param->{Block},
Data => {
%{ $Element{Config} },
%{$Param},
Data => $Self->{ $Param->{Name} },
NamePref => $Param->{Name},
Name => $Name,
NameForm => $NameForm,
},
);
}
}
# more link
if ( $Element{Config}->{Link} ) {
$LayoutObject->Block(
Name => $Element{Config}->{Block} . 'More',
Data => {
%{ $Element{Config} },
},
);
}
}
# send data to JS
$LayoutObject->AddJSData(
Key => 'ContainerNames',
Value => \@ContainerNames,
);
# build main menu
my $MainMenuConfig = $ConfigObject->Get($MainMenuConfigKey);
if ( IsHashRefWithData($MainMenuConfig) ) {
$LayoutObject->Block( Name => 'MainMenu' );
for my $MainMenuItem ( sort keys %{$MainMenuConfig} ) {
$LayoutObject->Block(
Name => 'MainMenuItem',
Data => {
%{ $MainMenuConfig->{$MainMenuItem} },
CustomerID => $Self->{CustomerID},
CustomerUserID => $Self->{CustomerUserID},
},
);
}
}
# add translations for the allocation lists for regular columns
if ( $Columns && IsHashRefWithData($Columns) ) {
COLUMN:
for my $Column ( sort keys %{$Columns} ) {
# dynamic fields will be translated in the next block
next COLUMN if $Column =~ m{ \A DynamicField_ }xms;
my $TranslatedWord = $Column;
if ( $Column eq 'EscalationTime' ) {
$TranslatedWord = Translatable('Service Time');
}
elsif ( $Column eq 'EscalationResponseTime' ) {
$TranslatedWord = Translatable('First Response Time');
}
elsif ( $Column eq 'EscalationSolutionTime' ) {
$TranslatedWord = Translatable('Solution Time');
}
elsif ( $Column eq 'EscalationUpdateTime' ) {
$TranslatedWord = Translatable('Update Time');
}
elsif ( $Column eq 'PendingTime' ) {
$TranslatedWord = Translatable('Pending till');
}
elsif ( $Column eq 'CustomerCompanyName' ) {
$TranslatedWord = Translatable('Customer Name');
}
elsif ( $Column eq 'CustomerID' ) {
$TranslatedWord = Translatable('Customer ID');
}
elsif ( $Column eq 'CustomerName' ) {
$TranslatedWord = Translatable('Customer User Name');
}
elsif ( $Column eq 'CustomerUserID' ) {
$TranslatedWord = Translatable('Customer User ID');
}
# send data to JS
$LayoutObject->AddJSData(
Key => 'Column' . $Column,
Value => $LayoutObject->{LanguageObject}->Translate($TranslatedWord),
);
}
}
# add translations for the allocation lists for dynamic field columns
my $ColumnsDynamicField = $DynamicFieldObject->DynamicFieldListGet(
Valid => 0,
ObjectType => ['Ticket'],
);
if ( $ColumnsDynamicField && IsArrayRefWithData($ColumnsDynamicField) ) {
my $Counter = 0;
DYNAMICFIELD:
for my $DynamicField ( sort @{$ColumnsDynamicField} ) {
next DYNAMICFIELD if !$DynamicField;
$Counter++;
# send data to JS
$LayoutObject->AddJSData(
Key => 'ColumnDynamicField_' . $DynamicField->{Name},
Value => $LayoutObject->{LanguageObject}->Translate( $DynamicField->{Label} ),
);
}
}
my $Output = $LayoutObject->Header();
$Output .= $LayoutObject->NavigationBar();
$Output .= $LayoutObject->Output(
TemplateFile => $Self->{Action},
Data => \%Param
);
$Output .= $LayoutObject->Footer();
return $Output;
}
sub _Element {
my ( $Self, %Param ) = @_;
my $Name = $Param{Name};
my $Configs = $Param{Configs};
my $Backends = $Param{Backends};
my $SortBy = $Param{SortBy};
my $OrderBy = $Param{OrderBy};
my $ColumnFilter = $Param{ColumnFilter};
my $GetColumnFilter = $Param{GetColumnFilter};
my $GetColumnFilterSelect = $Param{GetColumnFilterSelect};
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
# check permissions
if ( $Configs->{$Name}->{Group} ) {
my $PermissionOK = 0;
my @Groups = split /;/, $Configs->{$Name}->{Group};
GROUP:
for my $Group (@Groups) {
my $HasPermission = $GroupObject->PermissionCheck(
UserID => $Self->{UserID},
GroupName => $Group,
Type => 'ro',
);
if ($HasPermission) {
$PermissionOK = 1;
last GROUP;
}
}
return if !$PermissionOK;
}
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# load backends
my $Module = $Configs->{$Name}->{Module};
return if !$Kernel::OM->Get('Kernel::System::Main')->Require($Module);
my $Object = $Module->new(
%{$Self},
Config => $Configs->{$Name},
Name => $Name,
CustomerID => $Self->{CustomerID} || '',
CustomerUserID => $Self->{CustomerUserID} || '',
SortBy => $SortBy,
OrderBy => $OrderBy,
ColumnFilter => $ColumnFilter,
GetColumnFilter => $GetColumnFilter,
GetColumnFilterSelect => $GetColumnFilterSelect,
);
# get module config
my %Config = $Object->Config();
# Perform the actual data fetching and computation on the slave db, if configured
local $Kernel::System::DB::UseSlaveDB = 1;
# get module preferences
my @Preferences = $Object->Preferences();
return @Preferences if $Param{PreferencesOnly};
# Perform the actual data fetching and computation on the slave db, if configured
local $Kernel::System::DB::UseSlaveDB = 1;
if ( $Param{FilterContentOnly} ) {
my $FilterContent = $Object->FilterContent(
FilterColumn => $Param{FilterColumn},
Config => $Configs->{$Name},
Name => $Name,
CustomerID => $Self->{CustomerID} || '',
CustomerUserID => $Self->{CustomerUserID} || '',
);
return $FilterContent;
}
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# add backend to settings selection
if ($Backends) {
my $Checked = '';
if ( $Backends->{$Name} || $Configs->{$Name}->{Mandatory} ) {
$Checked = 'checked="checked"';
}
# Check whether the widget is forcibly displayed.
# Mandatory widgets are displayed as read-only.
my $Readonly = '';
if ( $Configs->{$Name}->{Mandatory} ) {
$Readonly = 'disabled="disabled"';
}
$LayoutObject->Block(
Name => 'ContentSettings',
Data => {
%Config,
Name => $Name,
Checked => $Checked,
Readonly => $Readonly,
},
);
return if !$Backends->{$Name};
}
# check backends cache (html page cache)
my $Content;
my $CacheKey = $Config{CacheKey};
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
if ( !$CacheKey ) {
$CacheKey = $Name . '-'
. ( $Self->{CustomerID} || '' ) . '-'
. ( $Self->{CustomerUserID} || '' ) . '-'
. $LayoutObject->{UserLanguage};
}
if ( $Config{CacheTTL} ) {
$Content = $CacheObject->Get(
Type => 'Dashboard',
Key => $CacheKey,
);
}
# execute backends
my $CacheUsed = 1;
if ( !defined $Content || $SortBy ) {
$CacheUsed = 0;
$Content = $Object->Run(
AJAX => $Param{AJAX},
CustomerID => $Self->{CustomerID} || '',
CustomerUserID => $Self->{CustomerUserID} || '',
);
}
# check if content should be shown
return if !$Content;
# set cache (html page cache)
if ( !$CacheUsed && $Config{CacheTTL} ) {
$CacheObject->Set(
Type => 'Dashboard',
Key => $CacheKey,
Value => $Content,
TTL => $Config{CacheTTL} * 60,
);
}
# return result
return (
Content => \$Content,
Config => \%Config,
Preferences => \@Preferences,
);
}
1;