diff --git a/Build.PL b/Build.PL index 9b4bc9cd2a..ec1939eea5 100644 --- a/Build.PL +++ b/Build.PL @@ -57,6 +57,7 @@ my $builder = Local::Module::Build->new( 'Template' => 0, 'Text::CSV_XS' => 0, 'UUID' => 0, + 'Hash::Merge::Simple' => 0, 'warnings' => 0, }, test_requires => { diff --git a/debian/control b/debian/control index e4e9986335..a7f0d48838 100644 --- a/debian/control +++ b/debian/control @@ -30,7 +30,7 @@ Build-Depends: debhelper (>= 8), libsys-sig-perl, libtext-csv-xs-perl, libtrycatch-perl, - libhash-merge-perl, + libhash-merge-simple-perl, ngcp-schema Standards-Version: 3.9.4 Homepage: http://sipwise.com/ @@ -59,13 +59,13 @@ Depends: libcatalyst-actionrole-acl-perl, libmoosex-fileattribute-perl, libmoosex-object-pluggable-perl, libmoosex-singleton-perl, - libnamespace-autoclean-perl, libnamespace-sweep-perl, libnet-http-perl, libregexp-parser-perl, libsys-sig-perl, libtemplate-perl, libtext-csv-xs-perl, + libhash-merge-simple-perl, ngcp-schema, ${misc:Depends}, ${perl:Depends} diff --git a/lib/NGCP/Panel.pm b/lib/NGCP/Panel.pm index b1e787b644..e15263f95e 100644 --- a/lib/NGCP/Panel.pm +++ b/lib/NGCP/Panel.pm @@ -1,6 +1,5 @@ package NGCP::Panel; use Moose; -use namespace::autoclean; use Catalyst::Runtime 5.80; diff --git a/lib/NGCP/Panel/Controller/Billing.pm b/lib/NGCP/Panel/Controller/Billing.pm index 6e0caa86ee..ad22864d29 100644 --- a/lib/NGCP/Panel/Controller/Billing.pm +++ b/lib/NGCP/Panel/Controller/Billing.pm @@ -1,6 +1,5 @@ package NGCP::Panel::Controller::Billing; use Sipwise::Base; -use namespace::autoclean; use Text::CSV_XS; use I18N::Langinfo qw(langinfo DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7); use DateTime::Format::ISO8601; diff --git a/lib/NGCP/Panel/Controller/Contact.pm b/lib/NGCP/Panel/Controller/Contact.pm index f616f69fe3..b41ab82296 100644 --- a/lib/NGCP/Panel/Controller/Contact.pm +++ b/lib/NGCP/Panel/Controller/Contact.pm @@ -94,7 +94,7 @@ sub create_without_reseller :Chained('list_contact') :PathPart('create/noreselle sub base :Chained('list_contact') :PathPart('') :CaptureArgs(1) { my ($self, $c, $contact_id) = @_; - unless($contact_id && $contact_id =~ /^\d+$/) { + unless($contact_id && $contact_id->is_int) { $c->flash(messages => [{type => 'error', text => 'Invalid contact id detected!'}]); NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for()); } diff --git a/lib/NGCP/Panel/Controller/Contract.pm b/lib/NGCP/Panel/Controller/Contract.pm index 7670875dc0..9d3d2da147 100644 --- a/lib/NGCP/Panel/Controller/Contract.pm +++ b/lib/NGCP/Panel/Controller/Contract.pm @@ -1,8 +1,7 @@ package NGCP::Panel::Controller::Contract; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } -use Hash::Merge; use NGCP::Panel::Form::Contract; use NGCP::Panel::Utils::Navigation; use NGCP::Panel::Utils::Contract; @@ -83,7 +82,7 @@ sub create :Chained('contract_list') :PathPart('create') :Args(0) { my $posted = ($c->request->method eq 'POST'); my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); my $form; $form = NGCP::Panel::Form::Contract->new; $form->process( @@ -177,7 +176,7 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) { my $contract = $c->stash->{contract_result}; my $billing_mapping = $contract->billing_mappings->find($contract->get_column('bmid')); my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); unless($posted) { $params->{billing_profile}{id} = $billing_mapping->billing_profile->id; $params->{contact}{id} = $contract->contact_id; @@ -298,7 +297,7 @@ sub peering_create :Chained('peering_list') :PathPart('create') :Args(0) { my $posted = ($c->request->method eq 'POST'); my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); my $form = NGCP::Panel::Form::Contract->new; $form->process( posted => $posted, @@ -379,7 +378,7 @@ sub customer_create :Chained('customer_list') :PathPart('create') :Args(0) { my $posted = ($c->request->method eq 'POST'); my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); my $form = NGCP::Panel::Form::Contract->new; $form->process( posted => $posted, diff --git a/lib/NGCP/Panel/Controller/Dashboard.pm b/lib/NGCP/Panel/Controller/Dashboard.pm index 7eb5754af0..4fb48b3c9a 100644 --- a/lib/NGCP/Panel/Controller/Dashboard.pm +++ b/lib/NGCP/Panel/Controller/Dashboard.pm @@ -1,6 +1,5 @@ package NGCP::Panel::Controller::Dashboard; use Moose; -use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } use NGCP::Panel::Widget; diff --git a/lib/NGCP/Panel/Controller/Domain.pm b/lib/NGCP/Panel/Controller/Domain.pm index e52922304f..d25ae7bd5d 100644 --- a/lib/NGCP/Panel/Controller/Domain.pm +++ b/lib/NGCP/Panel/Controller/Domain.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Domain; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } diff --git a/lib/NGCP/Panel/Controller/Login.pm b/lib/NGCP/Panel/Controller/Login.pm index d35d012101..8944b46fed 100644 --- a/lib/NGCP/Panel/Controller/Login.pm +++ b/lib/NGCP/Panel/Controller/Login.pm @@ -1,7 +1,7 @@ package NGCP::Panel::Controller::Login; use Moose; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } use NGCP::Panel::Form::Login; diff --git a/lib/NGCP/Panel/Controller/Logout.pm b/lib/NGCP/Panel/Controller/Logout.pm index ec674d6a86..ce7af76428 100644 --- a/lib/NGCP/Panel/Controller/Logout.pm +++ b/lib/NGCP/Panel/Controller/Logout.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Logout; use Moose; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } diff --git a/lib/NGCP/Panel/Controller/NCOS.pm b/lib/NGCP/Panel/Controller/NCOS.pm index 7a3c19cafd..0914d90e7c 100644 --- a/lib/NGCP/Panel/Controller/NCOS.pm +++ b/lib/NGCP/Panel/Controller/NCOS.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::NCOS; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } diff --git a/lib/NGCP/Panel/Controller/Peering.pm b/lib/NGCP/Panel/Controller/Peering.pm index d34dcf8a3d..c41692c398 100644 --- a/lib/NGCP/Panel/Controller/Peering.pm +++ b/lib/NGCP/Panel/Controller/Peering.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Peering; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } @@ -73,7 +73,7 @@ sub edit :Chained('base') :PathPart('edit') { my $posted = ($c->request->method eq 'POST'); my $form = NGCP::Panel::Form::PeeringGroup->new; my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); $form->process( posted => $posted, params => $c->request->params, @@ -122,7 +122,7 @@ sub create :Chained('group_list') :PathPart('create') :Args(0) { my $posted = ($c->request->method eq 'POST'); my $form = NGCP::Panel::Form::PeeringGroup->new; my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); $form->process( posted => $posted, params => $c->request->params, diff --git a/lib/NGCP/Panel/Controller/Reseller.pm b/lib/NGCP/Panel/Controller/Reseller.pm index d75b50133b..4ad57398dd 100644 --- a/lib/NGCP/Panel/Controller/Reseller.pm +++ b/lib/NGCP/Panel/Controller/Reseller.pm @@ -3,7 +3,6 @@ use Sipwise::Base; use namespace::sweep; BEGIN { extends 'Catalyst::Controller'; } use DateTime qw(); -use Hash::Merge; use HTTP::Status qw(HTTP_SEE_OTHER); use NGCP::Panel::Form::Reseller; use NGCP::Panel::Utils::Navigation; @@ -61,7 +60,7 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) { if($c->user->read_only); my $params = {}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); my $posted = $c->request->method eq 'POST'; my $form = NGCP::Panel::Form::Reseller->new; @@ -83,14 +82,14 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) { delete $form->params->{contract}; my $reseller = $c->model('DB')->resultset('resellers')->create($form->params); delete $c->session->{created_objects}->{contract}; + $c->session->{created_objects}->{reseller} = { id => $reseller->id }; $c->flash(messages => [{type => 'success', text => 'Reseller successfully created'}]); } catch($e) { $c->log->error($e); $c->flash(messages => [{type => 'error', text => 'Failed to create reseller'}]); } - $c->response->redirect($c->uri_for()); - return; + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for()); } $c->stash(create_flag => 1); @@ -101,7 +100,7 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) { sub base :Chained('list_reseller') :PathPart('') :CaptureArgs(1) { my ($self, $c, $reseller_id) = @_; - unless($reseller_id && $reseller_id =~ /^\d+$/) { + unless($reseller_id && $reseller_id->is_int) { $c->flash(messages => [{type => 'error', text => 'Invalid reseller id detected'}]); $c->response->redirect($c->uri_for()); return; @@ -198,7 +197,7 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) { my $params = { $c->stash->{reseller}->first->get_inflated_columns }; $params->{contract}{id} = delete $params->{contract_id}; - $params = Hash::Merge->new('RIGHT_PRECEDENT')->merge($params, $c->session->{created_objects}); + $params = $params->merge($c->session->{created_objects}); $form->process( posted => $posted, params => $c->request->params, @@ -361,7 +360,7 @@ sub create_defaults :Path('create_defaults') :Args(0) { $c->flash(messages => [{type => 'error', text => 'Failed to create reseller'}]); }; $c->flash(messages => [{type => 'success', text => "Reseller successfully created with login ".$defaults{admins}->{login}." and password ".$defaults{admins}->{md5pass}.", please review your settings below" }]); - $c->res->redirect(sprintf('/reseller/%d/details', $r{resellers}->id), HTTP_SEE_OTHER); + $c->res->redirect($c->uri_for_action('/reseller/details', [$r{resellers}->id])); $c->detach; return; } diff --git a/lib/NGCP/Panel/Controller/Rewrite.pm b/lib/NGCP/Panel/Controller/Rewrite.pm index 3bc298ec08..ae8426d691 100644 --- a/lib/NGCP/Panel/Controller/Rewrite.pm +++ b/lib/NGCP/Panel/Controller/Rewrite.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Rewrite; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } diff --git a/lib/NGCP/Panel/Controller/Root.pm b/lib/NGCP/Panel/Controller/Root.pm index aba7793e17..228c00f144 100644 --- a/lib/NGCP/Panel/Controller/Root.pm +++ b/lib/NGCP/Panel/Controller/Root.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Root; use Moose; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller' } @@ -73,6 +73,25 @@ sub index :Path :Args(0) { $c->response->redirect($c->uri_for('/dashboard')); } +sub back :Path('/back') :Args(0) { + my ( $self, $c ) = @_; + my $target; + my $ref_uri = URI->new($c->req->referer) || $c->uri_for('/dashboard'); + if($c->session->{redirect_targets}) { + while(@{ $c->session->{redirect_targets} }) { + $target = shift @{ $c->session->{redirect_targets} }; + last unless($ref_uri->path eq $target->path); + } + if($ref_uri->path eq $target->path) { + $target = $c->uri_for('/dashboard'); + } + } else { + $target = $c->uri_for('/dashboard'); + } + $c->response->redirect($target); + $c->detach; +} + sub default :Path { my ( $self, $c ) = @_; $c->detach( '/error_page' ); diff --git a/lib/NGCP/Panel/Controller/Sound.pm b/lib/NGCP/Panel/Controller/Sound.pm index 0eca80e326..797ec9edc5 100644 --- a/lib/NGCP/Panel/Controller/Sound.pm +++ b/lib/NGCP/Panel/Controller/Sound.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Sound; use Sipwise::Base; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } diff --git a/lib/NGCP/Panel/Controller/Statistics.pm b/lib/NGCP/Panel/Controller/Statistics.pm index 242a5410eb..37b44801d8 100644 --- a/lib/NGCP/Panel/Controller/Statistics.pm +++ b/lib/NGCP/Panel/Controller/Statistics.pm @@ -1,6 +1,6 @@ package NGCP::Panel::Controller::Statistics; use Moose; -use namespace::autoclean; + BEGIN { extends 'Catalyst::Controller'; } use Sipwise::Base; diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 5254c24cb1..2def6a4a1a 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -78,16 +78,23 @@ sub root :Chained('sub_list') :PathPart('') :Args(0) { sub create_list :Chained('sub_list') :PathPart('create') :Args(0) { my ($self, $c) = @_; + my $posted = ($c->request->method eq 'POST'); + my $params = {}; + $params = $params->merge($c->session->{created_objects}); my $form = NGCP::Panel::Form::Subscriber->new; $form->process( - posted => ($c->request->method eq 'POST'), + posted => $posted, params => $c->request->params, - action => $c->uri_for('/subscriber/create'), + item => $params, ); NGCP::Panel::Utils::Navigation::check_form_buttons( c => $c, form => $form, - fields => [qw/domain.create/], + fields => { + 'domain.create' => $c->uri_for('/domain/create'), + 'reseller.create' => $c->uri_for('/reseller/create'), + 'contract.create' => $c->uri_for('/contract/customer/create'), + }, back_uri => $c->req->uri, ); if($form->validated) { @@ -192,6 +199,10 @@ sub create_list :Chained('sub_list') :PathPart('create') :Args(0) { password => sprintf("%04d", int(rand 10000)), email => '', }); + + delete $c->session->{created_objects}->{reseller}; + delete $c->session->{created_objects}->{contract}; + delete $c->session->{created_objects}->{domain}; }); $c->flash(messages => [{type => 'success', text => 'Subscriber successfully created!'}]); $c->response->redirect($c->uri_for('/subscriber')); @@ -796,6 +807,12 @@ sub preferences_callforward_destinationset_create :Chained('base') :PathPart('pr posted => $posted, params => $c->req->params, ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { @@ -947,6 +964,12 @@ sub preferences_callforward_destinationset_edit :Chained('preferences_callforwar $form->process( params => $posted ? $c->req->params : $params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); delete $c->stash->{cf_tmp_params}; if($posted && $form->validated) { @@ -1133,6 +1156,12 @@ sub preferences_callforward_timeset_create :Chained('base') :PathPart('preferenc posted => $posted, params => $c->req->params, ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { @@ -1238,6 +1267,12 @@ sub preferences_callforward_timeset_edit :Chained('preferences_callforward_times $form->process( params => $posted ? $c->req->params : $params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { @@ -1459,6 +1494,12 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) { $form->process( params => $posted ? $c->request->params : $params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { my $schema = $c->model('DB'); @@ -1617,6 +1658,9 @@ sub edit_voicebox :Chained('base') :PathPart('preferences/voicebox/edit') :Args( $form = NGCP::Panel::Form::Voicemail::Pin->new; $params = { 'pin' => $vm_user->password }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $vm_user->update({ password => $form->field('pin')->value }); } @@ -1625,6 +1669,9 @@ sub edit_voicebox :Chained('base') :PathPart('preferences/voicebox/edit') :Args( $form = NGCP::Panel::Form::Voicemail::Email->new; $params = { 'email' => $vm_user->email }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $vm_user->update({ email => $form->field('email')->value }); } @@ -1633,6 +1680,9 @@ sub edit_voicebox :Chained('base') :PathPart('preferences/voicebox/edit') :Args( $form = NGCP::Panel::Form::Voicemail::Attach->new; $params = { 'attach' => $vm_user->attach eq 'yes' ? 1 : 0 }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $vm_user->update({ attach => $form->field('attach')->value ? 'yes' : 'no' }); } @@ -1641,6 +1691,9 @@ sub edit_voicebox :Chained('base') :PathPart('preferences/voicebox/edit') :Args( $form = NGCP::Panel::Form::Voicemail::Delete->new; $params = { 'delete' => $vm_user->get_column('delete') eq 'yes' ? 1 : 0 }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $vm_user->update({ delete => $form->field('delete')->value ? 'yes' : 'no', @@ -1698,6 +1751,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $form = NGCP::Panel::Form::Faxserver::Name->new; $params = { 'name' => $faxpref->name }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $faxpref->update({ name => $form->field('name')->value }); } @@ -1706,6 +1762,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $form = NGCP::Panel::Form::Faxserver::Password->new; $params = { 'password' => $faxpref->password }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $faxpref->update({ password => $form->field('password')->value }); } @@ -1714,6 +1773,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $form = NGCP::Panel::Form::Faxserver::Active->new; $params = { 'active' => $faxpref->active }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $faxpref->update({ active => $form->field('active')->value }); } @@ -1722,6 +1784,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $form = NGCP::Panel::Form::Faxserver::SendStatus->new; $params = { 'send_status' => $faxpref->send_status }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $faxpref->update({ send_status => $form->field('send_status')->value }); } @@ -1730,6 +1795,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $form = NGCP::Panel::Form::Faxserver::SendCopy->new; $params = { 'send_copy' => $faxpref->send_copy }; $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { $faxpref->update({ send_copy => $form->field('send_copy')->value }); } @@ -1751,6 +1819,9 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { $params->{destination} = \@dests; } $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, form => $form, fields => {}, back_uri => $c->req->uri, + ); if($posted && $form->validated) { for my $dest($prov_subscriber->voip_fax_destinations->all) { $dest->delete; @@ -1810,6 +1881,12 @@ sub edit_reminder :Chained('base') :PathPart('preferences/reminder/edit') { $form->process( params => $posted ? $c->req->params : $params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { @@ -2009,6 +2086,12 @@ sub create_registered :Chained('master') :PathPart('registered/create') :Args(0) posted => $posted, params => $c->request->params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { my $s = $c->stash->{subscriber}->provisioning_voip_subscriber; @@ -2065,6 +2148,12 @@ sub create_trusted :Chained('base') :PathPart('preferences/trusted/create') :Arg posted => $posted, params => $posted ? $c->req->params : {} ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { @@ -2127,6 +2216,12 @@ sub edit_trusted :Chained('trusted_base') :PathPart('edit') { $form->process( params => $posted ? $c->req->params : $params ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { @@ -2191,6 +2286,12 @@ sub create_speeddial :Chained('base') :PathPart('preferences/speeddial/create') my $form = NGCP::Panel::Form::Subscriber::SpeedDial->new(ctx => $c); $form->process(params => $c->req->params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { my $d = $form->field('destination')->value; @@ -2269,6 +2370,12 @@ sub edit_speeddial :Chained('speeddial') :PathPart('edit') :Args(0) { } $form->process(params => $posted ? $c->req->params : $params); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => {}, + back_uri => $c->req->uri, + ); if($posted && $form->validated) { try { my $d = $form->field('destination')->value; diff --git a/lib/NGCP/Panel/Field/CustomerContract.pm b/lib/NGCP/Panel/Field/CustomerContract.pm index 351e3261a7..0feecf2d11 100644 --- a/lib/NGCP/Panel/Field/CustomerContract.pm +++ b/lib/NGCP/Panel/Field/CustomerContract.pm @@ -10,8 +10,8 @@ has_field 'id' => ( required => 1, template => 'share/templates/helpers/datatables_field.tt', ajax_src => '/contract/customer/ajax', - table_titles => ['#', 'Contact #', 'External #', 'Status'], - table_fields => ['id', 'contact_id', 'external_id', 'status'], + table_titles => ['#', 'Contact Email', 'External #', 'Status'], + table_fields => ['id', 'contact_email', 'external_id', 'status'], ); has_field 'create' => ( diff --git a/lib/NGCP/Panel/Form/DestinationSet.pm b/lib/NGCP/Panel/Form/DestinationSet.pm index 4e95ad2329..5b3515a3a9 100644 --- a/lib/NGCP/Panel/Form/DestinationSet.pm +++ b/lib/NGCP/Panel/Form/DestinationSet.pm @@ -63,7 +63,7 @@ sub set_destination_groups { my $parent_id = $self->parent->name; my $uri_d = ""; my $uri_t = 300; - if($parent_id =~ /^\d+$/ && + if($parent_id->is_int && defined $self->form->ctx && defined $self->form->ctx->stash->{cf_tmp_params}) { my $d = $self->form->ctx->stash->{cf_tmp_params}->{destination}->[$parent_id]; diff --git a/lib/NGCP/Panel/Utils/Navigation.pm b/lib/NGCP/Panel/Utils/Navigation.pm index dfada47e87..267d2734eb 100644 --- a/lib/NGCP/Panel/Utils/Navigation.pm +++ b/lib/NGCP/Panel/Utils/Navigation.pm @@ -1,9 +1,8 @@ package NGCP::Panel::Utils::Navigation; -use strict; -use warnings; use Sipwise::Base; use DBIx::Class::Exception; +use URI::Encode qw(uri_decode); sub check_redirect_chain { my %params = @_; @@ -20,6 +19,17 @@ sub check_redirect_chain { $c->stash(close_target => $target); } } + + if($c->request->params->{back}) { + my $back_uri = URI->new(uri_decode($c->request->params->{back})); + $back_uri->query_param_delete('back'); + delete $c->request->params->{back}; + if($c->session->{redirect_targets}) { + unshift @{ $c->session->{redirect_targets} }, $back_uri; + } else { + $c->session->{redirect_targets} = [ $back_uri ]; + } + } } sub check_form_buttons { @@ -30,6 +40,7 @@ sub check_form_buttons { my $fields = $params{fields}; my $form = $params{form}; my $back_uri = $params{back_uri}; + $back_uri->query_param_delete('back'); $fields = { map {($_, undef)} @$fields } if (ref($fields) eq "ARRAY"); diff --git a/lib/NGCP/Panel/Utils/Subscriber.pm b/lib/NGCP/Panel/Utils/Subscriber.pm index 8d6fd3fd85..229b03ce88 100644 --- a/lib/NGCP/Panel/Utils/Subscriber.pm +++ b/lib/NGCP/Panel/Utils/Subscriber.pm @@ -71,7 +71,7 @@ sub destination_as_string { } else { my $d = $dest; $d =~ s/sip:(.+)\@.+$/$1/; - if($d =~ /^\d+$/) { + if($d->is_int) { return $d; } else { return $dest; diff --git a/lib/NGCP/Panel/View/HTML.pm b/lib/NGCP/Panel/View/HTML.pm index 311e35c856..509161371d 100644 --- a/lib/NGCP/Panel/View/HTML.pm +++ b/lib/NGCP/Panel/View/HTML.pm @@ -1,6 +1,5 @@ package NGCP::Panel::View::HTML; use Moose; -use namespace::autoclean; extends 'Catalyst::View::TT'; diff --git a/share/layout/body.tt b/share/layout/body.tt index a267301f9f..02427146d6 100644 --- a/share/layout/body.tt +++ b/share/layout/body.tt @@ -98,6 +98,31 @@ $(function () { $('#dataConfirmModal').modal({show:true}); return false; }); + + [% + backuri = c.req.uri; + tmp = backuri.query_param_delete('back'); + -%] + $('a').each(function() { + var _text = $(this).text().trim(); + if(_text == "Back" || + $(this).hasClass('accordion-toggle') || + $(this).parents('#footer').length || + $(this).parents('#topbar').length) { + + return true; + } + var _href = $(this).attr('href'); + var _back = 'back=[% backuri | uri %]'; + if(_href == null) { + // ignore + } else if(_href.match(/\?/)) { + $(this).attr('href', _href + '&' + _back); + } else { + $(this).attr('href', _href + '?' + _back); + } + return true; + }); }); diff --git a/share/static/js/libs/datatables-bootstrap-paging.js b/share/static/js/libs/datatables-bootstrap-paging.js index c1317da1b5..14f59fd668 100644 --- a/share/static/js/libs/datatables-bootstrap-paging.js +++ b/share/static/js/libs/datatables-bootstrap-paging.js @@ -60,7 +60,6 @@ $.fn.dataTableExt.oPagination.bootstrap = { // Update stateful properties this.fnUpdateState(oSettings); - console.log(oSettings); var totalPages = Math.ceil(oSettings._iRecordsDisplay / oSettings._iDisplayLength); if (oSettings._iCurrentPage === 1) { diff --git a/share/templates/customer/details.tt b/share/templates/customer/details.tt index 3f33632794..654fc21f4d 100644 --- a/share/templates/customer/details.tt +++ b/share/templates/customer/details.tt @@ -12,7 +12,7 @@
- Back + Back
diff --git a/share/templates/helpers/datatables.tt b/share/templates/helpers/datatables.tt index 4cc1002385..3230e66598 100644 --- a/share/templates/helpers/datatables.tt +++ b/share/templates/helpers/datatables.tt @@ -8,6 +8,8 @@ helper.column_fields.push(col.accessor); END; END; + backuri = c.req.uri; + tmp = backuri.query_param_delete('back'); -%] @@ -62,7 +64,7 @@ $(document).ready(function() { if([% button.condition %]) { [% END -%] html += - '' + + '' + ' [% button.name %]' + ''; [% IF button.condition -%] @@ -128,10 +130,14 @@ $(document).ready(function() {
+ + Back + [% FOR button IN helper.top_buttons -%] [% IF button.method == "post" -%]
+
[% ELSE -%] diff --git a/share/templates/reseller/details.tt b/share/templates/reseller/details.tt index cadec19621..0702baf999 100644 --- a/share/templates/reseller/details.tt +++ b/share/templates/reseller/details.tt @@ -2,7 +2,7 @@ diff --git a/share/templates/subscriber/list.tt b/share/templates/subscriber/list.tt index b418c2978f..1d2a4b3e01 100644 --- a/share/templates/subscriber/list.tt +++ b/share/templates/subscriber/list.tt @@ -12,14 +12,21 @@ helper.form_object = form; helper.ajax_uri = c.uri_for_action('/subscriber/ajax'); - helper.dt_buttons = [ - { name = 'Terminate', uri = "/subscriber/'+full.id+'/terminate", class = 'btn-small btn-secondary', icon = 'icon-trash', condition = 'full.status != "terminated"' }, - { name = 'Details', uri = "/subscriber/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-th-list', condition = 'full.status != "terminated"' }, - { name = 'Customer', uri = "/customer/'+full.contract_id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-user' }, - ]; - helper.top_buttons = [ - { name = 'Create Subscriber', uri = c.uri_for_action('/subscriber/create_list'), icon = 'icon-star' }, - ]; + UNLESS c.user.read_only; + helper.dt_buttons = [ + { name = 'Terminate', uri = "/subscriber/'+full.id+'/terminate", class = 'btn-small btn-secondary', icon = 'icon-trash', condition = 'full.status != "terminated"' }, + { name = 'Details', uri = "/subscriber/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-th-list', condition = 'full.status != "terminated"' }, + { name = 'Customer', uri = "/customer/'+full.contract_id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-user' }, + ]; + helper.top_buttons = [ + { name = 'Create Subscriber', uri = c.uri_for_action('/subscriber/create_list'), icon = 'icon-star' }, + ]; + ELSE; + helper.dt_buttons = [ + { name = 'Details', uri = "/subscriber/'+full.id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-th-list', condition = 'full.status != "terminated"' }, + { name = 'Customer', uri = "/customer/'+full.contract_id+'/details", class = 'btn-small btn-tertiary', icon = 'icon-user' }, + ]; + END; PROCESS 'helpers/datatables.tt'; -%] diff --git a/share/templates/widgets/admin_billing_overview.tt b/share/templates/widgets/admin_billing_overview.tt index 4910acae82..622aa22551 100644 --- a/share/templates/widgets/admin_billing_overview.tt +++ b/share/templates/widgets/admin_billing_overview.tt @@ -15,7 +15,7 @@
- Configure + Configure
diff --git a/share/templates/widgets/admin_peering_overview.tt b/share/templates/widgets/admin_peering_overview.tt index f1d9656f4e..21585c4b5b 100644 --- a/share/templates/widgets/admin_peering_overview.tt +++ b/share/templates/widgets/admin_peering_overview.tt @@ -14,7 +14,7 @@
- Configure + Configure
diff --git a/share/templates/widgets/admin_reseller_overview.tt b/share/templates/widgets/admin_reseller_overview.tt index 561ea7440c..c55441372a 100644 --- a/share/templates/widgets/admin_reseller_overview.tt +++ b/share/templates/widgets/admin_reseller_overview.tt @@ -15,7 +15,7 @@
- Configure + Configure
diff --git a/share/templates/widgets/admin_system_overview.tt b/share/templates/widgets/admin_system_overview.tt index 701841f991..c7db19c235 100644 --- a/share/templates/widgets/admin_system_overview.tt +++ b/share/templates/widgets/admin_system_overview.tt @@ -15,7 +15,7 @@
- View Statistics + View Statistics