diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm index e67ec51fa2..75c3af7d92 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm @@ -7,6 +7,7 @@ use Data::HAL::Link qw(); use HTTP::Headers qw(); use HTTP::Status qw(:constants); use MooseX::ClassAttribute qw(class_has); +use Data::Dumper; use NGCP::Panel::Utils::DateTime; BEGIN { extends 'Catalyst::Controller::ActionRole'; } require Catalyst::ActionRole::ACL; @@ -227,12 +228,54 @@ sub POST :Allow { $item = $c->model('DB')->resultset('autoprov_devices')->create($resource); foreach my $range(@{ $linerange }) { unless(ref $range eq "HASH") { - use Data::Dumper; $c->log->error("all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, all must be hash"); return; } - $item->autoprov_device_line_ranges->create($range); + foreach my $elem(qw/can_private can_shared can_blf keys/) { + unless(exists $range->{$elem}) { + $c->log->error("missing mandatory attribute '$elem' in a linerange element"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, missing attribute '$elem'"); + return; + } + } + unless(ref $range->{keys} eq "ARRAY") { + $c->log->error("linerange.keys must be array"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid linerange.keys parameter, must be array"); + last; + } + $range->{num_lines} = @{ $range->{keys} }; # backward compatibility + my $keys = delete $range->{keys}; + + my $r = $item->autoprov_device_line_ranges->create($range); + my $i = 0; + foreach my $label(@{ $keys }) { + $label->{line_index} = $i++; + unless(ref $label eq "HASH") { + $c->log->error("all elements in linerange must be hashes, but this is " . ref $range . ": " . Dumper $range); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid range definition inside linerange parameter, all must be hash"); + return; + } + my $valid = [qw/x y line_index labelpos/]; + foreach my $elem(@{ $valid }) { + unless(exists $label->{$elem}) { + $c->log->error("missing mandatory attribute '$elem' in a linerange.keys element"); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid keys definition inside linerange.keys parameter, missing attribute '$elem'"); + return; + } + } + foreach my $k(keys %{ $label }) { + delete $label->{$k} unless $k ~~ $valid; + } + my $pos = [qw/top bottom left right/]; + unless($label->{labelpos} ~~ $pos) { + $c->log->error("invalid value '$$label{labelpos}' for attribute 'labelpos', must be one of " . (join ', ', @{ $pos })); + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid value '$$label{labelpos}' for attribute 'labelpos', must be one of " . (join ', ', @{ $pos })); + return; + } + $label->{position} = delete $label->{labelpos}; + $r->annotations->create($label); + } } } catch($e) { $c->log->error("failed to create device model: $e"); diff --git a/lib/NGCP/Panel/Form/Device/Model.pm b/lib/NGCP/Panel/Form/Device/Model.pm index 0ad37c8c54..3447f817d9 100644 --- a/lib/NGCP/Panel/Form/Device/Model.pm +++ b/lib/NGCP/Panel/Form/Device/Model.pm @@ -36,7 +36,7 @@ has_field 'model' => ( has_field 'front_image' => ( type => 'Upload', - required => 0, + required => 1, label => 'Front Image', max_size => '67108864', # 64MB ); @@ -98,7 +98,7 @@ has_field 'linerange' => ( wrapper_class => [qw/hfh-rep-block/], element_attr => { rel => ['tooltip'], - title => ['An array of line/key definitions for this device. Each element is a hash containing the keys name, num_lines (defining the number of lines/keys for this range), can_private, can_shared, can_blf.'], + title => ['An array of line/key definitions for this device. Each element is a hash containing the keys name, can_private, can_shared, can_blf and keys (which in turn is an array of hashes having x, y and labelpos allowing top, bottom, left right).'], }, ); @@ -156,9 +156,55 @@ has_field 'linerange.can_blf' => ( }, ); +has_field 'linerange.keys' => ( + type => 'Hidden', + label => 'Key Definition', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['The position of the keys on the front image. Attributes are x, y, labelpos (how the label for the key is displayed in the web interface, relative to the given coordinates; one of top, bottom, left, right).'], + }, +); +=pod +has_field 'linerange.keys' => ( + type => 'Repeatable', + label => 'Key Definition', + setup_for_js => 1, + do_wrapper => 1, + do_label => 1, + required => 1, + tags => { + controls_div => 1, + }, + wrapper_class => [qw/hfh-rep-block/], + element_attr => { + rel => ['tooltip'], + title => ['The position of the keys on the front image. Attributes are x, y, labelpos (how the label for the key is displayed in the web interface, relative to the given coordinates; one of top, bottom, left, right).'], + }, +); + +has_field 'linerange.keys.id' => ( + type => 'Hidden', +); + +has_field 'linerange.keys.rm' => ( + type => 'RmElement', + value => 'Remove Key', + order => 100, + element_class => [qw/btn btn-primary pull-right/], +); + +has_field 'linerange.keys_add' => ( + type => 'AddElement', + repeatable => 'linerange.keys', + value => 'Add another Key Definition', + element_class => [qw/btn btn-primary pull-right/], +); +=cut + has_field 'linerange.rm' => ( type => 'RmElement', - value => 'Remove', + value => 'Remove Range', order => 100, element_class => [qw/btn btn-primary pull-right/], );