diff --git a/lib/NGCP/Panel/Controller/Device.pm b/lib/NGCP/Panel/Controller/Device.pm index 27e5dcb0c6..7fedb8f0de 100644 --- a/lib/NGCP/Panel/Controller/Device.pm +++ b/lib/NGCP/Panel/Controller/Device.pm @@ -214,7 +214,15 @@ sub devmod_create :Chained('base') :PathPart('model/create') :Args(0) :Does(ACL) foreach my $range(@{ $linerange }) { delete $range->{id}; - $devmod->autoprov_device_line_ranges->create($range); + $range->{num_lines} = @{ $range->{keys} }; # backward compatibility + my $keys = delete $range->{keys}; + my $r = $devmod->autoprov_device_line_ranges->create($range); + my $i = 0; + foreach my $label(@{ $keys }) { + $label->{line_index} = $i++; + $label->{position} = delete $label->{labelpos}; + $r->annotations->create($label); + } } delete $c->session->{created_objects}->{reseller}; @@ -285,7 +293,13 @@ sub devmod_edit :Chained('devmod_base') :PathPart('edit') :Args(0) :Does(ACL) :A my $params = { $c->stash->{devmod}->get_inflated_columns }; $params->{linerange} = []; foreach my $range($c->stash->{devmod}->autoprov_device_line_ranges->all) { - push @{ $params->{linerange} }, { $range->get_inflated_columns }; + my $keys = []; + foreach my $key($range->annotations->all) { + push @{ $keys }, { x => $key->x, y => $key->y, labelpos => $key->position }; + } + my $r = { $range->get_inflated_columns }; + $r->{keys} = $keys; + push @{ $params->{linerange} }, $r; } $params->{reseller}{id} = delete $params->{reseller_id}; $params = $params->merge($c->session->{created_objects}); @@ -349,6 +363,8 @@ sub devmod_edit :Chained('devmod_base') :PathPart('edit') :Args(0) :Does(ACL) :A my $range_rs = $c->stash->{devmod}->autoprov_device_line_ranges; foreach my $range(@{ $linerange }) { next unless(defined $range); + my $keys = delete $range->{keys}; + $range->{num_lines} = @{ $keys }; # backward compatibility my $old_range; if(defined $range->{id}) { # should be an existing range, do update @@ -367,6 +383,15 @@ sub devmod_edit :Chained('devmod_base') :PathPart('edit') :Args(0) :Does(ACL) :A # new range $old_range = $range_rs->create($range); } + $old_range->annotations->delete; + my $i = 0; + foreach my $label(@{ $keys }) { + next unless(defined $label); + $label->{line_index} = $i++; + $label->{position} = delete $label->{labelpos}; + $old_range->annotations->create($label); + } + push @existing_range, $old_range->id; # mark as valid (delete others later) # delete field device line assignments with are out-of-range or use a diff --git a/lib/NGCP/Panel/Form/Device/Model.pm b/lib/NGCP/Panel/Form/Device/Model.pm index b360441b22..1168f32ae7 100644 --- a/lib/NGCP/Panel/Form/Device/Model.pm +++ b/lib/NGCP/Panel/Form/Device/Model.pm @@ -116,16 +116,6 @@ has_field 'linerange.name' => ( }, ); -has_field 'linerange.num_lines' => ( - type => 'PosInteger', - label => 'Number of Lines/Keys', - default => 4, - element_attr => { - rel => ['tooltip'], - title => ['The number of Lines/Keys in this range, indexed from 0 in the config template array phone.lineranges[].lines[]'], - }, -); - has_field 'linerange.can_private' => ( type => 'Boolean', label => 'Supports Private Line', @@ -165,7 +155,7 @@ has_field 'linerange.keys' => ( tags => { controls_div => 1, }, - wrapper_class => [qw/hfh-rep-block/], + wrapper_class => [qw/hfh-nested-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).'], @@ -225,7 +215,7 @@ has_field 'linerange.keys.rm' => ( has_field 'linerange.keys_add' => ( type => 'AddElement', repeatable => 'keys', - value => 'Add another Key Definition', + value => 'Add Key', element_class => [qw/btn btn-primary pull-right/], ); diff --git a/lib/NGCP/Panel/Render/RepeatableJs.pm b/lib/NGCP/Panel/Render/RepeatableJs.pm index 05d1d13fd1..7046fbc265 100644 --- a/lib/NGCP/Panel/Render/RepeatableJs.pm +++ b/lib/NGCP/Panel/Render/RepeatableJs.pm @@ -27,30 +27,52 @@ sub render_repeatable_js { var rep_index = $index_str; var rep_html = $html_str; var rep_level = $level_str; - \$('.add_element').click(function() { + \$('.add_element').click(on_add_element); + function on_add_element() { + console.log("on_add_element this=", \$(this)); // get the repeatable id var data_rep_id = \$(this).attr('data-rep-id'); + console.log("data_rep_id=", data_rep_id); + + var id_re = new RegExp('\.[0-9]+\.'); + var data_rep_id_0 = data_rep_id.replace(id_re, '.0.'); + console.log("data_rep_id_0=", data_rep_id_0); + + // create a regex out of index placeholder - var level = rep_level[data_rep_id] + var level = rep_level[data_rep_id_0] + console.log("level=", level); var re = new RegExp('\{index-' + level + '\}',"g"); // replace the placeholder in the html with the index var index = rep_index[data_rep_id]; - var html = rep_html[data_rep_id]; + if(index == undefined) index = 1; + console.log("index for " + data_rep_id + " is " + index); + var html = rep_html[data_rep_id_0]; + console.log("html=", html); + + var esc_rep_id = data_rep_id.replace(/[.]/g, '\\\\.'); + var esc_rep_id_0 = data_rep_id_0.replace(/[.]/g, '\\\\.'); + + id_re = new RegExp(esc_rep_id_0, "g"); + html = html.replace(id_re, data_rep_id); + console.log("html replaced=", html); + html = html.replace(re, index); // escape dots in element id - var esc_rep_id = data_rep_id.replace(/[.]/g, '\\\\.'); // append new element in the 'controls' div of the repeatable var rep_controls = \$('#' + esc_rep_id + ' > .controls'); rep_controls.append(html); // increment index of repeatable fields index++; rep_index[data_rep_id] = index; + console.log("rep index " + data_rep_id + "=", rep_index); + \$('.add_element').click(on_add_element); // initiate callback if there is a handler for that if(repeatadd_handler) { repeatadd_handler.onAdd(index-1); } - }); + } \$(document).on('click', '.rm_element', function() { var id = \$(this).attr('data-rep-elem-id'); diff --git a/share/static/css/main.css b/share/static/css/main.css index 259ae8682c..5aca96829b 100644 --- a/share/static/css/main.css +++ b/share/static/css/main.css @@ -98,6 +98,28 @@ div.ngcp-modal div.modal-body div.control-group.hfh-rep div.controls div.hfh-rep margin-left: 180px; } +div.hfh-nested-rep-block { + margin-bottom: 0px !important; +} +div.hfh-nested-rep-block div.controls div.hfh-repinst div.controls { + margin-left: 0px !important; +} +div.hfh-nested-rep-block div.controls div.hfh-repinst div.controls div.control-group { + display: inline-block !important; + margin-bottom: 0px !important; +} +div.hfh-nested-rep-block div.controls div.hfh-repinst div.controls div.control-group label { + text-align: left; + width: auto; + margin-right: 10px; +} +div.hfh-nested-rep-block div.controls div.hfh-repinst div.controls div.control-group div.controls { + float: left; +} +div.hfh-nested-rep-block div.controls div.hfh-repinst div.controls div.control-group div.controls input { + width: 30px; + margin-right: 10px; +} div.ngcp-modal div.modal-body div.control-group.hfh-rep-block div.control-group.hfh-repinst div.controls { margin-left: 0;