From c72cac0c95af8baac551292c6dd42b2bc50f5b5a Mon Sep 17 00:00:00 2001 From: Andreas Granig Date: Mon, 15 Jul 2013 12:44:05 +0200 Subject: [PATCH] Add Advanced CF mock. --- Build.PL | 2 +- lib/NGCP/Panel.pm | 1 + lib/NGCP/Panel/Controller/Subscriber.pm | 176 +++++++++++++++++++- lib/NGCP/Panel/Form/SubscriberCFAdvanced.pm | 128 ++++++++++++++ lib/NGCP/Panel/Form/SubscriberCFSimple.pm | 21 ++- lib/NGCP/Panel/Utils.pm | 1 - share/static/css/main.css | 21 +++ share/templates/subscriber/preferences.tt | 7 +- 8 files changed, 343 insertions(+), 14 deletions(-) create mode 100644 lib/NGCP/Panel/Form/SubscriberCFAdvanced.pm diff --git a/Build.PL b/Build.PL index 061cd6164b..9b4bc9cd2a 100644 --- a/Build.PL +++ b/Build.PL @@ -33,7 +33,7 @@ my $builder = Local::Module::Build->new( 'DBIx::Class::ResultSet::RecursiveUpdate' => '0.30', 'Email::Valid' => 0, 'File::Type' => 0, - 'HTML::FormHandler' => 0, + 'HTML::FormHandler' => '0.40026', 'HTML::FormHandler::Field' => 0, 'HTML::FormHandler::Field::Compound' => 0, 'HTML::FormHandler::Field::Select' => 0, diff --git a/lib/NGCP/Panel.pm b/lib/NGCP/Panel.pm index 8964549bbe..b1e787b644 100644 --- a/lib/NGCP/Panel.pm +++ b/lib/NGCP/Panel.pm @@ -52,6 +52,7 @@ __PACKAGE__->config( __PACKAGE__->path_to('share', 'layout'), ], ABSOLUTE => 1, + EVAL_PERL => 1, }, 'View::JSON' => { #Set the stash keys to be exposed to a JSON response diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 44e5bc4e73..ba8f1ac217 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -6,6 +6,8 @@ use NGCP::Panel::Utils::Contract; use NGCP::Panel::Form::Subscriber; use NGCP::Panel::Form::SubscriberCFSimple; use NGCP::Panel::Form::SubscriberCFTSimple; +use NGCP::Panel::Form::SubscriberCFAdvanced; +#use NGCP::Panel::Form::SubscriberCFTAdvanced; use UUID; use Data::Printer; @@ -300,6 +302,8 @@ sub preferences_edit :Chained('preferences_base') :PathPart('edit') :Args(0) { sub preferences_callforward :Chained('base') :PathPart('preferences/callforward') :Args(1) { my ($self, $c, $cf_type) = @_; + say ">>>>>>>>>>>>>>>>>>>>>> preferences_callforward"; + my $cf_desc; given($cf_type) { when("cfu") { $cf_desc = "Unconditional" } @@ -307,6 +311,7 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' when("cft") { $cf_desc = "Timeout" } when("cfna") { $cf_desc = "Unavailable" } default { + $c->log->error("Invalid call-forward type '$cf_type'"); $c->flash(messages => [{type => 'error', text => 'Invalid Call Forward type'}]); $c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]])); return; @@ -347,11 +352,13 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' } if($posted) { $params = $c->request->params; - if($params->{destination} !~ /\@/) { - $params->{destination} .= '@'.$billing_subscriber->domain->domain; - } - if($params->{destination} !~ /^sip:/) { - $params->{destination} = 'sip:' . $params->{destination}; + if(!defined($c->request->params->{submitid})) { + if($params->{destination} !~ /\@/) { + $params->{destination} .= '@'.$billing_subscriber->domain->domain; + } + if($params->{destination} !~ /^sip:/) { + $params->{destination} = 'sip:' . $params->{destination}; + } } } @@ -362,14 +369,167 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' $cf_form = NGCP::Panel::Form::SubscriberCFSimple->new; } + $cf_form->process( + params => $params, + ); + # TODO: if more than one entry in $cf_mapping->voip_cf_destination_set->voip_cf_destinations, # show advanced mode and list them all; same for time sets + say ">>>>>>>>>>>>>>>>>>>>>>>> check_form_buttons"; + return if NGCP::Panel::Utils::check_form_buttons( + c => $c, form => $cf_form, + fields => { + 'advanced' => + $c->uri_for_action('/subscriber/preferences_callforward_advanced', + [$c->req->captures->[0]], $cf_type, 'advanced' + ), + 'simple' => + $c->uri_for_action('/subscriber/preferences_callforward', + [$c->req->captures->[0]], $cf_type + ), + }, + back_uri => $c->uri_for($c->action, $c->req->captures) + ); + + + say ">>>>>>>>>>>>>>>>>>>>>>>> after check_form_buttons"; + + if($posted && $cf_form->validated) { + try { + $c->model('DB')->schema->txn_do( sub { + my $dest_set = $c->model('DB')->resultset('voip_cf_destination_sets')->find({ + subscriber_id => $prov_subscriber->id, + name => 'quickset_'.$cf_type, + }); + unless($dest_set) { + $dest_set = $c->model('DB')->resultset('voip_cf_destination_sets')->create({ + name => 'quickset_'.$cf_type, + subscriber_id => $prov_subscriber->id, + }); + } else { + my @all = $dest_set->voip_cf_destinations->all; + foreach my $dest(@all) { + $dest->delete; + } + } + my $dest = $dest_set->voip_cf_destinations->create({ + priority => 1, + timeout => 300, + destination => $c->request->params->{destination}, + }); + + unless(defined $cf_mapping) { + $cf_mapping = $prov_subscriber->voip_cf_mappings->create({ + type => $cf_type, + # subscriber_id => $prov_subscriber->id, + destination_set_id => $dest_set->id, + time_set_id => undef, #$time_set_id, + }); + } + my $cf_preference_row = $cf_preference->find({ + subscriber_id => $prov_subscriber->id + }); + if($cf_preference_row) { + $cf_preference_row->update({ value => $cf_mapping->id }); + } else { + $cf_preference->create({ + subscriber_id => $prov_subscriber->id, + value => $cf_mapping->id, + }); + } + if($cf_type eq 'cft') { + my $ringtimeout_preference_row = $ringtimeout_preference->find({ + subscriber_id => $prov_subscriber->id + }); + if($ringtimeout_preference_row) { + $ringtimeout_preference_row->update({ + value => $c->request->params->{ringtimeout} + }); + } else { + $ringtimeout_preference->create({ + subscriber_id => $prov_subscriber->id, + value => $c->request->params->{ringtimeout}, + }); + } + } + }); + } catch($e) { + $c->log->error("failed to save call-forward: $e"); + $c->flash(messages => [{type => 'error', text => 'Failed to save Call Forward'}]); + $c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]])); + return; + } + + $c->flash(messages => [{type => 'success', text => 'Successfully saved Call Forward'}]); + $c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]])); + return; + } + + $self->load_preference_list($c); + $c->stash(template => 'subscriber/preferences.tt'); + $c->stash( + edit_cf_flag => 1, + cf_description => $cf_desc, + cf_form => $cf_form, + ); +} + +sub preferences_callforward_advanced :Chained('base') :PathPart('preferences/callforward') :Args(2) { + my ($self, $c, $cf_type, $advanced) = @_; + + say ">>>>>>>>>>>>>>>>>>>>>> preferences_callforward_advanced"; + + if(defined $advanced && $advanced eq 'advanced') { + $advanced = 1; + } else { + $advanced = 0; + } + + my $cf_desc; + given($cf_type) { + when("cfu") { $cf_desc = "Unconditional" } + when("cfb") { $cf_desc = "Busy" } + when("cft") { $cf_desc = "Timeout" } + when("cfna") { $cf_desc = "Unavailable" } + default { + $c->log->error("Invalid call-forward type '$cf_type'"); + $c->flash(messages => [{type => 'error', text => 'Invalid Call Forward type'}]); + $c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]])); + return; + } + } + + my $posted = ($c->request->method eq 'POST'); + + my $cf_form; +# my $params = {}; +# if($cf_type eq "cft") { +# $cf_form = NGCP::Panel::Form::SubscriberCFTAdvanced->new; +# } else { + $cf_form = NGCP::Panel::Form::SubscriberCFAdvanced->new; +# } $cf_form->process( - params => $params, - action => $c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0], $c->req->captures->[1]]) + params => $posted ? $c->request->params : {} ); + + say ">>>>>>>>>>>>>>>>>>>>>>>> check_form_buttons"; + return if NGCP::Panel::Utils::check_form_buttons( + c => $c, form => $cf_form, + fields => { + 'simple' => + $c->uri_for_action('/subscriber/preferences_callforward', + [$c->req->captures->[0], $cf_type], + ), + }, + back_uri => $c->uri_for($c->action, $c->req->captures) + ); + + + say ">>>>>>>>>>>>>>>>>>>>>>>> after check_form_buttons"; + +=pod if($posted && $cf_form->validated) { try { $c->model('DB')->schema->txn_do( sub { @@ -441,6 +601,8 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' return; } +=cut + $self->load_preference_list($c); $c->stash(template => 'subscriber/preferences.tt'); $c->stash( diff --git a/lib/NGCP/Panel/Form/SubscriberCFAdvanced.pm b/lib/NGCP/Panel/Form/SubscriberCFAdvanced.pm new file mode 100644 index 0000000000..ae274350cd --- /dev/null +++ b/lib/NGCP/Panel/Form/SubscriberCFAdvanced.pm @@ -0,0 +1,128 @@ +package NGCP::Panel::Form::SubscriberCFAdvanced; +use HTML::FormHandler::Moose; +use HTML::FormHandler::Widget::Block::Bootstrap; +#use NGCP::Panel::Render::RepeatableJs; +#use Moose::Util::TypeConstraints; +extends 'HTML::FormHandler'; + +with 'HTML::FormHandler::Render::RepeatableJs'; + +has '+widget_wrapper' => (default => 'Bootstrap'); + +has_field 'submitid' => ( + type => 'Hidden', +); + +has_field 'active_callforward' => ( + type => 'Repeatable', + setup_for_js => 1, + #do_wrapper => 0, + do_wrapper => 1, + do_label => 0, + tags => { + controls_div => 1, + }, + wrapper_class => [qw/hfh-rep/], +); + +has_field 'active_callforward.destination_set' => ( + type => 'Select', + label => 'Destination Set', + wrapper_class => [qw/hfh-rep-field/], + +); + +has_field 'active_callforward.time_set' => ( + type => 'Select', + label => 'during Time Set', + wrapper_class => [qw/hfh-rep-field/], +); + +has_field 'add_active_callforward' => ( + type => 'AddElement', + repeatable => 'active_callforward', + value => 'Add more', + element_class => [qw/btn btn-primary pull-right/], +); + +#has_field 'rm_active_callforward' => ( +# type => 'RmElement', +# repeatable => 'active_callforward', +# value => 'Remove last', +# element_class => [qw/btn btn-primary pull-right/], +#); + +=pod +has_field 'destination_set.foo' => ( + type => 'Select', + label => 'Destination Set', +); + +has_field 'add_element' => ( + type => '+NGCP::Panel::Field::AddElement', + repeatable => 'destination_set.foo', + value => 'Add more', +); + +has_field 'destination_set' => ( + type => 'Repeatable', +); + +has_field 'destination_set.foo' => ( + type => 'Select', + label => 'Destination Set', +); + +has_field 'add_element' => ( + type => '+NGCP::Panel::Field::AddElement', + repeatable => 'destination_set.foo', + value => 'Add more', +); +=cut + +has_block 'fields' => ( + tag => 'div', + class => [qw(modal-body)], + #render_list => [qw(submitid active_callforward add_active_callforward rm_active_callforward)], + render_list => [qw(submitid active_callforward add_active_callforward )], +); + +has_field 'simple' => ( + type => 'Button', + do_label => 0, + value => 'Simple', + element_class => [qw(btn btn-tertiary)], +); + +has_field 'save' => ( + type => 'Submit', + element_class => [qw(btn btn-primary)], +); + +has_block 'actions' => ( + tag => 'div', + class => [qw(modal-footer)], + render_list => [qw(simple save)], +); + +sub build_render_list { + return [qw(fields actions)]; +} + +sub build_form_element_class { + return [qw(form-horizontal)]; +} + +#sub validate_destination { +# my ($self, $field) = @_; +# +# # TODO: proper SIP URI check! +# if($field->value !~ /^sip:.+\@.+$/) { +# my $err_msg = 'Destination must be a valid SIP URI in format "sip:user@domain"'; +# $field->add_error($err_msg); +# } +#} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/SubscriberCFSimple.pm b/lib/NGCP/Panel/Form/SubscriberCFSimple.pm index 38c5afb092..790edf4e34 100644 --- a/lib/NGCP/Panel/Form/SubscriberCFSimple.pm +++ b/lib/NGCP/Panel/Form/SubscriberCFSimple.pm @@ -5,7 +5,15 @@ use Moose::Util::TypeConstraints; extends 'HTML::FormHandler'; has '+widget_wrapper' => (default => 'Bootstrap'); -has_field 'id' => (type => 'Hidden'); + +has_field 'id' => ( + type => 'Hidden', + noupdate => 1, +); + +has_field 'submitid' => ( + type => 'Hidden', +); has_field 'destination' => ( type => 'Text', @@ -16,13 +24,20 @@ has_field 'destination' => ( }, ); +has_field 'advanced' => ( + type => 'Button', + do_label => 0, + value => 'Advanced', + element_class => [qw(btn btn-tertiary)], +); has_field 'save' => (type => 'Submit', element_class => [qw(btn btn-primary)],); + has_block 'fields' => ( tag => 'div', class => [qw(modal-body)], - render_list => [qw(destination)], + render_list => [qw(submitid destination)], ); -has_block 'actions' => (tag => 'div', class => [qw(modal-footer)], render_list => [qw(save)],); +has_block 'actions' => (tag => 'div', class => [qw(modal-footer)], render_list => [qw(advanced save)],); sub build_render_list { return [qw(id fields actions)]; diff --git a/lib/NGCP/Panel/Utils.pm b/lib/NGCP/Panel/Utils.pm index 6a96c7ccee..b133e858a2 100644 --- a/lib/NGCP/Panel/Utils.pm +++ b/lib/NGCP/Panel/Utils.pm @@ -37,7 +37,6 @@ sub check_form_buttons { if($posted && $form->field('submitid')) { my $val = $form->field('submitid')->value; - if(defined $val and exists($fields->{$val}) ) { my $target; if (defined $fields->{$val}) { diff --git a/share/static/css/main.css b/share/static/css/main.css index 106edfa28d..45dd418181 100644 --- a/share/static/css/main.css +++ b/share/static/css/main.css @@ -39,6 +39,25 @@ div.ngcp-modal .help-inline { z-index: 2000 !important; } +div.ngcp-modal div.modal-body div.control-group.hfh-rep { + margin-left: 0; +} + +div.ngcp-modal div.modal-body div.control-group.hfh-rep div.controls { + margin-left: 0; +} + +div.ngcp-modal div.modal-body div.control-group.hfh-rep div.controls div.hfh-rep-field .controls { + margin-left: 180px; +} + +/* +div.ngcp-modal .control-group.hfh-rep .controls { + margin-left: 0; + border: 1px solid green; +} +*/ + /* --------- Datatable (main one) ------------*/ @@ -225,3 +244,5 @@ div.ngcp-modal .control-group.error .dataTables_wrapper input[type="text"] { width: 206px !important; padding: 4px 6px !important; } + +/* vim: set tabstop=4 syntax=css expandtab: */ diff --git a/share/templates/subscriber/preferences.tt b/share/templates/subscriber/preferences.tt index ba14061562..81ed525167 100644 --- a/share/templates/subscriber/preferences.tt +++ b/share/templates/subscriber/preferences.tt @@ -67,7 +67,7 @@ [% 'always' IF cf_destinations.${cf.type}.size %]
- Edit + Edit [% IF cf_mappings.${cf.type}.id -%] Delete [% END -%] @@ -94,7 +94,10 @@ modal_header(m.name = "Call Forward " _ cf_description); -%] -[% cf_form.render(); %] +[% IF cf_form.has_for_js -%] +[% cf_form.render_repeatable_js %] +[% END -%] +[% cf_form.render %] [% modal_footer();