Skip to content

Commit

Permalink
Support to update maps of a lifecycle via JSON on Advanced page
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnavy committed Feb 6, 2024
1 parent 7292690 commit 3679823
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 4 deletions.
11 changes: 9 additions & 2 deletions lib/RT/Lifecycle.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1005,27 +1005,34 @@ sub UpdateLifecycle {
return (1, $CurrentUser->loc("Lifecycle [_1] updated", $name));
}

=head2 UpdateMaps( CurrentUser => undef, Maps => undef )
=head2 UpdateMaps( CurrentUser => undef, Maps => undef, Name => undef )
Update lifecycle maps.
Returns (STATUS, MESSAGE). STATUS is true if succeeded, otherwise false.
Note that the Maps in argument will be merged into existing maps. To delete
all existing items for a lifecycle before merging, pass its Name.
=cut

sub UpdateMaps {
my $class = shift;
my %args = (
CurrentUser => undef,
Maps => undef,
Name => undef,
@_,
);

my $CurrentUser = $args{CurrentUser};
my $lifecycles = RT->Config->Get('Lifecycles');

my $all_maps = $lifecycles->{__maps__} || {};
my @keep_keys = grep { $args{Name} && !/^\Q$args{Name}\E -> | -> \Q$args{Name}\E$/ } keys %$all_maps;

%{ $lifecycles->{__maps__} } = (
%{ $lifecycles->{__maps__} || {} },
map( { $_ => $all_maps->{$_} } @keep_keys ),
%{ $args{Maps} },
);

Expand Down
82 changes: 80 additions & 2 deletions share/html/Admin/Lifecycles/Advanced.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@
</span>
</div>

<form action="<%RT->Config->Get('WebPath')%>/Admin/Lifecycles/Advanced.html" name="ModifyLifecycleAdvanced" method="post" enctype="multipart/form-data" class="mx-auto max-width-sm">

<form action="<%RT->Config->Get('WebPath')%>/Admin/Lifecycles/Advanced.html" name="ModifyLifecycleAdvanced" method="post" enctype="multipart/form-data" class="mx-auto max-width-lg">
<input type="hidden" class="hidden" name="Name" value="<% $LifecycleObj->Name %>" />
<input type="hidden" class="hidden" name="Type" value="<% $LifecycleObj->Type %>" />

<&| /Widgets/TitleBox, title => loc('Basics'), content_class => 'mx-auto width-sm' &>
<div class="form-row">
<span class="col-12">
<textarea class="form-control" rows="30" name="Config"><% $Config |n %></textarea>
Expand All @@ -83,8 +84,40 @@
<& /Elements/Submit, Label => loc('Delete'), Name => 'Delete' &>
</div>
</div>
</&>
</form>



<form action="<%RT->Config->Get('WebPath')%>/Admin/Lifecycles/Advanced.html" name="ModifyLifecycleAdvancedMappings" method="post" enctype="multipart/form-data" class="mx-auto max-width-lg">
<input type="hidden" class="hidden" name="Name" value="<% $LifecycleObj->Name %>" />
<input type="hidden" class="hidden" name="Type" value="<% $LifecycleObj->Type %>" />
<&| /Widgets/TitleBox, title => loc('Mappings'), content_class => 'mx-auto width-sm' &>

<div class="form-row">
<span class="col-12">
<textarea class="form-control" rows="30" name="Maps"><% $Maps |n %></textarea>
</span>
</div>

<div class="form-row invalid-json hidden">
<div class="col-12">
<div class="alert alert-danger mb-0"><&|/l&>Invalid JSON</&></div>
</div>
</div>

<div class="form-row">
<div class="col-6 d-flex">
<& /Elements/Submit, Label => loc('Validate Mappings'), Name => 'ValidateMaps' &>
</div>
<div class="col-6">
<& /Elements/Submit, Label => loc('Save Mappings'), Name => 'UpdateMaps' &>
</div>
</div>
</&>
</form>


<%INIT>
my ($title, @results);
my $LifecycleObj = RT::Lifecycle->new();
Expand All @@ -100,6 +133,13 @@
push @results, loc("The graphical lifecycle builder is not currently supported on IE 11. You can update the lifecycle configuration using the Advanced tab or access the lifecycle editor in a supported browser.");
}

if ( !defined $Maps && ( my $all_maps = RT->Config->Get('Lifecycles')->{__maps__} ) ) {
for my $item ( grep {/^\Q$Name\E -> | -> \Q$Name\E$/} keys %$all_maps ) {
$Maps->{$item} = $all_maps->{$item};
}
$Maps = JSON::to_json( $Maps || {}, { canonical => 1, pretty => 1 } );
}

my $redirect_to ='/Admin/Lifecycles/Advanced.html';
my %redirect_args;

Expand Down Expand Up @@ -157,6 +197,41 @@
);
}
}
elsif ( $ValidateMaps || $UpdateMaps ) {
my $maps = JSON::from_json($Maps || '{}');

my ( $valid, @warnings )
= $LifecycleObj->ValidateLifecycleMaps( Maps => $maps, CurrentUser => $session{CurrentUser} );

my $updated;
if ($valid) {
if ($ValidateMaps) {
push @results, loc('Mappings is valid');
}
else {
# Maps will be merged into existing value, here we remove existing values so admins can delete items

( $updated, my $msg ) = RT::Lifecycle->UpdateMaps(
CurrentUser => $session{CurrentUser},
Maps => $maps,
Name => $Name,
);
push @results, $msg;
}

}
else {
push @results, @warnings;
}

%redirect_args = (
Name => $Name,
Type => $Type,

# Get the latest canonicalized data if updated successfully
$updated ? () : ( Maps => $Maps ),
);
}

MaybeRedirectForResults(
Actions => \@results,
Expand All @@ -172,4 +247,7 @@
$Validate => undef
$Update => undef
$Delete => undef
$ValidateMaps => undef
$UpdateMaps => undef
$Maps => undef
</%ARGS>
56 changes: 56 additions & 0 deletions t/web/lifecycle_mappings.t
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,62 @@ diag "Test updating sales-engineering mappings";
);
}

diag "Test advanced mappings";
{
$m->get_ok( $url . '/Admin/Lifecycles/Advanced.html?Type=ticket&Name=sales-engineering' );
my $form = $m->form_name('ModifyLifecycleAdvancedMappings');

require JSON;
my $maps = JSON::from_json( $form->value('Maps') );
is_deeply(
$maps,
{
'sales-engineering -> default' => {
'rejected' => 'rejected',
'resolved' => 'resolved',
'deleted' => 'deleted',
'engineering' => 'open',
'stalled' => 'stalled',
'sales' => 'new'
}
},
'Correct current value'
);

$maps->{'default -> sales-engineering'} = { 'new' => 'sales', };

$m->submit_form_ok(
{
fields => {
Maps => JSON::to_json($maps),
Name => "sales-engineering",
Type => "ticket",
},
button => 'UpdateMaps',
},
'Update maps'
);
$m->content_contains('Lifecycle mappings updated');
$form = $m->form_name('ModifyLifecycleAdvancedMappings');
is_deeply( $maps, JSON::from_json( $form->value('Maps') ), 'Correct updated value' );

$m->submit_form_ok(
{
fields => {
Maps => '',
Name => "sales-engineering",
Type => "ticket",
},
button => 'UpdateMaps',
},
'Clear maps'
);
$m->content_contains('Lifecycle mappings updated');
$form = $m->form_name('ModifyLifecycleAdvancedMappings');
$form->value( "Maps", "{}", 'Maps got cleared' );
}


sub reload_lifecycle {
# to get rid of the warning of:
# you're changing config option in a test file when server is active
Expand Down

0 comments on commit 3679823

Please sign in to comment.