File Coverage

lib/CallBackery/GuiPlugin/AbstractAction.pm
Criterion Covered Total %
statement 49 58 84.4
branch 9 16 56.2
condition 2 9 22.2
subroutine 9 9 100.0
pod 1 1 100.0
total 70 93 75.2


line stmt bran cond sub pod time code
1             package CallBackery::GuiPlugin::AbstractAction;
2 1     1   664 use Carp qw(carp croak);
  1         1  
  1         77  
3 1     1   7 use CallBackery::Translate qw(trm);
  1         2  
  1         42  
4 1     1   6 use CallBackery::Exception qw(mkerror);
  1         2  
  1         32  
5 1     1   5 use Mojo::Promise;
  1         2  
  1         6  
6 1     1   46 use Mojo::JSON qw(encode_json);
  1         2  
  1         53  
7 1     1   18 use Mojo::Util qw(dumper);
  1         3  
  1         56  
8              
9             =head1 NAME
10              
11             CallBackery::GuiPlugin::AbstractAction - action form base class
12              
13             =head1 SYNOPSIS
14              
15             use Mojo::Base 'CallBackery::GuiPlugin::AbstractAction';
16              
17             =head1 DESCRIPTION
18              
19             The base class for gui forms with actions.
20              
21             =cut
22              
23 1     1   7 use Mojo::Base 'CallBackery::GuiPlugin::Abstract';
  1         2  
  1         8  
24              
25             =head1 ATTRIBUTES
26              
27             The attributes of the L class plus:
28              
29             =head2 screenCfg
30              
31             Returns a configuration structure for the form. The output from this
32             method is fed to the callbackery.ui.form.Auto object to build the
33             Qooxdoo form.
34              
35             =cut
36              
37             has screenCfg => sub {
38             my $self = shift;
39             $self->__fixActionCfg;
40             return {
41             type => 'action',
42             options => $self->screenOpts,
43             action => $self->actionCfg,
44             }
45             };
46              
47             =head2 screenOpts
48              
49             Returns a hash of options for the screen Options
50              
51             =cut
52              
53             has screenOpts => sub {
54             {
55             }
56             };
57              
58             =head2 actionCfg
59              
60             Returns a list of action buttons to place at the top of the form.
61              
62             =cut
63              
64             has actionCfg => sub {
65             [];
66             };
67              
68             =head2 actionCfgMap
69              
70             Lookup table for action plugins.
71              
72             NOTE: Unique keys are not checked for popup plugins as they don't have
73             action handlers.
74             This allows multiple popup actions using the same plugin instance.
75             In this case an additional cfg parameter C must be
76             used to make the QoxdooObjectIds unique used from frontend testing.
77              
78             =cut
79              
80             has actionCfgMap => sub {
81             my $self = shift;
82             my %map;
83             for my $row (@{$self->actionCfg}){
84             next unless $row->{action} =~ /^(submit|upload|download|display|autoSubmit|save)/;
85             next unless $row->{key};
86             my $key = $row->{key};
87             die mkerror(4646, "Duplicate action key $key") if exists $map{$key};
88             $map{$key} = $row;
89             }
90             return \%map;
91             };
92              
93              
94             =head1 METHODS
95              
96             All the methods of L plus:
97              
98             =cut
99              
100             =head2 massageConfig
101              
102             Function to integrate the plugin configuration recursively into the main config
103             hash.
104              
105             =cut
106              
107             sub massageConfig {
108 4     4 1 8 my $self = shift;
109 4         8 my $cfg = shift;
110 4         19 $self->__fixActionCfg;
111 4         11 my $actionCfg = $self->actionCfg;
112 4         22 for my $button (@$actionCfg){
113 6 100       32 if ($button->{action} =~ /popup|wizzard/) {
114 2         7 my $name = $button->{name};
115             # allow same plugin multiple times
116 2         5 $button->{name} = $name;
117 2 50       8 if ($cfg->{PLUGIN}{prototype}{$name}) {
118 0         0 my $newCfg = encode_json($button->{backend});
119 0         0 my $oldCfg = encode_json($cfg->{PLUGIN}{prototype}{$name}{backend});
120 0 0 0     0 if ($oldCfg ne 'null' and $newCfg ne $oldCfg) {
121 0         0 $self->log->warn("oldCfg=" . dumper $oldCfg);
122 0         0 $self->log->warn("newCfg=", dumper $newCfg);
123 0         0 die "Not unique plugin instance name $name not allowed as backend config is different\n";
124             }
125             }
126             my $popup = $cfg->{PLUGIN}{prototype}{$name}
127 2         6 = $self->app->config->loadAndNewPlugin($button->{backend}{plugin});
128 2         35 $popup->config($button->{backend}{config});
129 2         20 $popup->name($name);
130 2         15 $popup->app($self->app);
131 2         40 $popup->massageConfig($cfg);
132             }
133             }
134 4         11 return;
135             }
136              
137             =head2 __fixActionCfg
138              
139             make sure actionCfg buttons only have keys and no names
140             add properly constructed name properties
141              
142             =cut
143              
144             sub __fixActionCfg {
145 4     4   8 my $self = shift;
146 4 50       14 return $self if $self->{__action_cfg_fixed};
147 4         12 my $name = $self->name;
148 4         23 my $pkg = ref $self;
149 4         7 for my $action (@{$self->actionCfg}) {
  4         13  
150             next if $action->{action} eq 'separator'
151             or $action->{action} eq 'refresh'
152 6 50 33     39 or $action->{action} eq 'logout';
      33        
153 6 50       16 if ($action->{name}) {
154 0         0 $self->log->warn(
155             $pkg . " action should not have a name attribute:"
156             . " name=$action->{name}"
157             );
158             }
159 6 50       13 if (not $action->{key}) {
160 0         0 $self->log->warn(
161             $pkg . " action should have a key attribute,"
162             . " created a key from name=$action->{name} instead"
163             );
164 0         0 $action->{key} = $action->{name};
165             }
166             # popups and wizzards do need a name internally
167 6 100       36 if ($action->{action} =~ /popup|wizzard/) {
168 2         10 $action->{name} = "${name}_$action->{key}";
169             }
170             }
171 4         12 $self->{__action_cfg_fixed} = 1;
172 4         9 return $self;
173             }
174              
175              
176             1;
177             __END__