Skip to content

Commit

Permalink
Issue #2298: Activate AJAX Update for reference fields and make lense…
Browse files Browse the repository at this point in the history
…s respect the reference object of the edit mask if applicable.
  • Loading branch information
Sven committed Jul 27, 2023
1 parent 411fffa commit 6268125
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 62 deletions.
109 changes: 75 additions & 34 deletions Kernel/Modules/AdminDynamicFieldLens.pm
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,13 @@ sub new {
ConfigParamName => 'ReferenceDF',
Label => Translatable('The referenced DF'),
Explanation => Translatable('Select the DF that references an object'),
InputType => 'Integer',
InputType => 'Text',
},
{
ConfigParamName => 'AttributeDF',
Label => Translatable('The attribute DF of the referenced object'),
Explanation => Translatable('Select the attribute DF that references an object'),
InputType => 'Integer',
},
{
ConfigParamName => 'MultiValue',
Label => Translatable('Multiple Values'),
Explanation => Translatable('Activate this option to allow multiple values for this field.'),
InputType => 'Selection',
SelectionData => \%MultiValueSelectionData,
InputType => 'Text',
},
],
};
Expand Down Expand Up @@ -239,16 +232,6 @@ sub _AddAction {
);
}

# return to add screen if errors
if (%Errors) {
return $Self->_ShowScreen(
%Param,
%Errors,
%GetParam,
Mode => 'Add',
);
}

# set specific config
my %FieldConfig = (
Tooltip => $GetParam{Tooltip},
Expand All @@ -262,6 +245,34 @@ sub _AddAction {
}
}

# store the name for easier ajax evaluation
$FieldConfig{ReferenceDFName} = 'DynamicField_' . $FieldConfig{ReferenceDF};

for my $ConfigDF ( qw/ReferenceDF AttributeDF/ ) {
my $DynamicField = $DynamicFieldObject->DynamicFieldGet(
Name => $FieldConfig{$ConfigDF},
);

# TODO: Show error message
if ( !$DynamicField ) {
$Errors{ $ConfigDF . 'ServerError' } = 'ServerError';
$Errors{ $ConfigDF . 'NameServerErrorMessage' } = Translatable('Not a valid dynamic field.');
}

# store the ID
$FieldConfig{$ConfigDF} = $DynamicField->{ID};
}

# return to add screen if errors
if (%Errors) {
return $Self->_ShowScreen(
%Param,
%Errors,
%GetParam,
Mode => 'Add',
);
}

# create a new field
my $FieldID = $DynamicFieldObject->DynamicFieldAdd(
Name => $GetParam{Name},
Expand All @@ -288,8 +299,9 @@ sub _AddAction {
sub _Change {
my ( $Self, %Param ) = @_;

my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');

my %GetParam;
for my $Needed (qw(ObjectType FieldType)) {
Expand All @@ -314,7 +326,7 @@ sub _Change {
}

# get dynamic field data
my $DynamicFieldData = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
my $DynamicFieldData = $DynamicFieldObject->DynamicFieldGet(
ID => $FieldID,
);

Expand All @@ -333,6 +345,17 @@ sub _Change {
%Config = $DynamicFieldData->{Config}->%*;
}

# show dynamic field names instead of IDs
for my $ConfigDF ( qw/ReferenceDF AttributeDF/ ) {
my $DynamicField = $DynamicFieldObject->DynamicFieldGet(
ID => $Config{$ConfigDF},
);

# translate to name
$Config{$ConfigDF} = $DynamicField->{Name};
}


return $Self->_ShowScreen(
%Param,
%GetParam,
Expand Down Expand Up @@ -494,17 +517,6 @@ sub _ChangeAction {
}
}

# return to change screen if errors
if (%Errors) {
return $Self->_ShowScreen(
%Param,
%Errors,
%GetParam,
ID => $FieldID,
Mode => 'Change',
);
}

# set specific config
my %FieldConfig = (
Tooltip => $GetParam{Tooltip},
Expand All @@ -518,6 +530,35 @@ sub _ChangeAction {
}
}

# store the name for easier ajax evaluation
$FieldConfig{ReferenceDFName} = 'DynamicField_' . $FieldConfig{ReferenceDF};

for my $ConfigDF ( qw/ReferenceDF AttributeDF/ ) {
my $DynamicField = $DynamicFieldObject->DynamicFieldGet(
Name => $FieldConfig{$ConfigDF},
);

# TODO: Show error message
if ( !$DynamicField ) {
$Errors{ $ConfigDF . 'ServerError' } = 'ServerError';
$Errors{ $ConfigDF . 'NameServerErrorMessage' } = Translatable('Not a valid dynamic field.');
}

# store the ID
$FieldConfig{$ConfigDF} = $DynamicField->{ID};
}

# return to change screen if errors
if (%Errors) {
return $Self->_ShowScreen(
%Param,
%Errors,
%GetParam,
ID => $FieldID,
Mode => 'Change',
);
}

# update dynamic field (FieldType and ObjectType cannot be changed; use old values)
my $UpdateSuccess = $DynamicFieldObject->DynamicFieldUpdate(
ID => $FieldID,
Expand Down Expand Up @@ -675,7 +716,7 @@ sub _ShowScreen {
my $Name = $Setting->{ConfigParamName};

my $FieldStrg;
if ( $Setting->{InputType} eq 'Integer' ) {
if ( $Setting->{InputType} eq 'Text' ) {

# TODO: proper HTML builder
$FieldStrg = sprintf
Expand Down
133 changes: 107 additions & 26 deletions Kernel/System/DynamicField/Driver/Lens.pm
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,11 @@ sub ValueGet {
my $ReferencedObjectID = $Self->_GetReferencedObjectID(
ObjectID => $Param{ObjectID},
LensDynamicFieldConfig => $LensDFConfig,
EditFieldValue => $Param{UseReferenceEditField},
);

return if !$ReferencedObjectID;

my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $LensDFConfig,
);
Expand All @@ -111,11 +114,16 @@ sub ValueSet {

my $LensDFConfig = $Param{DynamicFieldConfig};

# as we are already saving we trust, that the reference edit field has been validated
my $ReferencedObjectID = $Self->_GetReferencedObjectID(
ObjectID => $Param{ObjectID},
LensDynamicFieldConfig => $LensDFConfig,
EditFieldValue => 1,
);

# TODO: Do we want to log this?
return if !$ReferencedObjectID;

my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $LensDFConfig,
);
Expand All @@ -135,9 +143,14 @@ sub ValueSet {
sub ValueValidate {
my ( $Self, %Param ) = @_;

# there is nothing to validate, as all is in the config
# TODO: delegate to the referenced field
return 1;
my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->ValueValidate(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

sub SearchSQLGet {
Expand Down Expand Up @@ -180,22 +193,16 @@ sub EditFieldRender {
LensDynamicFieldConfig => $LensDFConfig,
);

# Call EditLabelRender on the common Driver.
# The edit field should be rendered like the attribute of the referenced object,
# But the name should be that of the Lens dynamic field.
$AttributeDFConfig->{Name} = $LensDFConfig->{Name};
# But name and Label should be that of the Lens dynamic field.
$AttributeDFConfig->{Name} = $LensDFConfig->{Name};
$AttributeDFConfig->{Label} = $LensDFConfig->{Label};
my $AttributeFieldHTML = $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->EditFieldRender(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);

return unless $AttributeFieldHTML;

# But show the label of the Lens dynamic field
return {
Field => $AttributeFieldHTML->{Field},
Label => $LensDFConfig->{Label},
};
return $AttributeFieldHTML;
}

sub EditFieldValueGet {
Expand Down Expand Up @@ -500,7 +507,73 @@ sub HistoricalValuesGet {
sub ValueLookup {
my ( $Self, %Param ) = @_;

return $Param{Key} // '';
my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->ValueLookup(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

sub ValueIsDifferent {
my ( $Self, %Param ) = @_;

my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->ValueIsDifferent(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

sub HasBehavior {
my ( $Self, %Param ) = @_;

# TODO: Think about additional behaviors we can just adopt from the attribute field
# for certain behaviors instead use the attribute field behaviors
if ( grep { $Param{Behavior} } qw/IsACLReducible/ ) {
my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->HasBehavior(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

# return success if the dynamic field has the expected behavior
return IsPositiveInteger( $Self->{Behaviors}->{ $Param{Behavior} } );
}

sub PossibleValuesGet {
my ( $Self, %Param ) = @_;

my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->PossibleValuesGet(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

sub BuildSelectionDataGet {
my ( $Self, %Param ) = @_;

my $AttributeDFConfig = $Self->_GetAttributeDFConfig(
LensDynamicFieldConfig => $Param{DynamicFieldConfig},
);

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->BuildSelectionDataGet(
%Param,
DynamicFieldConfig => $AttributeDFConfig,
);
}

=head1 internal methods
Expand All @@ -513,15 +586,15 @@ A dynamic field configuration that can be used as a delegate.
=cut

#TODO: in CI definitions store the definition id or df configs in the lens config and use this one instead of the current df configs
sub _GetReferenceDFConfig {
my ( $Self, %Param ) = @_;

my $LensDFConfig = $Param{LensDynamicFieldConfig};
my $ReferenceDFID = $LensDFConfig->{Config}->{ReferenceDF};

return $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
ID => $ReferenceDFID,
$Self->{ReferenceDFCache}{ $Param{LensDynamicFieldConfig}{ID} } //= $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
ID => $Param{LensDynamicFieldConfig}{Config}{ReferenceDF},
);

return $Self->{ReferenceDFCache}{ $Param{LensDynamicFieldConfig}{ID} };
}

=head2 _GetAttributeDFConfig()
Expand All @@ -533,12 +606,11 @@ A dynamic field configuration that can be used as a delegate.
sub _GetAttributeDFConfig {
my ( $Self, %Param ) = @_;

my $LensDFConfig = $Param{LensDynamicFieldConfig};
my $AttributeDFID = $LensDFConfig->{Config}->{AttributeDF};

return $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
ID => $AttributeDFID,
$Self->{AttributeDFCache}{ $Param{LensDynamicFieldConfig}{ID} } //= $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldGet(
ID => $Param{LensDynamicFieldConfig}{Config}{AttributeDF},
);

return $Self->{AttributeDFCache}{ $Param{LensDynamicFieldConfig}{ID} };
}

=head2 _GetReferencedObjectID()
Expand All @@ -552,16 +624,25 @@ sub _GetReferencedObjectID {

# extract params
my $LensDFConfig = $Param{LensDynamicFieldConfig};
my $ObjectID = $Param{ObjectID};

# Get the dynamic field config for the referenced object
my $ReferenceDFConfig = $Self->_GetReferenceDFConfig(
LensDynamicFieldConfig => $LensDFConfig,
);

if ( $Param{EditFieldValue} ) {
return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->EditFieldValueGet(
DynamicFieldConfig => $ReferenceDFConfig,
ParamObject => $Kernel::OM->Get('Kernel::System::Web::Request'),
TransformDates => 0,
ForLens => 1,
);
}

return $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->ValueGet(
DynamicFieldConfig => $ReferenceDFConfig,
ObjectID => $ObjectID,
ObjectID => $Param{ObjectID},
ForLens => 1,
);
}

Expand Down
Loading

0 comments on commit 6268125

Please sign in to comment.