Merge pull request #969 from snipe/inline_adding

Inline adding of dependent drop-down contents on asset-creation
This commit is contained in:
snipe
2015-07-27 23:39:07 -07:00
9 changed files with 399 additions and 20 deletions
@@ -27,6 +27,7 @@ use Mail;
use Datatable;
use TCPDF;
use Slack;
use Manufacturer; //for embedded-create
class AssetsController extends AdminController
{
@@ -77,6 +78,11 @@ class AssetsController extends AdminController
// Grab the dropdown list of status
$statuslabel_list = array('' => Lang::get('general.select_statuslabel')) + Statuslabel::orderBy('name', 'asc')->lists('name', 'id');
// grap dropdown lists for embedded create drop-downs
$manufacturer_list = array('' => 'Select One') + Manufacturer::lists('name', 'id');
$category_list = array('' => '') + DB::table('categories')->whereNull('deleted_at')->lists('name', 'id');
$view = View::make('backend/hardware/edit');
$view->with('supplier_list',$supplier_list);
@@ -85,6 +91,8 @@ class AssetsController extends AdminController
$view->with('assigned_to',$assigned_to);
$view->with('location_list',$location_list);
$view->with('asset',new Asset);
$view->with('manufacturer',$manufacturer_list);
$view->with('category',$category_list);
if (!is_null($model_id)) {
$selected_model = Model::find($model_id);
@@ -12,6 +12,8 @@ use Str;
use Validator;
use View;
use Symfony\Component\HttpFoundation\JsonResponse;
class LocationsController extends AdminController
{
/**
@@ -97,6 +99,52 @@ class LocationsController extends AdminController
return Redirect::to('admin/settings/locations/create')->with('error', Lang::get('admin/locations/message.create.error'));
}
public function store()
{
$new = Input::all();
$new['currency']=Setting::first()->default_currency;
// create a new location instance
$location = new Location();
// attempt validation
if ($location->validate($new)) {
// Save the location data
$location->name = e(Input::get('name'));
// if (Input::get('parent_id')=='') {
// $location->parent_id = null;
// } else {
// $location->parent_id = e(Input::get('parent_id'));
// }
$location->currency = Setting::first()->default_currency; //e(Input::get('currency'));
$location->address = ''; //e(Input::get('address'));
// $location->address2 = e(Input::get('address2'));
$location->city = e(Input::get('city'));
$location->state = '';//e(Input::get('state'));
$location->country = e(Input::get('country'));
// $location->zip = e(Input::get('zip'));
$location->user_id = Sentry::getId();
// Was the asset created?
if($location->save()) {
// Redirect to the new location page
return JsonResponse::create($location);
//return Redirect::to("admin/settings/locations")->with('success', Lang::get('admin/locations/message.create.success'));
} else {
return JsonResponse::create(["error" => "Couldn't save Location"],500);
}
} else {
// failure
$errors = $location->errors();
return JsonResponse::create(["error" => "Failed validation: ".print_r($errors->all('<li>:message</li>'),true)],500);
}
// Redirect to the location create page
return Redirect::to('admin/settings/locations/create')->with('error', Lang::get('admin/locations/message.create.error'));
}
/**
@@ -16,6 +16,9 @@ use Validator;
use View;
use Datatable;
//use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
class ModelsController extends AdminController
{
/**
@@ -114,6 +117,35 @@ class ModelsController extends AdminController
return Redirect::to('hardware/models/create')->with('error', Lang::get('admin/models/message.create.error'));
}
public function store()
{
//COPYPASTA!!!! FIXME
$model = new Model;
$settings=Input::all();
$settings['eol']=0;
//
$validator = Validator::make($settings, $model->validationRules());
if ($validator->fails())
{
// The given data did not pass validation
return JsonResponse::create(["error" => "Failed validation: ".print_r($validator->messages()->all('<li>:message</li>'),true)],500);
} else {
$model->name=e(Input::get('name'));
$model->manufacturer_id=e(Input::get('manufacturer_id'));
$model->category_id=e(Input::get('category_id'));
$model->user_id=Sentry::getUser()->id;
$model->eol=0;
if($model->save()) {
return JsonResponse::create($model);
} else {
return JsonResponse::create(["error" => "Couldn't save Model"],500);
}
}
}
/**
* Model update.
@@ -12,6 +12,8 @@ use Str;
use Validator;
use View;
use Symfony\Component\HttpFoundation\JsonResponse;
class StatuslabelsController extends AdminController
{
/**
@@ -89,6 +91,43 @@ class StatuslabelsController extends AdminController
return Redirect::to('admin/settings/statuslabels/create')->with('error', Lang::get('admin/statuslabels/message.create.error'));
}
public function store()
{
// get the POST data
$new = Input::all();
$new['statuslabel_types']="deployable";
// create a new model instance
$statuslabel = new Statuslabel();
// attempt validation
if ($statuslabel->validate($new)) {
//$statustype = Statuslabel::getStatuslabelTypesForDB(Input::get('statuslabel_types'));
// Save the Statuslabel data
$statuslabel->name = e(Input::get('name'));
$statuslabel->user_id = Sentry::getId();
//$statuslabel->notes = e(Input::get('notes'));
$statuslabel->deployable = true; //$statustype['deployable'];
$statuslabel->pending = false; //$statustype['pending'];
$statuslabel->archived = false; //$statustype['archived'];
// Was the asset created?
if($statuslabel->save()) {
// Redirect to the new Statuslabel page
return JsonResponse::create($statuslabel);
} else {
return JsonResponse::create(["error" => "Couldn't save Statuslabel"],500);
}
} else {
// failure
$errors = $statuslabel->errors();
return JsonResponse::create(["error" => "Failed validation: ".print_r($errors->all('<li>:message</li>'),true)],500);
}
}
/**
@@ -13,6 +13,9 @@ use Str;
use Validator;
use View;
use Symfony\Component\HttpFoundation\JsonResponse;
class SuppliersController extends AdminController
{
/**
@@ -100,6 +103,26 @@ class SuppliersController extends AdminController
return Redirect::to('admin/settings/suppliers/create')->with('error', Lang::get('admin/suppliers/message.create.error'));
}
public function store()
{
$supplier=new Supplier;
$new=Input::all();
$validator = Validator::make($new, $supplier->validationRules());
if($validator->fails()) {
return JsonResponse::create(["error" => "Failed validation: ".print_r($validator->messages()->all('<li>:message</li>'),true)],500);
} else {
//$supplier->fill($new);
$supplier->name=$new['name'];
$supplier->user_id = Sentry::getId();
if($supplier->save()) {
return JsonResponse::create($supplier);
} else {
return JsonResponse::create(["error" => "Couldn't save Supplier"]);
}
}
}
/**
* Supplier update.
+61
View File
@@ -27,6 +27,7 @@ use Datatable;
use League\Csv\Reader;
use Mail;
use Accessory;
use Symfony\Component\HttpFoundation\JsonResponse;
class UsersController extends AdminController
{
@@ -187,6 +188,66 @@ class UsersController extends AdminController
// Redirect to the user creation page
return Redirect::route('create/user')->withInput()->with('error', $error);
}
public function store()
{
// Create a new validator instance from our validation rules
$validator = Validator::make(Input::all(), $this->validationRules);
$permissions = Input::get('permissions', array());
$this->decodePermissions($permissions);
app('request')->request->set('permissions', $permissions);
// If validation fails, we'll exit the operation now.
if ($validator->fails()) {
// Ooops.. something went wrong
return JsonResponse::create(["error" => "Failed validation: ".print_r($validator->messages()->all('<li>:message</li>'),true)],500); }
try {
// We need to reverse the UI specific logic for our
// permissions here before we create the user.
// Get the inputs, with some exceptions
$inputs = Input::except('csrf_token', 'password_confirm', 'groups','email_user');
// @TODO: Figure out WTF I need to do this.
/*if ($inputs['manager_id']=='') {
unset($inputs['manager_id']);
}*/
/*if ($inputs['location_id']=='') {
unset($inputs['location_id']);
}*/
// Was the user created?
if ($user = Sentry::getUserProvider()->create($inputs)) {
if (Input::get('email_user')==1) {
// Send the credentials through email
$data = array();
$data['email'] = e(Input::get('email'));
$data['first_name'] = e(Input::get('first_name'));
$data['password'] = e(Input::get('password'));
Mail::send('emails.send-login', $data, function ($m) use ($user) {
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
$m->subject('Welcome ' . $user->first_name);
});
}
return JsonResponse::create($user);
} else {
return JsonResponse::create(["error" => "Couldn't save User"],500);
}
} catch (Exception $e) {
// Redirect to the user creation page
return JsonResponse::create(["error" => "Failed validation: ".print_r($validator->messages()->all('<li>:message</li>'),true)],500);
}
}
/**
* User update.
+6 -2
View File
@@ -8,7 +8,7 @@
* Country macro
* Generates the dropdown menu of countries for the profile form
*/
Form::macro('countries', function ($name = "country", $selected = null, $class = null) {
Form::macro('countries', function ($name = "country", $selected = null, $class = null, $id = null) {
$countries = array(
''=>"Select a Country",
@@ -262,7 +262,11 @@ Form::macro('countries', function ($name = "country", $selected = null, $class =
'ZW'=>'Zimbabwe'
);
$select = '<select name="'.$name.'" class="'.$class.'" style="min-width:350px">';
$idclause='';
if($id) {
$idclause=" id='$id'";
}
$select = '<select name="'.$name.'" class="'.$class.'" style="min-width:350px"'.$idclause.'>';
foreach ($countries as $abbr => $country) {
$select .= '<option value="'.strtoupper($abbr).'"'.(strtoupper($selected)== strtoupper($abbr) ? ' selected="selected"' : '').'>'.$country.'</option> ';
+16 -10
View File
@@ -12,14 +12,15 @@ Route::group(array('prefix' => 'api', 'namespace' => 'Controllers\Admin', 'befor
/*---Status Label API---*/
Route::group(array('prefix'=>'statuslabels'), function() {
Route::get('{statuslabelId}/deployable', function ($statuslabelId) {
$statuslabel = Statuslabel::find($statuslabelId);
if (($statuslabel->deployable=='1') && ($statuslabel->pending!='1') && ($statuslabel->archived!='1')) {
return '1';
} else {
return '0';
}
});
Route::resource('/','StatuslabelsController');
Route::get('{statuslabelId}/deployable', function ($statuslabelId) {
$statuslabel = Statuslabel::find($statuslabelId);
if (($statuslabel->deployable=='1') && ($statuslabel->pending!='1') && ($statuslabel->archived!='1')) {
return '1';
} else {
return '0';
}
});
});
/*---Accessories API---*/
@@ -46,9 +47,10 @@ Route::group(array('prefix' => 'api', 'namespace' => 'Controllers\Admin', 'befor
/*---Locations API---*/
Route::group(array('prefix'=>'locations'), function() {
Route::resource('/','LocationsController');
Route::get('{locationID}/check', function ($locationID) {
$location = Location::find($locationID);
return $location;
$location = Location::find($locationID);
return $location;
});
});
@@ -73,6 +75,10 @@ Route::group(array('prefix' => 'api', 'namespace' => 'Controllers\Admin', 'befor
Route::get('list', ['as'=>'api.categories.list', 'uses'=>'CategoriesController@getDatatable']);
Route::get('{categoryID}/view', ['as'=>'api.categories.view', 'uses'=>'CategoriesController@getDataView']);
});
/*-- Suppliers API (mostly for creating new ones in-line while creating an asset) --*/
Route::group(['prefix'=>'suppliers'], function () {
Route::resource('/', 'SuppliersController');
});
});
/*
+166 -8
View File
@@ -9,6 +9,81 @@
@endif
@parent
@stop
{{-- Some room for the modals --}}
<div class="modal fade" id="createModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<label for="modal-name" class="dynamic-form-element">Name:
<input type='text' id='modal-name' class="form-control">
<br>
</label>
<label for="modal-manufacturer_id" class="dynamic-form-element">Manufacturer:
{{ Form::select('modal-manufacturer', $manufacturer , '', array('class'=>'select2 parent', 'style'=>'width:350px','id' =>'modal-manufacturer_id')) }}
<br>
</label>
<label for="modal-category_id" class="dynamic-form-element">Category:
{{ Form::select('modal-category', $category ,'', array('class'=>'select2 parent', 'style'=>'width:350px','id' => 'modal-category_id')) }}
<br>
</label>
<label for="modal-city" class="dynamic-form-element">City:
<input type='text' id='modal-city' class="form-control">
<br>
</label>
<label for="modal-country" class="dynamic-form-element">Country:
{{ Form::countries('country', Input::old('country'), 'select2 country',"modal-country") }}
<br>
</label>
<label for="modal-first_name" class="dynamic-form-element">First Name:
<input type='text' id='modal-first_name' class="form-control">
<br>
</label>
<label for="modal-last_name" class="dynamic-form-element">Last Name:
<input type='text' id='modal-last_name' class="form-control">
<br>
</label>
<label for="modal-username" class="dynamic-form-element">Username:
<input type='text' id='modal-username' class="form-control">
<br>
</label>
<label for="modal-password" class="dynamic-form-element">Password:
<input type='password' id='modal-password' class="form-control">
<br>
</label>
<label for="modal-password_confirm" class="dynamic-form-element">Confirm Password:
<input type='password' id='modal-password_confirm' class="form-control">
</label>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="modal-save">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{{-- Page content --}}
@@ -81,14 +156,14 @@
</label>
<div class="col-md-7 col-sm-12">
@if (isset($selected_model))
{{ Form::select('model_id', $model_list , $selected_model->id, array('class'=>'select2 model', 'style'=>'min-width:400px')) }}
{{ Form::select('model_id', $model_list , $selected_model->id, array('class'=>'select2 model', 'style'=>'min-width:400px','id' =>'model_select_id')) }}
@else
{{ Form::select('model_id', $model_list , Input::old('model_id', $asset->model_id), array('class'=>'select2 model', 'style'=>'min-width:400px')) }}
{{ Form::select('model_id', $model_list , Input::old('model_id', $asset->model_id), array('class'=>'select2 model', 'style'=>'min-width:400px','id' =>'model_select_id')) }}
@endif
<span class="mac_spinner" style="padding-left: 10px; color: green; display:none; width: 30px;"><i class="fa fa-spinner fa-spin"></i> </span>
<a href='#' data-toggle="modal" data-target="#createModal" data-dependency="model" data-select="model_select_id">Add new Model...</a> <!-- onclick="return dependency('model')" -->
{{ $errors->first('model_id', '<br><span class="alert-msg"><i class="fa fa-times"></i> :message</span>') }}
</div>
</div>
@@ -116,7 +191,8 @@
<div class="form-group {{ $errors->has('supplier_id') ? ' has-error' : '' }}">
<label for="supplier_id" class="col-md-2 control-label">@lang('admin/hardware/form.supplier')</label>
<div class="col-md-7 col-sm-12">
{{ Form::select('supplier_id', $supplier_list , Input::old('supplier_id', $asset->supplier_id), array('class'=>'select2', 'style'=>'min-width:350px')) }}
{{ Form::select('supplier_id', $supplier_list , Input::old('supplier_id', $asset->supplier_id), array('class'=>'select2', 'style'=>'min-width:350px','id'=>'supplier_select_id')) }}
<a href='#' data-toggle="modal" data-target="#createModal" data-dependency="supplier" data-select='supplier_select_id'>Add new Supplier...</a>
{{ $errors->first('supplier_id', '<br><span class="alert-msg"><i class="fa fa-times"></i> :message</span>') }}
</div>
</div>
@@ -165,8 +241,8 @@
<div class="form-group {{ $errors->has('status_id') ? ' has-error' : '' }}">
<label for="status_id" class="col-md-2 control-label">@lang('admin/hardware/form.status') <i class='fa fa-asterisk'></i></label>
<div class="col-md-7 col-sm-12 col-sm-12">
{{ Form::select('status_id', $statuslabel_list , Input::old('status_id', $asset->status_id), array('class'=>'select2 status_id', 'style'=>'width:350px')) }}
{{ Form::select('status_id', $statuslabel_list , Input::old('status_id', $asset->status_id), array('class'=>'select2 status_id', 'style'=>'width:350px','id'=>'status_select_id')) }}
<a href='#' data-toggle="modal" data-target="#createModal" data-dependency='statuslabel' data-select='status_select_id'>Add new Status...</a>
<span class="status_spinner" style="padding-left: 10px; color: green; display:none; width: 30px;"><i class="fa fa-spinner fa-spin"></i> </span>
<p class="help-block">@lang('admin/hardware/form.help_checkout')</p>
@@ -181,6 +257,7 @@
</label>
<div class="col-md-7 col-sm-12">
{{ Form::select('assigned_to', $assigned_to , Input::old('assigned_to', $asset->assigned_to), array('class'=>'select2', 'id'=>'assigned_to', 'style'=>'min-width:350px')) }}
<a href='#' data-toggle="modal" data-target="#createModal" data-dependency="user" data-select='assigned_to'>Add new User...</a>
{{ $errors->first('assigned_to', '<br><span class="alert-msg"><i class="fa fa-times"></i> :message</span>') }}
</div>
</div>
@@ -199,7 +276,8 @@
<div class="form-group {{ $errors->has('rtd_location_id') ? ' has-error' : '' }}">
<label for="rtd_location_id" class="col-md-2 control-label">@lang('admin/hardware/form.default_location')</label>
<div class="col-md-7 col-sm-12">
{{ Form::select('rtd_location_id', $location_list , Input::old('rtd_location_id', $asset->rtd_location_id), array('class'=>'select2', 'style'=>'width:350px')) }}
{{ Form::select('rtd_location_id', $location_list , Input::old('rtd_location_id', $asset->rtd_location_id), array('class'=>'select2', 'style'=>'width:350px','id'=>'rtd_location_select')) }}
<a href='#' data-toggle="modal" data-target="#createModal" data-dependency='location' data-select='rtd_location_select'>Add new Location...</a>
{{ $errors->first('rtd_location_id', '<br><span class="alert-msg"><i class="fa fa-times"></i> :message</span>') }}
</div>
</div>
@@ -290,8 +368,88 @@
}
};
$(function () {
var model,select;
$('#createModal').on("show.bs.modal",function (event) {
var link = $(event.relatedTarget);
// data-dependency="model" data-select="model_select_id"
model=link.data("dependency");
select=link.data("select");
var modal = $(this);
modal.find('.modal-title').text('Add a new ' + model);
//modal.find('.modal-body').text("This is where I should be AJAX'ing in the contents for the new " +model+" that you'are about to add!");
//use a spinner instead?
$('.dynamic-form-element').hide();
function show_er(selector) {
$(selector).show().parent().show();
}
show_er('#modal-name');
switch(model) {
case 'model':
show_er('#modal-manufacturer_id');
show_er('#modal-category_id');
break;
case 'user':
$('.dynamic-form-element').hide(); //we don't want a generic "name"
show_er("#modal-first_name");
show_er("#modal-last_name");
show_er("#modal-username");
show_er("#modal-password");
show_er("#modal-password_confirm");
break;
case 'location':
show_er('#modal-city');
show_er('#modal-country');
break;
case 'supplier':
case 'status':
//do nothing, they just need 'name'
}
console.warn("The Model is: "+model+" and the select is: "+select);
});
$('#modal-save').on('click',function () {
var data={};
console.warn("We are about to SAVE!!! for model: "+model+" and select ID: "+select);
$('.modal-body input:visible').each(function (index,elem) {
console.warn("["+index+"]: "+elem.id+" = "+$(elem).val());
var bits=elem.id.split("-");
if(bits[0]==="modal") {
data[bits[1]]=$(elem).val();
}
});
$('.modal-body select:visible').each(function (index,elem) {
var bits=elem.id.split("-");
data[bits[1]]=$(elem).val();
});
console.dir(data);
$.post("{{Config::get('app.url')}}/api/"+model+"s",data,function (result) {
var id=result.id;
var name=result.name || (result.first_name+" "+result.last_name);
$('.modal-body input:visible').val("");
$('#createModal').modal('hide');
console.warn("The select ID thing we're going for is: "+select);
var selector=document.getElementById(select);
selector.options[selector.length]=new Option(name,id);
selector.selectedIndex=selector.length-1;
$(selector).trigger("change");
}).fail(function (result) {
//console.dir(result.responseJSON);
msg=result.responseJSON.error.message || result.responseJSON.error;
window.alert("Unable to add new "+model+" - error: "+msg);
});
});
});
</script>
@stop