Implement speed dial management.

agranig/1_0_subfix
Andreas Granig 13 years ago
parent 6b7be6450f
commit 8c7a23fb71

@ -22,6 +22,7 @@ use NGCP::Panel::Form::Voicemail::Delete;
use NGCP::Panel::Form::Reminder;
use NGCP::Panel::Form::Subscriber::TrustedSource;
use NGCP::Panel::Form::Subscriber::Location;
use NGCP::Panel::Form::Subscriber::SpeedDial;
use NGCP::Panel::Form::Faxserver::Name;
use NGCP::Panel::Form::Faxserver::Password;
use NGCP::Panel::Form::Faxserver::Active;
@ -226,6 +227,12 @@ sub base :Chained('/subscriber/sub_list') :PathPart('') :CaptureArgs(1) {
}
$c->stash(subscriber => $res);
$c->stash->{sd_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "id", search => 1, title => "#" },
{ name => "slot", search => 1, title => "Slot" },
{ name => "destination", search => 1, title => "Destination" },
]);
}
sub ajax :Chained('sub_list') :PathPart('ajax') :Args(0) {
@ -1898,7 +1905,7 @@ sub voicemail :Chained('master') :PathPart('voicemail') :CaptureArgs(1) {
});
unless($rs->first) {
$c->log->error("no such voicemail file with id '$vm_id' for uuid ".$c->stash->{subscriber}->uuid);
$c->flash(messages => [{type => 'error', text => 'No such voicemail file to play'}]);
$c->flash(messages => [{type => 'error', text => 'No such voicemail file'}]);
$c->response->redirect($c->uri_for_action('/subscriber/details', [$c->req->captures->[0]]));
return;
}
@ -2166,6 +2173,140 @@ sub delete_trusted :Chained('trusted_base') :PathPart('delete') :Args(0) {
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
}
sub ajax_speeddial :Chained('base') :PathPart('preferences/speeddial/ajax') :Args(0) {
my ($self, $c) = @_;
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $sd_rs = $prov_subscriber->voip_speed_dials;
NGCP::Panel::Utils::Datatables::process($c, $sd_rs, $c->stash->{sd_dt_columns});
$c->detach( $c->view("JSON") );
}
sub create_speeddial :Chained('base') :PathPart('preferences/speeddial/create') :Args(0) {
my ($self, $c) = @_;
my $posted = ($c->request->method eq 'POST');
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $slots = $prov_subscriber->voip_speed_dials;
$c->stash->{used_sd_slots} = $slots;
my $form = NGCP::Panel::Form::Subscriber::SpeedDial->new(ctx => $c);
$form->process(params => $c->req->params);
if($posted && $form->validated) {
try {
my $d = $form->field('destination')->value;
if($d !~ /\@/) {
$d .= '@'.$prov_subscriber->domain->domain;
}
if($d !~ /^sip:/) {
$d = 'sip:' . $d;
}
$slots->create({
slot => $form->field('slot')->value,
destination => $d,
});
$c->flash(messages => [{type => 'success', text => 'Successfully created speed dial slot'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
} catch($e) {
$c->log->error("failed to create speed dial slot: $e");
$c->flash(messages => [{type => 'error', text => 'Failed to created speed dial slot'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
}
delete $c->stash->{used_sd_slots};
$c->stash(
template => 'subscriber/preferences.tt',
edit_cf_flag => 1,
cf_description => "Speed Dial Slot",
cf_form => $form,
close_target => $c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]),
);
}
sub speeddial :Chained('base') :PathPart('preferences/speeddial') :CaptureArgs(1) {
my ($self, $c, $sd_id) = @_;
my $sd = $c->stash->{subscriber}->provisioning_voip_subscriber->voip_speed_dials
->find($sd_id);
unless($sd) {
$c->log->error("no such speed dial slot with id '$sd_id' for uuid ".$c->stash->{subscriber}->uuid);
$c->flash(messages => [{type => 'error', text => 'No such speed dial id'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
$c->stash->{speeddial} = $sd;
}
sub delete_speeddial :Chained('speeddial') :PathPart('delete') :Args(0) {
my ($self, $c) = @_;
try {
$c->stash->{speeddial}->delete;
$c->flash(messages => [{type => 'success', text => 'Successfully deleted speed dial slot'}]);
} catch($e) {
$c->log->error("failed to delete speed dial slot: $e");
$c->flash(messages => [{type => 'error', text => 'Failed to delete speed dial slot'}]);
}
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
}
sub edit_speeddial :Chained('speeddial') :PathPart('edit') :Args(0) {
my ($self, $c) = @_;
my $posted = ($c->request->method eq 'POST');
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $slots = $prov_subscriber->voip_speed_dials;
$c->stash->{used_sd_slots} = $slots;
my $form = NGCP::Panel::Form::Subscriber::SpeedDial->new(ctx => $c);
my $params;
unless($posted) {
$params->{slot} = $c->stash->{speeddial}->slot;
$params->{destination} = $c->stash->{speeddial}->destination;
}
$form->process(params => $posted ? $c->req->params : $params);
if($posted && $form->validated) {
try {
my $d = $form->field('destination')->value;
if($d !~ /\@/) {
$d .= '@'.$prov_subscriber->domain->domain;
}
if($d !~ /^sip:/) {
$d = 'sip:' . $d;
}
$c->stash->{speeddial}->update({
slot => $form->field('slot')->value,
destination => $d,
});
$c->flash(messages => [{type => 'success', text => 'Successfully updated speed dial slot'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
} catch($e) {
$c->log->error("failed to update speed dial slot: $e");
$c->flash(messages => [{type => 'error', text => 'Failed to update speed dial slot'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
}
delete $c->stash->{used_sd_slots};
$c->stash(
template => 'subscriber/preferences.tt',
edit_cf_flag => 1,
cf_description => "Speed Dial Slot",
cf_form => $form,
close_target => $c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]),
);
}
=head1 AUTHOR
Andreas Granig,,,

@ -0,0 +1,77 @@
package NGCP::Panel::Form::Subscriber::SpeedDial;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use Moose::Util::TypeConstraints;
use HTML::FormHandler::Widget::Block::Bootstrap;
with 'NGCP::Panel::Render::RepeatableJs';
has '+widget_wrapper' => ( default => 'Bootstrap' );
sub build_render_list {[qw/fields actions/]}
sub build_form_element_class { [qw/form-horizontal/] }
has_field 'slot' => (
type => 'Select',
label => 'Slot',
options_method => \&set_slots,
required => 1,
wrapper_class => [qw/hfh-rep-field/],
);
sub set_slots {
my($self) = @_;
my @options = ();
my @used = ();
my $current;
if(defined $self->form->ctx &&
defined $self->form->ctx->stash->{used_sd_slots}) {
foreach my $s($self->form->ctx->stash->{used_sd_slots}->all) {
push @used, $s->slot;
}
}
if(defined $self->form->ctx &&
defined $self->form->ctx->stash->{speeddial}) {
$current = $self->form->ctx->stash->{speeddial}->slot;
}
foreach my $s(@{ $self->form->ctx->config->{speed_dial_vsc_presets}->{vsc} })
{
if($s ~~ @used) {
next unless(defined $current && $s eq $current);
}
push @options, { label => $s, value => $s };
}
return \@options;
}
has_field 'destination' => (
type => 'Text',
label => 'Destination',
required => 1,
wrapper_class => [qw/hfh-rep-field/],
);
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/slot destination/ ],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/save/],
);
1;
# vim: set tabstop=4 expandtab:

@ -35,3 +35,15 @@ log4perl.appender.Default.layout.ConversionPattern=%d{ISO8601} [%p] [%F +%L] %m{
path <sip:127.0.0.1:5062;lr>
</sip>
<speed_dial_vsc_presets>
vsc *0
vsc *1
vsc *2
vsc *3
vsc *4
vsc *5
vsc *6
vsc *7
vsc *8
vsc *9
</speed_dial_vsc_presets>

@ -13,7 +13,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,800">
<link rel="stylesheet" href="/css/font-opensans.css">
<link rel="stylesheet" href="/css/font-awesome.css">
<link rel="stylesheet" href="/css/bootstrap.css">

@ -85,13 +85,8 @@
[%
helper.name = 'Calls';
helper.column_sort = 'status';
helper.dt_columns = calls_dt_columns;
helper.column_sort = 'start_time';
helper.close_target = close_target;
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/subscriber/ajax_calls', [c.req.captures.0]);
@ -113,9 +108,6 @@
helper.column_sort = 'origtime';
helper.dt_columns = vm_dt_columns;
helper.close_target = close_target;
helper.create_flag = create_flag;
helper.edit_flag = edit_flag;
helper.form_object = form;
helper.ajax_uri = c.uri_for_action('/subscriber/ajax_voicemails', [c.req.captures.0]);

@ -296,6 +296,32 @@
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#preference_groups" href="#collapse_speed">Speed Dial</a>
</div>
<div class="accordion-body collapse" id="collapse_speed">
<div class="accordion-inner">
<a class="btn btn-tertiary button-large" href="[% c.uri_for_action('/subscriber/create_speeddial', [c.req.captures.0]) %]"><i class="icon-star"></i> Create Slot</a>
[%
helper.messages = '';
helper.name = 'Speeddial';
helper.column_sort = 'slot';
helper.dt_columns = sd_dt_columns;
helper.ajax_uri = c.uri_for_action('/subscriber/ajax_speeddial', [c.req.captures.0]);
helper.dt_buttons = [
{ name = 'Edit', uri = "preferences/speeddial/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = 'Delete', uri = "preferences/speeddial/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
];
PROCESS 'helpers/datatables.tt';
%]
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#preference_groups" href="#collapse_rm">Reminder</a>

Loading…
Cancel
Save