mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-13 17:14:10 -08:00
Merge remote-tracking branch 'origin/master' into develop
Signed-off-by: snipe <snipe@snipe.net> # Conflicts: # app/Http/Controllers/Api/AssetsController.php # app/Http/Transformers/AssetsTransformer.php # app/Importer/ConsumableImporter.php # app/Models/Consumable.php # config/version.php # package-lock.json # package.json # public/css/dist/all.css # public/css/dist/bootstrap-table.css # public/js/build/app.js # public/js/dist/all.js # public/js/dist/bootstrap-table.js # public/mix-manifest.json # resources/views/custom_fields/fieldsets/view.blade.php # resources/views/layouts/default.blade.php # routes/web.php # routes/web/fields.php
This commit is contained in:
commit
f2f8f96991
|
@ -96,6 +96,8 @@ RUN \
|
||||||
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
||||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||||
|
&& ln -fs "/var/lib/snipeit/keys/ldap_client_tls.cert" "/var/www/html/storage/ldap_client_tls.cert" \
|
||||||
|
&& ln -fs "/var/lib/snipeit/keys/ldap_client_tls.key" "/var/www/html/storage/ldap_client_tls.key" \
|
||||||
&& chown docker "/var/lib/snipeit/keys/" \
|
&& chown docker "/var/lib/snipeit/keys/" \
|
||||||
&& chown -h docker "/var/www/html/storage/" \
|
&& chown -h docker "/var/www/html/storage/" \
|
||||||
&& chmod +x /var/www/html/artisan \
|
&& chmod +x /var/www/html/artisan \
|
||||||
|
|
|
@ -171,6 +171,7 @@ class AssetsController extends Controller
|
||||||
// case we override with the actual count, so we should return 0 items.
|
// case we override with the actual count, so we should return 0 items.
|
||||||
$offset = (($assets) && ($request->get('offset') > $assets->count())) ? $assets->count() : $request->get('offset', 0);
|
$offset = (($assets) && ($request->get('offset') > $assets->count())) ? $assets->count() : $request->get('offset', 0);
|
||||||
|
|
||||||
|
|
||||||
// Check to make sure the limit is not higher than the max allowed
|
// Check to make sure the limit is not higher than the max allowed
|
||||||
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
|
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
|
||||||
|
|
||||||
|
@ -336,6 +337,7 @@ class AssetsController extends Controller
|
||||||
return (new $transformer)->transformAssets($assets, $total, $request);
|
return (new $transformer)->transformAssets($assets, $total, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns JSON with information about an asset (by tag) for detail view.
|
* Returns JSON with information about an asset (by tag) for detail view.
|
||||||
*
|
*
|
||||||
|
@ -373,9 +375,19 @@ class AssetsController extends Controller
|
||||||
}
|
}
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
|
||||||
|
|
||||||
|
$assets = Asset::with('assetstatus')->with('assignedTo');
|
||||||
|
|
||||||
|
if ($request->input('deleted', 'false') === 'true') {
|
||||||
|
$assets = $assets->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$assets = $assets->where('serial', $serial)->get();
|
||||||
|
if ($assets) {
|
||||||
|
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
|
||||||
|
} else {
|
||||||
|
return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns JSON with information about an asset for detail view.
|
* Returns JSON with information about an asset for detail view.
|
||||||
|
@ -677,6 +689,8 @@ class AssetsController extends Controller
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore a soft-deleted asset.
|
* Restore a soft-deleted asset.
|
||||||
*
|
*
|
||||||
|
|
|
@ -114,25 +114,14 @@ class AssetsTransformer
|
||||||
}
|
}
|
||||||
|
|
||||||
$permissions_array['available_actions'] = [
|
$permissions_array['available_actions'] = [
|
||||||
'checkout' => Gate::allows('checkout', Asset::class),
|
'checkout' => ($asset->deleted_at=='' && Gate::allows('checkout', Asset::class)) ? true : false,
|
||||||
'checkin' => Gate::allows('checkin', Asset::class),
|
'checkin' => ($asset->deleted_at=='' && Gate::allows('checkin', Asset::class)) ? true : false,
|
||||||
'clone' => false,
|
'clone' => Gate::allows('create', Asset::class) ? true : false,
|
||||||
'restore' => false,
|
'restore' => ($asset->deleted_at!='' && Gate::allows('create', Asset::class)) ? true : false,
|
||||||
'update' => (bool) Gate::allows('update', Asset::class),
|
'update' => ($asset->deleted_at=='' && Gate::allows('update', Asset::class)) ? true : false,
|
||||||
'delete' => ($asset->assigned_to == '' && Gate::allows('delete', Asset::class)),
|
'delete' => ($asset->deleted_at=='' && $asset->assigned_to =='' && Gate::allows('delete', Asset::class)) ? true : false,
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($asset->deleted_at != '') {
|
|
||||||
$permissions_array['available_actions'] = [
|
|
||||||
'checkout' => true,
|
|
||||||
'checkin' => false,
|
|
||||||
'clone' => Gate::allows('create', Asset::class),
|
|
||||||
'restore' => Gate::allows('create', Asset::class),
|
|
||||||
'update' => false,
|
|
||||||
'delete' => false,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (request('components')=='true') {
|
if (request('components')=='true') {
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ abstract class Importer
|
||||||
'department' => 'department',
|
'department' => 'department',
|
||||||
'manager_first_name' => 'manager first name',
|
'manager_first_name' => 'manager first name',
|
||||||
'manager_last_name' => 'manager last name',
|
'manager_last_name' => 'manager last name',
|
||||||
|
'min_amt' => 'minimum quantity',
|
||||||
];
|
];
|
||||||
/**
|
/**
|
||||||
* Map of item fields->csv names
|
* Map of item fields->csv names
|
||||||
|
@ -196,11 +197,11 @@ abstract class Importer
|
||||||
$val = $default;
|
$val = $default;
|
||||||
$key = $this->lookupCustomKey($key);
|
$key = $this->lookupCustomKey($key);
|
||||||
|
|
||||||
// $this->log("Custom Key: ${key}");
|
$this->log("Custom Key: ${key}");
|
||||||
if (array_key_exists($key, $array)) {
|
if (array_key_exists($key, $array)) {
|
||||||
$val = Encoding::toUTF8(trim($array[$key]));
|
$val = Encoding::toUTF8(trim($array[$key]));
|
||||||
}
|
}
|
||||||
// $this->log("${key}: ${val}");
|
$this->log("${key}: ${val}");
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
| serial number | serial | Asset, license |
|
| serial number | serial | Asset, license |
|
||||||
| status | status | Asset ? All |
|
| status | status | Asset ? All |
|
||||||
| supplier | supplier | Asset ? All |
|
| supplier | supplier | Asset ? All |
|
||||||
|
| minimum quantity | min_amt | Consumable |
|
||||||
| termination date | termination_date | License |
|
| termination date | termination_date | License |
|
||||||
| warranty months | warranty_months | Asset |
|
| warranty months | warranty_months | Asset |
|
||||||
| User Related Fields | assigned_to | Asset |
|
| User Related Fields | assigned_to | Asset |
|
||||||
|
|
|
@ -68,6 +68,7 @@ class Consumable extends SnipeModel
|
||||||
'purchase_cost',
|
'purchase_cost',
|
||||||
'purchase_date',
|
'purchase_date',
|
||||||
'qty',
|
'qty',
|
||||||
|
'min_amt',
|
||||||
'requestable',
|
'requestable',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -185,6 +186,7 @@ class Consumable extends SnipeModel
|
||||||
return $this->belongsTo(\App\Models\Category::class, 'category_id');
|
return $this->belongsTo(\App\Models\Category::class, 'category_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the component -> action logs relationship
|
* Establishes the component -> action logs relationship
|
||||||
*
|
*
|
||||||
|
@ -209,8 +211,8 @@ class Consumable extends SnipeModel
|
||||||
if ($this->image) {
|
if ($this->image) {
|
||||||
return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
|
return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,6 +227,7 @@ class Consumable extends SnipeModel
|
||||||
return $this->belongsToMany(\App\Models\User::class, 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps();
|
return $this->belongsToMany(\App\Models\User::class, 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether to send a checkin/checkout email based on
|
* Determine whether to send a checkin/checkout email based on
|
||||||
* asset model category
|
* asset model category
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# A supervisor event listener which terminates supervisord if any of its child
|
# A supervisor event listener which terminates supervisord if any of its child
|
||||||
# processes enter the FATAL state.
|
# processes enter the FATAL state.
|
||||||
# https://stackoverflow.com/a/37527488/119527
|
# https://stackoverflow.com/a/37527488/119527
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
"bootstrap-colorpicker": "^2.5.3",
|
"bootstrap-colorpicker": "^2.5.3",
|
||||||
"bootstrap-datepicker": "^1.9.0",
|
"bootstrap-datepicker": "^1.9.0",
|
||||||
"bootstrap-less": "^3.3.8",
|
"bootstrap-less": "^3.3.8",
|
||||||
"bootstrap-table": "^1.18.3",
|
"bootstrap-table": "^1.19.1",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"css-loader": "^3.6.0",
|
"css-loader": "^3.6.0",
|
||||||
"ekko-lightbox": "^5.1.1",
|
"ekko-lightbox": "^5.1.1",
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
"imagemin": "^5.3.1",
|
"imagemin": "^5.3.1",
|
||||||
"jquery-form-validator": "^2.3.79",
|
"jquery-form-validator": "^2.3.79",
|
||||||
"jquery-slimscroll": "^1.3.8",
|
"jquery-slimscroll": "^1.3.8",
|
||||||
"jquery-ui": "^1.12.1",
|
"jquery-ui": "^1.13.0",
|
||||||
"jquery-ui-bundle": "^1.12.1",
|
"jquery-ui-bundle": "^1.12.1",
|
||||||
"jquery.iframe-transport": "^1.0.0",
|
"jquery.iframe-transport": "^1.0.0",
|
||||||
"less": "^4.1.1",
|
"less": "^4.1.1",
|
||||||
|
|
Binary file not shown.
|
@ -158,6 +158,7 @@
|
||||||
consumables: [
|
consumables: [
|
||||||
{id: 'item_no', text: "Item Number"},
|
{id: 'item_no', text: "Item Number"},
|
||||||
{id: 'model_number', text: "Model Number"},
|
{id: 'model_number', text: "Model Number"},
|
||||||
|
{id: 'min_amt', text: "Minimum Quantity"},
|
||||||
],
|
],
|
||||||
licenses: [
|
licenses: [
|
||||||
{id: 'asset_tag', text: 'Assigned To Asset'},
|
{id: 'asset_tag', text: 'Assigned To Asset'},
|
||||||
|
@ -216,6 +217,7 @@
|
||||||
.concat(this.columnOptions.accessories)
|
.concat(this.columnOptions.accessories)
|
||||||
.sort(sorter);
|
.sort(sorter);
|
||||||
case 'consumable':
|
case 'consumable':
|
||||||
|
console.log('Returned consumable');
|
||||||
return this.columnOptions.general
|
return this.columnOptions.general
|
||||||
.concat(this.columnOptions.consumables)
|
.concat(this.columnOptions.consumables)
|
||||||
.sort(sorter);
|
.sort(sorter);
|
||||||
|
|
|
@ -57,21 +57,28 @@
|
||||||
<td>{{$field->element}}</td>
|
<td>{{$field->element}}</td>
|
||||||
<td>{{ $field->field_encrypted=='1' ? trans('general.yes') : trans('general.no') }}</td>
|
<td>{{ $field->field_encrypted=='1' ? trans('general.yes') : trans('general.no') }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
@if ($field->pivot->required)
|
@if ($field->pivot->required)
|
||||||
<a href="{{ route('fields.optional', [$custom_fieldset->id, $field->id]) }}">
|
<form method="post" action="{{ route('fields.optional', [$custom_fieldset->id, $field->id]) }}">
|
||||||
<i class="fas fa-check text-success" aria-hidden="true"></i>
|
@csrf
|
||||||
<span class="sr-only">Required - click to make optional</span>
|
<button type="submit" class="btn btn-link"><i class="fa fa-check text-success" aria-hidden="true"></i></button>
|
||||||
</a>
|
</form>
|
||||||
|
|
||||||
@else
|
@else
|
||||||
<a href="{{ route('fields.required', [$custom_fieldset->id, $field->id]) }}">
|
|
||||||
<i class="fas fa-times text-danger" aria-hidden="true"></i>
|
<form method="post" action="{{ route('fields.required', [$custom_fieldset->id, $field->id]) }}">
|
||||||
<span class="sr-only">Optional - click to make required</span>
|
@csrf
|
||||||
</a>
|
<button type="submit" class="btn btn-link"><i class="fa fa-times text-danger" aria-hidden="true"></i></button>
|
||||||
|
</form>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@can('update', $custom_fieldset)
|
@can('update', $custom_fieldset)
|
||||||
<a href="{{ route('fields.disassociate', [$field, $custom_fieldset->id]) }}" class="btn btn-sm btn-danger">Remove</a>
|
<form method="post" action="{{ route('fields.disassociate', [$field, $custom_fieldset->id]) }}">
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="btn btn-sm btn-danger">Remove</button>
|
||||||
|
</form>
|
||||||
@endcan
|
@endcan
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -109,14 +109,14 @@
|
||||||
@if ($snipeSettings->brand == '3')
|
@if ($snipeSettings->brand == '3')
|
||||||
<a class="logo navbar-brand no-hover" href="{{ url('/') }}">
|
<a class="logo navbar-brand no-hover" href="{{ url('/') }}">
|
||||||
@if ($snipeSettings->logo!='')
|
@if ($snipeSettings->logo!='')
|
||||||
<img class="navbar-brand-img" src="{{ Storage::disk('public')->url('/').e($snipeSettings->logo) }}" alt="{{ $snipeSettings->site_name }} logo">
|
<img class="navbar-brand-img" src="{{ Storage::disk('public')->url($snipeSettings->logo) }}" alt="{{ $snipeSettings->site_name }} logo">
|
||||||
@endif
|
@endif
|
||||||
{{ $snipeSettings->site_name }}
|
{{ $snipeSettings->site_name }}
|
||||||
</a>
|
</a>
|
||||||
@elseif ($snipeSettings->brand == '2')
|
@elseif ($snipeSettings->brand == '2')
|
||||||
<a class="logo navbar-brand no-hover" href="{{ url('/') }}">
|
<a class="logo navbar-brand no-hover" href="{{ url('/') }}">
|
||||||
@if ($snipeSettings->logo!='')
|
@if ($snipeSettings->logo!='')
|
||||||
<img class="navbar-brand-img" src="{{ Storage::disk('public')->url('/').e($snipeSettings->logo) }}" alt="{{ $snipeSettings->site_name }} logo">
|
<img class="navbar-brand-img" src="{{ Storage::disk('public')->url($snipeSettings->logo) }}" alt="{{ $snipeSettings->site_name }} logo">
|
||||||
@endif
|
@endif
|
||||||
<span class="sr-only">{{ $snipeSettings->site_name }}</span>
|
<span class="sr-only">{{ $snipeSettings->site_name }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -355,10 +355,17 @@
|
||||||
@endcan
|
@endcan
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url('/logout') }}">
|
|
||||||
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
|
<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
|
||||||
{{ trans('general.logout') }}
|
<i class="fa fa-sign-out fa-fw"></i> {{ trans('general.logout') }}
|
||||||
|
{{ csrf_field() }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
||||||
|
{{ csrf_field() }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
@ -947,6 +954,7 @@
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@livewireScripts
|
@livewireScripts
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,58 +1,40 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\CustomFieldsController;
|
|
||||||
use App\Http\Controllers\CustomFieldsetsController;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Custom Fields Routes
|
* Custom Fields Routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Route::group([ 'prefix' => 'fields','middleware' => ['auth'] ], function () {
|
Route::group([ 'prefix' => 'fields','middleware' => ['auth'] ], function () {
|
||||||
|
|
||||||
Route::get(
|
Route::post('required/{fieldset_id}/{field_id}',
|
||||||
'required/{fieldset_id}/{field_id}',
|
['uses' => 'CustomFieldsetsController@makeFieldRequired',
|
||||||
[
|
'as' => 'fields.required']
|
||||||
CustomFieldsetsController::class,
|
);
|
||||||
'makeFieldRequired'
|
|
||||||
]
|
|
||||||
)->name('fields.required');
|
|
||||||
|
|
||||||
Route::get(
|
Route::post('optional/{fieldset_id}/{field_id}',
|
||||||
'optional/{fieldset_id}/{field_id}',
|
['uses' => 'CustomFieldsetsController@makeFieldOptional',
|
||||||
[
|
'as' => 'fields.optional']
|
||||||
CustomFieldsetsController::class,
|
);
|
||||||
'makeFieldOptional'
|
|
||||||
]
|
|
||||||
)->name('fields.optional');
|
|
||||||
|
|
||||||
Route::get(
|
Route::post('{field_id}/fieldset/{fieldset_id}/disassociate',
|
||||||
'{field_id}/fieldset/{fieldset_id}/disassociate',
|
['uses' => 'CustomFieldsController@deleteFieldFromFieldset',
|
||||||
[
|
'as' => 'fields.disassociate']
|
||||||
CustomFieldsetsController::class,
|
);
|
||||||
'deleteFieldFromFieldset'
|
|
||||||
]
|
|
||||||
)->name('fields.disassociate');
|
|
||||||
|
|
||||||
Route::post(
|
Route::post('fieldsets/{id}/associate',
|
||||||
'fieldsets/{id}/associate',
|
['uses' => 'CustomFieldsetsController@associate',
|
||||||
[
|
'as' => 'fieldsets.associate']
|
||||||
CustomFieldsetsController::class,
|
);
|
||||||
'associate'
|
|
||||||
]
|
|
||||||
)->name('fieldsets.associate');
|
|
||||||
|
|
||||||
Route::resource('fieldsets', CustomFieldsetsController::class, [
|
Route::resource('fieldsets', 'CustomFieldsetsController', [
|
||||||
'parameters' => ['fieldset' => 'field_id', 'field' => 'field_id'],
|
'parameters' => ['fieldset' => 'field_id', 'field' => 'field_id']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::resource('fields', 'CustomFieldsController', [
|
||||||
Route::resource('fields', CustomFieldsController::class, [
|
'middleware' => ['auth'],
|
||||||
'parameters' => ['field' => 'field_id'],
|
'parameters' => ['field' => 'field_id', 'fieldset' => 'fieldset_id']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue