Switched to presented for ugly BS table column headers

This commit is contained in:
snipe 2017-02-03 22:20:11 -08:00
parent d37b9fe169
commit 1751a8c0e0
11 changed files with 293 additions and 271 deletions

View file

@ -38,7 +38,8 @@ class UsersController extends Controller
'users.company_id',
'users.deleted_at',
'users.activated'
])->with('manager', 'groups', 'userloc', 'company', 'throttle');
])->with('manager', 'groups', 'userloc', 'company', 'throttle','assets','licenses','accessories','consumables')
->withCount('assets','licenses','accessories','consumables');
$users = Company::scopeCompanyables($users);

View file

@ -366,9 +366,9 @@ class UsersController extends Controller
// Authorize takes care of many of our logic checks now.
$this->authorize('delete', User::class);
if ($user->assignedAssets()->count() > 0) {
if ($user->assets()->count() > 0) {
// Redirect to the user management page
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assignedAssets()->count() . ' assets associated with them.');
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
}
if ($user->licenses()->count() > 0) {
@ -1127,7 +1127,7 @@ class UsersController extends Controller
$user->email,
($user->manager) ? $user->manager->present()->fullName() : '',
($user->userloc) ? $user->userloc->name : '',
$user->assignedAssets->count(),
$user->assets->count(),
$user->licenses->count(),
$user->accessories->count(),
$user->consumables->count(),

View file

@ -36,6 +36,10 @@ class UsersTransformer
'two_factor_activated' => ($user->activated =='1') ? true : false,
'created_at' => $user->created_at,
'updated_at' => $user->updated_at,
'assets_count' => $user->assets_count,
'licenses_count' => $user->licenses_count,
'accessories_count' => $user->accessories_count,
'consumables_count' => $user->consumables_count,
];
return $array;

View file

@ -127,7 +127,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
/**
* Get assets assigned to this user
*/
public function assignedAssets()
public function assets()
{
return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
// return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed();

View file

@ -13,145 +13,94 @@ use Illuminate\Support\Facades\Gate;
class AssetPresenter extends Presenter
{
public function detail() {
return $this->model;
}
/**
* Bootstrap Table Bits
* @param array $all_custom_fields Preloaded cache of custom fields
* @return mixed
*/
public function forDataTable($all_custom_fields)
{
// Actions
$inout = '';
$actions = '<div style="white-space: nowrap;">';
if ($this->model->deleted_at=='') {
if (Gate::allows('create', $this->model)) {
$actions .= Helper::generateDatatableButton('clone', route('clone/hardware', $this->model->id));
}
if (Gate::allows('update', $this->model)) {
$actions .= Helper::generateDatatableButton('edit', route('hardware.edit', $this->model->id));
}
if (Gate::allows('delete', $this->model)) {
$actions .= Helper::generateDatatableButton(
'delete',
route('hardware.destroy', $this->model->id),
true, /*enabled*/
trans('admin/hardware/message.delete.confirm'),
$this->model->asset_tag
);
}
} elseif ($this->model->model->deleted_at=='') {
$actions .= Helper::generateDatatableButton('restore', route('restore/hardware', $this->model->id));
}
$actions .= '</div>';
if (($this->model->availableForCheckout())) {
if (Gate::allows('checkout', $this->model)) {
$inout = '<a href="' . route(
'checkout/hardware',
$this->model->id
) . '" class="btn btn-info btn-sm" title="Checkout this asset to a user" data-toggle="tooltip">' . trans('general.checkout') . '</a>';
}
} else {
if (!empty($this->model->assigned_to)) {
if (Gate::allows('checkin', $this->model)) {
$inout = '<a href="' . route(
'checkin/hardware',
$this->model->id
) . '" class="btn btn-primary btn-sm" title="Checkin this asset" data-toggle="tooltip">' . trans('general.checkin') . '</a>';
}
}
}
$results = [];
$results['checkbox'] = '<div class="text-center"><input type="checkbox" name="edit_asset['.$this->id.']" class="one_required"></div>';
$results['id'] = $this->id;
$results['name'] = $this->nameUrl();
$results['asset_tag'] = $this->assetTagUrl();
$results['serial'] = $this->serial;
$results['image'] = $this->imageUrl();
// Presets for when conditionals fail.
$results['model'] = $this->modelUrl();
$results['model_number'] = $this->model->model_number;
$results['category'] = $this->categoryUrl();
$results['manufacturer'] = $this->manufacturerUrl();
$results['status_label'] = '';
$results['assigned_to'] = '';
if ($assigned = $this->model->assignedTo) {
$results['assigned_to'] = $assigned->present()->glyph() . ' ' . $assigned->present()->nameUrl();
}
$results['status_label'] = $this->statusText();
$results['location'] = '';
if (isset($assigned) and !empty($assignedLoc = $this->model->assetLoc)) {
$results['location'] = $assignedLoc->present()->nameUrl();
} elseif (!empty($this->model->defaultLoc)) {
$results['location'] = $this->model->defaultLoc->present()->nameUrl();
}
$results['eol'] = $this->eol_date() ?: '';
$results['purchase_cost'] = Helper::formatCurrencyOutput($this->purchase_cost);
$results['purchase_date'] = $this->purchase_date ?: '';
$results['notes'] = $this->notes;
$results['order_number'] = $this->order_number;
if (!empty($this->order_number)) {
$results['order_number'] = link_to_route('hardware.index', $this->order_number, ['order_number' => $this->order_number]);
}
$results['last_checkout'] = $this->last_checkout ?: '';
$results['expected_checkin'] = $this->expected_checkin ?: '';
$results['created_at'] = '';
if (!empty($this->created_at)) {
$results['created_at'] = $this->created_at->format('F j, Y h:iA');
}
$results['companyName'] = $this->companyUrl();
$results['actions'] = $actions;
$results['change'] = $inout;
// Custom Field bits
foreach ($all_custom_fields as $field) {
$column_name = $field->db_column_name();
if ($field->isFieldDecryptable($this->model->{$column_name})) {
if (Gate::allows('admin')) {
if (($field->format=='URL') && ($this->model->{$column_name}!='')) {
$row[$column_name] = '<a href="'.Helper::gracefulDecrypt($field, $this->model->{$column_name}).'" target="_blank">'.Helper::gracefulDecrypt($field, $this->model->{$column_name}).'</a>';
} else {
$row[$column_name] = Helper::gracefulDecrypt($field, $this->model->{$column_name});
}
} else {
$row[$field->db_column_name()] = strtoupper(trans('admin/custom_fields/general.encrypted'));
}
} else {
if (($field->format=='URL') && ($this->model->{$field->db_column_name()}!='')) {
$row[$field->db_column_name()] = '<a href="'.$this->model->{$field->db_column_name()}.'" target="_blank">'.$this->model->{$field->db_column_name()}.'</a>';
} else {
$row[$field->db_column_name()] = e($this->model->{$field->db_column_name()});
}
}
}
return $results;
}
/**
* Generate html link to this items asset tag
* Json Column Layout for bootstrap table
* @return string
*/
public function assetTagUrl()
public static function dataTableLayout()
{
return (string) link_to_route('hardware.show', e($this->asset_tag), $this->id);
$layout = [
[
"field" => "company",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => '',
"visible" => true,
"formatter" => "companiesLinkObjFormatter"
], [
"field" => "name",
"searchable" => true,
"sortable" => true,
"title" => trans('admin/accessories/table.title'),
"formatter" => "accessoriesLinkFormatter"
], [
"field" => "category",
"searchable" => true,
"sortable" => true,
"title" => trans('admin/accessories/general.accessory_category'),
"formatter" => "categoriesLinkObjFormatter"
], [
"field" => "model_number",
"searchable" => true,
"sortable" => true,
"title" => trans('admin/models/table.modelnumber'),
"formatter" => "accessoriesLinkFormatter"
], [
"field" => "manufacturer",
"searchable" => true,
"sortable" => true,
"title" => trans('general.manufacturer'),
"formatter" => "manufacturersLinkObjFormatter",
], [
"field" => "location",
"searchable" => true,
"sortable" => true,
"title" => trans('general.location'),
"formatter" => "locationsLinkObjFormatter",
], [
"field" => "qty",
"searchable" => false,
"sortable" => false,
"title" => trans('admin/accessories/general.total'),
], [
"field" => "min_qty",
"searchable" => false,
"sortable" => true,
"title" => trans('general.min_amt'),
], [
"field" => "remaining_qty",
"searchable" => false,
"sortable" => false,
"title" => trans('admin/accessories/general.remaining'),
], [
"field" => "purchase_date",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.purchase_date'),
], [
"field" => "purchase_cost",
"searchable" => true,
"sortable" => true,
"title" => trans('general.purchase_cost'),
], [
"field" => "order_number",
"searchable" => true,
"sortable" => true,
"visible" => false,
"title" => trans('general.order_number'),
], [
"field" => "actions",
"searchable" => false,
"sortable" => false,
"switchable" => false,
"title" => trans('table.actions'),
"formatter" => "accessoriesActionsFormatter",
]
];
return json_encode($layout);
}
/**

View file

@ -14,81 +14,188 @@ use Illuminate\Support\Facades\Gate;
class UserPresenter extends Presenter
{
/**
* Generates json for bootstrap table.
* @param string $status Status of User to filter on
* @return array
* Json Column Layout for bootstrap table
* @return string
*/
public function forDataTable($status = null)
public static function dataTableLayout()
{
$group_names = '';
$actions = '<nobr>';
foreach ($this->model->groups as $group) {
$group_names .= link_to_route('update/group', $group->name, $group->id, ['class' => 'label label-default']);
}
if (!is_null($this->model->deleted_at)) {
if (Gate::allows('delete', $this)) {
$actions .= Helper::generateDatatableButton('restore', route('restore/user', $this->id));
}
} else {
if (Gate::allows('delete', $this)) {
if ($this->accountStatus() == 'suspended') {
$actions .= link_to_route(
'unsuspend/user',
'<span class="fa fa-clock-o"></span>"',
$this->id,
['class' => 'btn btn-default btn-sm']
);
}
}
if (Gate::allows('update', $this)) {
$actions .= Helper::generateDatatableButton('edit', route('users.edit', $this->id));
$actions .= Helper::generateDatatableButton('clone', route('clone/user', $this->id));
}
if (Gate::allows('delete', $this)) {
if ((Auth::user()->id !== $this->id) && (!config('app.lock_passwords'))) {
$actions .= Helper::generateDatatableButton(
'delete',
route('users.destroy', $this->id),
true, /*enabled*/
"Are you sure you wish to delete this user?",
$this->first_name
);
} else {
$actions .= ' <span class="btn delete-asset btn-danger btn-sm disabled"><i class="fa fa-trash icon-white"></i></span>';
}
}
}
$actions .= '</nobr>';
$result = [
'id' => $this->id,
'checkbox' => ($status!='deleted') ? '<div class="text-center hidden-xs hidden-sm"><input type="checkbox" name="edit_user['.e($this->id).']" class="one_required"></div>' : '',
'name' => $this->nameUrl(),
'jobtitle' => $this->jobtitle,
'email' => $this->emailLink(),
'username' => $this->username,
'location' => ($this->model->userloc) ? $this->model->userloc->present()->nameUrl() : '',
'manager' => ($this->model->manager) ? $this->manager->present()->nameUrl() : '',
'employee_num' => $this->employee_num,
'assets' => $this->model->assignedAssets()->count(),
'licenses' => $this->model->licenses()->count(),
'accessories' => $this->model->accessories()->count(),
'consumables' => $this->model->consumables()->count(),
'groups' => $group_names,
'notes' => $this->notes,
'two_factor_enrolled' => ($this->two_factor_enrolled=='1') ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'two_factor_optin' => (($this->two_factor_optin=='1') || (Setting::getSettings()->two_factor_enabled=='2') ) ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'created_at' => ($this->model->created_at!='') ? e($this->model->created_at->format('F j, Y h:iA')) : '',
'activated' => ($this->activated=='1') ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'actions' => $actions ?: '',
'companyName' => $this->companyUrl()
$layout = [
[
"field" => "checkbox",
"searchable" => false,
"sortable" => false,
"switchable" => false,
"title" => trans('admin/companies/table.title'),
"visible" => false,
"checkbox" => true
],
[
"field" => "id",
"searchable" => false,
"sortable" => true,
"switchable" => true,
"title" => trans('general.id'),
"visible" => false
],
[
"field" => "company",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/companies/table.title'),
"visible" => false,
"formatter" => "companiesLinkObjFormatter"
],
[
"field" => "name",
"searchable" => true,
"sortable" => true,
"title" => trans('admin/users/table.name'),
"visible" => true,
"formatter" => "usersLinkFormatter"
],
[
"field" => "jobtitle",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/users/table.title'),
"visible" => true,
"formatter" => "usersLinkFormatter"
],
[
"field" => "email",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/users/table.email'),
"visible" => true,
"formatter" => "emailFormatter"
],
[
"field" => "username",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/users/table.username'),
"visible" => true,
"formatter" => "usersLinkFormatter"
],
[
"field" => "location",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('admin/users/table.location'),
"true" => false,
"formatter" => "locationsLinkObjFormatter"
],
[
"field" => "assets_count",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => ' <span class="hidden-md hidden-lg">Assets</span>'
.'<span class="hidden-xs"><i class="fa fa-barcode fa-lg"></i></span>',
"visible" => true,
],
[
"field" => "licenses_count",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => ' <span class="hidden-md hidden-lg">Licenses</span>'
.'<span class="hidden-xs"><i class="fa fa-floppy-o fa-lg"></i></span>',
"visible" => true,
],
[
"field" => "consumables_count",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => ' <span class="hidden-md hidden-lg">Consumables</span>'
.'<span class="hidden-xs"><i class="fa fa-tint fa-lg"></i></span>',
"visible" => true,
],
[
"field" => "accessories_count",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => ' <span class="hidden-md hidden-lg">Accessories</span>'
.'<span class="hidden-xs"><i class="fa fa-keyboard-o fa-lg"></i></span>',
"visible" => true,
],
[
"field" => "notes",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('general.notes'),
"visible" => true,
],
[
"field" => "groups",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => trans('general.groups'),
"visible" => true,
'formatter' => 'groupsFormatter'
],
[
"field" => "two_factor_enrolled",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => trans('admin/users/general.two_factor_enrolled'),
"visible" => false,
'formatter' => 'trueFalseFormatter'
],
[
"field" => "two_factor_active",
"searchable" => false,
"sortable" => false,
"switchable" => true,
"title" => trans('admin/users/general.two_factor_active'),
"visible" => false,
'formatter' => 'trueFalseFormatter'
],
[
"field" => "activated",
"searchable" => false,
"sortable" => true,
"switchable" => true,
"title" => trans('general.activated'),
"visible" => true,
'formatter' => 'trueFalseFormatter'
],
[
"field" => "created_at",
"searchable" => true,
"sortable" => true,
"switchable" => true,
"title" => trans('general.created_at'),
"visible" => false,
'formatter' => 'createdAtFormatter'
],
[
"field" => "actions",
"searchable" => false,
"sortable" => false,
"switchable" => false,
"title" => trans('table.actions'),
"visible" => true,
"formatter" => "accessoriesActionsFormatter",
]
];
return $result;
return json_encode($layout);
}
public function emailLink()
{
if ($this->email) {

View file

@ -23,7 +23,7 @@ View Assets for {{ $user->present()->fullName() }}
<div class="box-body">
<!-- checked out assets table -->
@if (count($user->assignedAssets) > 0)
@if (count($user->assets) > 0)
<div class="table-responsive">
<table class="table table-striped">
<thead>
@ -35,7 +35,7 @@ View Assets for {{ $user->present()->fullName() }}
</tr>
</thead>
<tbody>
@foreach ($user->assignedAssets as $asset)
@foreach ($user->assets as $asset)
<tr>
<td>
@if ($asset->physical=='1')

View file

@ -3,21 +3,21 @@
@section('title0')
@if (Input::get('status'))
@if (Input::get('status')=='Pending')
{{ trans('general.pending') }}
@elseif (Input::get('status')=='RTD')
{{ trans('general.ready_to_deploy') }}
@elseif (Input::get('status')=='Undeployable')
{{ trans('general.undeployable') }}
@elseif (Input::get('status')=='Deployable')
{{ trans('general.deployed') }}
@elseif (Input::get('status')=='Requestable')
{{ trans('admin/hardware/general.requestable') }}
@elseif (Input::get('status')=='Archived')
{{ trans('general.archived') }}
@elseif (Input::get('status')=='Deleted')
{{ trans('general.deleted') }}
@endif
@if (Input::get('status')=='Pending')
{{ trans('general.pending') }}
@elseif (Input::get('status')=='RTD')
{{ trans('general.ready_to_deploy') }}
@elseif (Input::get('status')=='Undeployable')
{{ trans('general.undeployable') }}
@elseif (Input::get('status')=='Deployable')
{{ trans('general.deployed') }}
@elseif (Input::get('status')=='Requestable')
{{ trans('admin/hardware/general.requestable') }}
@elseif (Input::get('status')=='Archived')
{{ trans('general.archived') }}
@elseif (Input::get('status')=='Deleted')
{{ trans('general.deleted') }}
@endif
@else
{{ trans('general.all') }}
@endif

View file

@ -70,7 +70,7 @@ Bulk Checkin &amp;amp; Delete
@endforeach
</td>
<td>
{{ number_format($user->assignedAssets()->count()) }}
{{ number_format($user->assets()->count()) }}
</td>
<td>
{{ number_format($user->accessories()->count()) }}

View file

@ -67,50 +67,7 @@
data-cookie="true"
data-click-to-select="true"
data-cookie-id-table="userTableDisplay-{{ config('version.hash_version') }}">
<thead>
<tr>
@if (Input::get('status')!='deleted')
<th data-checkbox="true" data-field="checkbox"></th>
@endif
<th data-switchable="true" data-sortable="true" data-field="id" data-visible="false">{{ trans('general.id') }}</th>
<th data-switchable="true" data-sortable="false" data-field="company" data-visible="false">{{ trans('admin/companies/table.title') }}</th>
<th data-switchable="true" data-sortable="true" data-field="employee_num" data-visible="false">{{ trans('admin/users/table.employee_num') }}</th>
<th data-sortable="true" data-field="name" data-formatter="usersLinkFormatter">{{ trans('admin/users/table.name') }}</th>
<th data-switchable="true" data-sortable="true" data-field="jobtitle" data-visible="false">{{ trans('admin/users/table.title') }}</th>
<th data-sortable="true" data-field="email" data-formatter="emailFormatter">
{{ trans('admin/users/table.email') }}
</th>
<th data-sortable="true" data-field="username">{{ trans('admin/users/table.username') }}</th>
<th data-searchable="true" data-sortable="true" data-field="manager" data-formatter="usersLinkObjFormatter">{{ trans('admin/users/table.manager') }}</th>
<th data-sortable="true" data-field="location" data-formatter="locationsLinkObjFormatter">{{ trans('admin/users/table.location') }}</th>
<th data-sortable="false" data-field="assets">
<span class="hidden-md hidden-lg">Assets</span>
<span class="hidden-xs"><i class="fa fa-barcode fa-lg"></i></span>
</th>
<th data-sortable="false" data-field="licenses">
<span class="hidden-md hidden-lg">Licenses</span>
<span class="hidden-xs"><i class="fa fa-floppy-o fa-lg"></i></span>
</th>
<th data-sortable="false" data-field="accessories">
<span class="hidden-md hidden-lg">Accessories</span>
<span class="hidden-xs"><i class="fa fa-keyboard-o fa-lg"></i></span>
</th>
<th data-sortable="false" data-field="consumables">
<span class="hidden-md hidden-lg">Consumables</span>
<span class="hidden-xs"><i class="fa fa-tint fa-lg"></i></span>
</th>
<th data-sortable="false" data-field="groups" data-formatter="groupsFormatter">
{{ trans('general.groups') }}
</th>
<th data-sortable="true" data-field="notes">{{ trans('general.notes') }}</th>
<th data-sortable="true" data-field="two_factor_enrolled" data-visible="false" data-formatter="trueFalseFormatter" class="text-center">{{ trans('admin/users/general.two_factor_enrolled') }}</th>
<th data-sortable="true" data-field="two_factor_optin" data-formatter="trueFalseFormatter" data-visible="false" class="text-center">{{ trans('admin/users/general.two_factor_active') }}</th>
<th data-sortable="true" data-field="activated" class="text-center" data-formatter="trueFalseFormatter">{{ trans('general.activated') }}</th>
<th data-sortable="true" data-field="created_at" data-searchable="true" data-visible="false" data-formatter="createdAtFormatter">{{ trans('general.created_at') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-formatter="usersActionsFormatter" data-field="actions" >{{ trans('table.actions') }}</th>
</tr>
</thead>
</table>
{{ Form::close() }}
@ -122,7 +79,11 @@
@stop
@section('moar_scripts')
@include ('partials.bootstrap-table', ['exportFile' => 'users-export', 'search' => true])
@include ('partials.bootstrap-table',
['exportFile' => 'users-export',
'search' => true,
'columns' => \App\Presenters\UserPresenter::dataTableLayout()
])
<script>

View file

@ -228,7 +228,7 @@
</tr>
</thead>
<tbody>
@foreach ($user->assignedAssets as $asset)
@foreach ($user->assets as $asset)
<tr>
<td>
@if ($asset->physical=='1')