diff --git a/lib/NGCP/Panel/Controller/Device.pm b/lib/NGCP/Panel/Controller/Device.pm index b8dc3d63f5..9de8f0b1dc 100644 --- a/lib/NGCP/Panel/Controller/Device.pm +++ b/lib/NGCP/Panel/Controller/Device.pm @@ -4,6 +4,7 @@ use Sipwise::Base; use NGCP::Panel::Form::Device::Model; use NGCP::Panel::Form::Device::ModelAdmin; use NGCP::Panel::Form::Device::Firmware; +use NGCP::Panel::Form::Device::Config; use NGCP::Panel::Utils::Navigation; @@ -46,9 +47,25 @@ sub base :Chained('/') :PathPart('device') :CaptureArgs(0) { { name => 'filename', search => 1, title => 'Firmware File' }, ]); + my $devconf_rs = $c->model('DB')->resultset('autoprov_configs'); + unless($c->user->is_superuser) { + $devconf_rs = $devconf_rs->search({ + 'device.reseller_id' => $c->user->reseller_id + }, { + join => 'device', + }); + } + $c->stash->{devconf_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [ + { name => 'id', search => 1, title => '#' }, + { name => 'device.vendor', search => 1, title => 'Device Vendor' }, + { name => 'device.model', search => 1, title => 'Device Model' }, + { name => 'version', search => 1, title => 'Version' }, + ]); + $c->stash( devmod_rs => $devmod_rs, devfw_rs => $devfw_rs, + devconf_rs => $devconf_rs, template => 'device/list.tt', ); } @@ -389,94 +406,165 @@ sub devfw_download :Chained('devfw_base') :PathPart('download') :Args(0) { $c->response->header ('Content-Disposition' => 'attachment; filename="' . $fw->filename . '"'); $c->response->content_type('application/octet-stream'); $c->response->body($fw->data); - $c->flash(messages => [{type => 'success', text => 'Device firmware successfully deleted' }]); } -__PACKAGE__->meta->make_immutable; - -1; - -__END__ - -=head1 NAME - -NGCP::Panel::Controller::Domain - Catalyst Controller - -=head1 DESCRIPTION - -Catalyst Controller. - -=head1 METHODS - -=head2 dom_list - -basis for the domain controller - -=head2 root - -=head2 create - -Provide a form to create new domains. Handle posted data and create domains. - -=head2 search - -obsolete - -=head2 base - -Fetch a domain by its id. - -Data that is put on stash: domain, domain_result - -=head2 edit - -probably obsolete +sub devconf_ajax :Chained('base') :PathPart('config/ajax') :Args(0) { + my ($self, $c) = @_; -=head2 delete + my $resultset = $c->stash->{devconf_rs}; + NGCP::Panel::Utils::Datatables::process($c, $resultset, $c->stash->{devconf_dt_columns}); + $c->detach( $c->view("JSON") ); +} -deletes a domain (defined in base) +sub devconf_create :Chained('base') :PathPart('config/create') :Args(0) { + my ($self, $c) = @_; -=head2 ajax + my $posted = ($c->request->method eq 'POST'); + my $form = NGCP::Panel::Form::Device::Config->new; -Get domains and output them as JSON. + my $params = {}; + $params = $params->merge($c->session->{created_objects}); + $form->process( + posted => $posted, + params => $c->request->params, + item => $params + ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => { + 'device.create' => $c->uri_for('/device/model/create'), + }, + back_uri => $c->req->uri, + ); -=head2 preferences + if($posted && $form->validated) { + try { + my $schema = $c->model('DB'); + $schema->txn_do(sub { + my $devmod = $c->stash->{devmod_rs}->find($form->params->{device}{id}); + $devmod->create_related('autoprov_configs', $form->params); + delete $c->session->{created_objects}->{device}; + $c->flash(messages => [{type => 'success', text => 'Successfully created device configuration'}]); + }); + } catch($e) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => $e, + desc => "Failed to create device configuration", + ); + } + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/device')); + } -Show a table view of preferences. + $c->stash( + devconf_create_flag => 1, + form => $form, + ); +} -=head2 preferences_base +sub devconf_base :Chained('base') :PathPart('config') :CaptureArgs(1) { + my ($self, $c, $devconf_id) = @_; -Get details about one preference for further editing. + unless($devconf_id->is_int) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => "invalid device config id '$devconf_id'", + desc => "Invalid device configuration id", + ); + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/device')); + } -Data that is put on stash: preference_meta, preference, preference_values + $c->stash->{devconf} = $c->stash->{devconf_rs}->find($devconf_id); + unless($c->stash->{devconf}) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => "device configuration with id '$devconf_id' not found", + desc => "Device configuration not found", + ); + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/device')); + } +} -=head2 preferences_edit +sub devconf_delete :Chained('devconf_base') :PathPart('delete') :Args(0) { + my ($self, $c) = @_; -Use a form for editing one preference. Execute the changes that are posted. + try { + $c->stash->{devconf}->delete; + $c->flash(messages => [{type => 'success', text => 'Device configuration successfully deleted' }]); + } catch($e) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => "failed to delete device configuration with id '".$c->stash->{devconf}->id."': $e", + desc => "Failed to delete device configuration", + ); + } -Data that is put on stash: edit_preference, form + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/device')); +} -=head2 load_preference_list +sub devconf_edit :Chained('devconf_base') :PathPart('edit') :Args(0) { + my ($self, $c) = @_; -Retrieves and processes a datastructure containing preference groups, preferences and their values, to be used in rendering the preference list. + my $posted = ($c->request->method eq 'POST'); + my $form; + my $params = { $c->stash->{devconf}->get_inflated_columns }; + $params->{device}{id} = delete $params->{device_id}; + $params = $params->merge($c->session->{created_objects}); + $form = NGCP::Panel::Form::Device::Config->new; -Data that is put on stash: pref_groups + $form->process( + posted => $posted, + params => $c->request->params, + item => $params + ); + NGCP::Panel::Utils::Navigation::check_form_buttons( + c => $c, + form => $form, + fields => { + 'device.create' => $c->uri_for('/device/model/create'), + }, + back_uri => $c->req->uri, + ); -=head2 _sip_domain_reload + if($posted && $form->validated) { + try { + my $schema = $c->model('DB'); + $schema->txn_do(sub { + $form->params->{device_id} = $form->params->{device}{id}; + delete $form->params->{device}; -Ported from ossbss + $c->stash->{devconf}->update($form->params); + delete $c->session->{created_objects}->{device}; + $c->flash(messages => [{type => 'success', text => 'Successfully updated device configuration'}]); + }); + } catch($e) { + NGCP::Panel::Utils::Message->error( + c => $c, + error => $e, + desc => "Failed to update device configuration", + ); + } + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/device')); + } -reloads domain cache of sip proxies + $c->stash( + devconf_edit_flag => 1, + form => $form, + ); +} -=head1 AUTHOR +sub devconf_download :Chained('devconf_base') :PathPart('download') :Args(0) { + my ($self, $c) = @_; -Andreas Granig,,, + my $conf = $c->stash->{devconf}; -=head1 LICENSE + $c->response->content_type($conf->content_type); + $c->response->body($conf->data); +} -This library is free software. You can redistribute it and/or modify -it under the same terms as Perl itself. +__PACKAGE__->meta->make_immutable; -=cut +1; # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Device/Config.pm b/lib/NGCP/Panel/Form/Device/Config.pm new file mode 100644 index 0000000000..3fbe2d2ed6 --- /dev/null +++ b/lib/NGCP/Panel/Form/Device/Config.pm @@ -0,0 +1,63 @@ +package NGCP::Panel::Form::Device::Config; + +use HTML::FormHandler::Moose; +extends 'HTML::FormHandler'; +use Moose::Util::TypeConstraints; + +use HTML::FormHandler::Widget::Block::Bootstrap; + +has '+widget_wrapper' => ( default => 'Bootstrap' ); +has_field 'submitid' => ( type => 'Hidden' ); +sub build_render_list {[qw/submitid fields actions/]} +sub build_form_element_class {[qw(form-horizontal)]} + +has_field 'device' => ( + type => '+NGCP::Panel::Field::Device', + not_nullable => 1, + label => 'Device Model', +); + +has_field 'version' => ( + type => 'Text', + required => 1, + label => 'Version', +); + +has_field 'content_type' => ( + type => 'Text', + required => 1, + label => 'Content Type', + default => 'text/xml', +); + +has_field 'data' => ( + type => 'TextArea', + required => 1, + label => 'Content', + cols => 200, + rows => 10, + maxlength => '67108864', # 64MB + element_class => [qw/ngcp-autoconf-area/], +); + +has_field 'save' => ( + type => 'Submit', + value => 'Save', + element_class => [qw/btn btn-primary/], + label => '', +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/device version content_type data/], +); + +has_block 'actions' => ( + tag => 'div', + class => [qw/modal-footer/], + render_list => [qw/save/], +); + +1; +# vim: set tabstop=4 expandtab: diff --git a/share/static/css/main.css b/share/static/css/main.css index 41fd90c1c2..cba67ac1bc 100644 --- a/share/static/css/main.css +++ b/share/static/css/main.css @@ -388,4 +388,8 @@ div.ngcp-modal .control-group.error .dataTables_wrapper input[type="text"] { cursor: not-allowed; } +textarea.ngcp-autoconf-area { + width: 580px; +} + /* vim: set tabstop=4 syntax=css expandtab: */ diff --git a/share/templates/device/list.tt b/share/templates/device/list.tt index 0cae0bb462..a953a1a7f9 100644 --- a/share/templates/device/list.tt +++ b/share/templates/device/list.tt @@ -92,6 +92,43 @@ +