Compare commits
1 Commits
fix_action
...
move_faker
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c125eb8e6e |
@@ -4162,24 +4162,6 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tinyblargon",
|
||||
"name": "Okean",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/76069640?v=4",
|
||||
"profile": "https://github.com/Tinyblargon",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "amedranogil",
|
||||
"name": "Alejandro Medrano",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6515064?v=4",
|
||||
"profile": "https://www.lst.tfo.upm.es/alejandro-medrano/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/80526133?v=4" width="110px;"/><br /><sub>AlexanderWPapyrus</sub>](https://github.com/AlexanderWPapyrus)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AlexanderWPapyrus "Code") | [<img src="https://avatars.githubusercontent.com/u/306231?v=4" width="110px;"/><br /><sub>Alexandr Hacicheant</sub>](https://github.com/disc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=disc "Code") | [<img src="https://avatars.githubusercontent.com/u/3032891?v=4" width="110px;"/><br /><sub>Hex</sub>](https://hex128.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hex128 "Code") | [<img src="https://avatars.githubusercontent.com/u/8697942?v=4" width="110px;"/><br /><sub>Arunas Skirius</sub>](https://github.com/arukompas)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arukompas "Code") | [<img src="https://avatars.githubusercontent.com/u/104396?v=4" width="110px;"/><br /><sub>Ben Periton</sub>](https://github.com/benperiton)<br />[💻](https://github.com/snipe/snipe-it/commits?author=benperiton "Code") | [<img src="https://avatars.githubusercontent.com/u/11906832?v=4" width="110px;"/><br /><sub>Byron Wolfman</sub>](https://wolfman.dev/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=byronwolfman "Code") | [<img src="https://avatars.githubusercontent.com/u/56485508?v=4" width="110px;"/><br /><sub>Calvin</sub>](https://github.com/CalvinSchwartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=CalvinSchwartz "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/181059?v=4" width="110px;"/><br /><sub>Juan Font</sub>](https://github.com/juanfont)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juanfont "Code") | [<img src="https://avatars.githubusercontent.com/u/13137708?v=4" width="110px;"/><br /><sub>Juho Taipale</sub>](https://github.com/juhotaipale)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juhotaipale "Code") | [<img src="https://avatars.githubusercontent.com/u/1007419?v=4" width="110px;"/><br /><sub>Korvin Szanto</sub>](https://github.com/KorvinSzanto)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KorvinSzanto "Code") | [<img src="https://avatars.githubusercontent.com/u/8513053?v=4" width="110px;"/><br /><sub>Lewis Foster</sub>](https://lewisfoster.foo/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sniff122 "Code") | [<img src="https://avatars.githubusercontent.com/u/33877541?v=4" width="110px;"/><br /><sub>Logan Swartzendruber</sub>](https://github.com/loganswartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=loganswartz "Code") | [<img src="https://avatars.githubusercontent.com/u/1156208?v=4" width="110px;"/><br /><sub>Lorenzo P.</sub>](https://github.com/lopezio)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lopezio "Code") | [<img src="https://avatars.githubusercontent.com/u/33946590?v=4" width="110px;"/><br /><sub>Lukas Jung</sub>](https://github.com/m4us1ne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=m4us1ne "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/10965027?v=4" width="110px;"/><br /><sub>Ellie</sub>](https://leafedfox.xyz/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeafedFox "Code") | [<img src="https://avatars.githubusercontent.com/u/20960555?v=4" width="110px;"/><br /><sub>GA Stamper</sub>](https://github.com/gastamper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gastamper "Code") | [<img src="https://avatars.githubusercontent.com/u/206553556?v=4" width="110px;"/><br /><sub>Guillaume Lefranc</sub>](https://github.com/gl-pup)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gl-pup "Code") | [<img src="https://avatars.githubusercontent.com/u/733892?v=4" width="110px;"/><br /><sub>Hajo Möller</sub>](https://github.com/dasjoe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dasjoe "Code") | [<img src="https://avatars.githubusercontent.com/u/3420063?v=4" width="110px;"/><br /><sub>Istvan Basa</sub>](https://github.com/pottom)<br />[💻](https://github.com/snipe/snipe-it/commits?author=pottom "Code") | [<img src="https://avatars.githubusercontent.com/u/810824?v=4" width="110px;"/><br /><sub>JJ Asghar</sub>](https://jjasghar.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jjasghar "Code") | [<img src="https://avatars.githubusercontent.com/u/40404495?v=4" width="110px;"/><br /><sub>James E. Msenga</sub>](https://github.com/JemCdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JemCdo "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") | [<img src="https://avatars.githubusercontent.com/u/76069640?v=4" width="110px;"/><br /><sub>Okean</sub>](https://github.com/Tinyblargon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tinyblargon "Code") | [<img src="https://avatars.githubusercontent.com/u/6515064?v=4" width="110px;"/><br /><sub>Alejandro Medrano</sub>](https://www.lst.tfo.upm.es/alejandro-medrano/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=amedranogil "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FixUpAssignedTypeWithoutAssignedTo extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:assigned-type-fixup';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fixes up assets that have an assigned_type but no assigned_to';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
DB::table('assets')->whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]);
|
||||
$this->info("Assets with an assigned_type but no assigned_to are fixed");
|
||||
}
|
||||
}
|
||||
@@ -99,11 +99,8 @@ class SendAcceptanceReminder extends Command
|
||||
foreach ($no_email_list as $user) {
|
||||
$rows[] = [$user['id'], $user['name']];
|
||||
}
|
||||
|
||||
if (!empty($rows)) {
|
||||
$this->info("The following users do not have an email address:");
|
||||
$this->table($headers, $rows);
|
||||
}
|
||||
$this->info("The following users do not have an email address:");
|
||||
$this->table($headers, $rows);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class CheckoutableCheckedIn
|
||||
$this->checkedOutTo = $checkedOutTo;
|
||||
$this->checkedInBy = $checkedInBy;
|
||||
$this->note = $note;
|
||||
$this->action_date = $action_date ?? date('Y-m-d H:i:s');
|
||||
$this->action_date = $action_date ?? date('Y-m-d');
|
||||
$this->originalValues = $originalValues;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ use Illuminate\Support\Facades\Log;
|
||||
use Throwable;
|
||||
use JsonException;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use Illuminate\Http\Exceptions\ThrottleRequestsException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@@ -108,10 +107,11 @@ class Handler extends ExceptionHandler
|
||||
|
||||
$statusCode = $e->getStatusCode();
|
||||
|
||||
// API throttle requests are handled in the RouteServiceProvider configureRateLimiting() method, so we don't need to handle them here
|
||||
switch ($e->getStatusCode()) {
|
||||
case '404':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
|
||||
case '429':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Too many requests'), 429);
|
||||
case '405':
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
|
||||
default:
|
||||
@@ -143,8 +143,6 @@ class Handler extends ExceptionHandler
|
||||
$route = 'maintenances.index';
|
||||
} elseif ($route === 'licenseseats.index') {
|
||||
$route = 'licenses.index';
|
||||
} elseif ($route === 'customfields.index') {
|
||||
$route = 'fields.index';
|
||||
}
|
||||
|
||||
return redirect()
|
||||
@@ -203,7 +201,6 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
|
||||
@@ -1313,24 +1313,25 @@ class Helper
|
||||
switch ($item) {
|
||||
case 'asset':
|
||||
return 'fas fa-barcode';
|
||||
break;
|
||||
case 'accessory':
|
||||
return 'fas fa-keyboard';
|
||||
break;
|
||||
case 'component':
|
||||
return 'fas fa-hdd';
|
||||
break;
|
||||
case 'consumable':
|
||||
return 'fas fa-tint';
|
||||
break;
|
||||
case 'license':
|
||||
return 'far fa-save';
|
||||
break;
|
||||
case 'location':
|
||||
return 'fas fa-map-marker-alt';
|
||||
break;
|
||||
case 'user':
|
||||
return 'fas fa-user';
|
||||
case 'supplier':
|
||||
return 'fa-solid fa-store';
|
||||
case 'manufacturer':
|
||||
return 'fa-solid fa-building';
|
||||
case 'category':
|
||||
return 'fa-solid fa-table-columns';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,12 +85,6 @@ class AssetModelsController extends Controller
|
||||
$assetmodels = $assetmodels->where('models.model_number', '=', $request->input('model_number'));
|
||||
}
|
||||
|
||||
if ($request->input('requestable') == 'true') {
|
||||
$assetmodels = $assetmodels->where('models.requestable', '=', '1');
|
||||
} elseif ($request->input('requestable') == 'false') {
|
||||
$assetmodels = $assetmodels->where('models.requestable', '=', '0');
|
||||
}
|
||||
|
||||
if ($request->filled('notes')) {
|
||||
$assetmodels = $assetmodels->where('models.notes', '=', $request->input('notes'));
|
||||
}
|
||||
|
||||
@@ -1146,7 +1146,7 @@ class AssetsController extends Controller
|
||||
|
||||
// Validate the rest of the data before we turn off the event dispatcher
|
||||
if ($asset->isInvalid()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', ['asset_tag' => $asset->asset_tag], $asset->getErrors()));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -234,15 +234,6 @@ class ImportController extends Controller
|
||||
case 'location':
|
||||
$redirectTo = 'locations.index';
|
||||
break;
|
||||
case 'supplier':
|
||||
$redirectTo = 'suppliers.index';
|
||||
break;
|
||||
case 'manufacturer':
|
||||
$redirectTo = 'manufacturers.index';
|
||||
break;
|
||||
case 'category':
|
||||
$redirectTo = 'categories.index';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($errors) { //Failure
|
||||
|
||||
@@ -87,8 +87,7 @@ class LocationsController extends Controller
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->with('adminuser');
|
||||
->withCount('users as users_count');
|
||||
|
||||
// Only scope locations if the setting is enabled
|
||||
if (Setting::getSettings()->scope_locations_fmcs) {
|
||||
@@ -219,7 +218,6 @@ class LocationsController extends Controller
|
||||
'locations.updated_at',
|
||||
'locations.image',
|
||||
'locations.currency',
|
||||
'locations.company_id',
|
||||
'locations.notes',
|
||||
])
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
|
||||
@@ -24,15 +24,10 @@ class SuppliersController extends Controller
|
||||
public function index(Request $request): array
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
$allowed_columns = ['
|
||||
id',
|
||||
'name',
|
||||
'address',
|
||||
'address2',
|
||||
'city',
|
||||
'state',
|
||||
'country',
|
||||
'zip',
|
||||
'phone',
|
||||
'contact',
|
||||
'fax',
|
||||
@@ -44,24 +39,21 @@ class SuppliersController extends Controller
|
||||
'components_count',
|
||||
'consumables_count',
|
||||
'url',
|
||||
'notes',
|
||||
];
|
||||
|
||||
$suppliers = Supplier::select(
|
||||
['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'created_by', 'updated_at', 'deleted_at', 'image', 'notes', 'url', 'zip'])
|
||||
['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'updated_at', 'deleted_at', 'image', 'notes', 'url'])
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('licenses as licenses_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('components as components_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->with('adminuser');
|
||||
->withCount('consumables as consumables_count');
|
||||
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$suppliers->TextSearch($request->input('search'));
|
||||
$suppliers = $suppliers->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('name')) {
|
||||
$suppliers->where('name', '=', $request->input('name'));
|
||||
}
|
||||
@@ -108,15 +100,7 @@ class SuppliersController extends Controller
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
switch ($request->input('sort')) {
|
||||
case 'created_by':
|
||||
$suppliers->OrderByCreatedByName($order);
|
||||
break;
|
||||
default:
|
||||
$suppliers->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
$suppliers->orderBy($sort, $order);
|
||||
|
||||
$total = $suppliers->count();
|
||||
$suppliers = $suppliers->skip($offset)->take($limit)->get();
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\ActionlogsTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
@@ -81,7 +80,7 @@ class UsersController extends Controller
|
||||
'users.autoassign_licenses',
|
||||
'users.website',
|
||||
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations', 'eulas')
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations')
|
||||
->withCount([
|
||||
'assets as assets_count' => function(Builder $query) {
|
||||
$query->withoutTrashed();
|
||||
@@ -737,25 +736,6 @@ class UsersController extends Controller
|
||||
return (new UsersTransformer)->transformUser($request->user());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the EULAs accepted by the user.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Http\Transformers\ActionlogsTransformer $transformer
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*@since [v8.1.16]
|
||||
* @author [Godfrey Martinez] [<gmartinez@grokability.com>]
|
||||
*/
|
||||
public function eulas(User $user, ActionlogsTransformer $transformer)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$eulas = $user->eulas;
|
||||
return response()->json(
|
||||
$transformer->transformActionlogs($eulas, $eulas->count())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a soft-deleted user.
|
||||
*
|
||||
|
||||
@@ -67,10 +67,16 @@ class AssetMaintenancesController extends Controller
|
||||
// We have to set this so that the correct property is set in the select2 ajax dropdown
|
||||
$asset->asset_id = $asset->id;
|
||||
}
|
||||
|
||||
|
||||
// Prepare Asset Maintenance Type List
|
||||
$assetMaintenanceType = [
|
||||
'' => 'Select an asset maintenance type',
|
||||
] + AssetMaintenance::getImprovementOptions();
|
||||
// Mark the selected asset, if it came in
|
||||
|
||||
return view('asset_maintenances/edit')
|
||||
->with('assetMaintenanceType', AssetMaintenance::getImprovementOptions())
|
||||
->with('asset', $asset)
|
||||
->with('assetMaintenanceType', $assetMaintenanceType)
|
||||
->with('item', new AssetMaintenance);
|
||||
}
|
||||
|
||||
@@ -85,47 +91,43 @@ class AssetMaintenancesController extends Controller
|
||||
public function store(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||
$assetMaintenance->cost = $request->input('cost');
|
||||
$assetMaintenance->notes = $request->input('notes');
|
||||
$asset = Asset::find($request->input('asset_id'));
|
||||
|
||||
$assets = Asset::whereIn('id', $request->input('selected_assets'))->get();
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if ((! Company::isCurrentUserHasAccess($asset)) && ($asset != null)) {
|
||||
return static::getInsufficientPermissionsRedirect();
|
||||
}
|
||||
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||
$assetMaintenance->cost = $request->input('cost');
|
||||
$assetMaintenance->notes = $request->input('notes');
|
||||
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $asset->id;
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
$assetMaintenance->created_by = auth()->id();
|
||||
|
||||
if (($assetMaintenance->completion_date !== null)
|
||||
&& ($assetMaintenance->start_date !== '')
|
||||
&& ($assetMaintenance->start_date !== '0000-00-00')
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||
}
|
||||
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if (!$assetMaintenance->save()) {
|
||||
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
|
||||
}
|
||||
if ((! Company::isCurrentUserHasAccess($asset)) && ($asset != null)) {
|
||||
return static::getInsufficientPermissionsRedirect();
|
||||
}
|
||||
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('success', trans('admin/asset_maintenances/message.create.success'));
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $request->input('asset_id');
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
$assetMaintenance->created_by = auth()->id();
|
||||
|
||||
if (($assetMaintenance->completion_date !== null)
|
||||
&& ($assetMaintenance->start_date !== '')
|
||||
&& ($assetMaintenance->start_date !== '0000-00-00')
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||
}
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($assetMaintenance->save()) {
|
||||
// Redirect to the new asset maintenance page
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('success', trans('admin/asset_maintenances/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,7 +149,7 @@ class AssetMaintenancesController extends Controller
|
||||
}
|
||||
|
||||
// Prepare Improvement Type List
|
||||
$assetMaintenanceType = ['' => trans('general.select')] + AssetMaintenance::getImprovementOptions();
|
||||
$assetMaintenanceType = ['' => 'Select an improvement type'] + AssetMaintenance::getImprovementOptions();
|
||||
|
||||
return view('asset_maintenances/edit')
|
||||
->with('selectedAsset', null)
|
||||
|
||||
@@ -149,7 +149,7 @@ class AssetsController extends Controller
|
||||
$asset->byod = request('byod', 0);
|
||||
|
||||
if (! empty($settings->audit_interval)) {
|
||||
$asset->next_audit_date = Carbon::now()->addMonths((int) $settings->audit_interval)->toDateString();
|
||||
$asset->next_audit_date = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
|
||||
}
|
||||
|
||||
// Set location_id to rtd_location_id ONLY if the asset isn't being checked out
|
||||
@@ -188,31 +188,14 @@ class AssetsController extends Controller
|
||||
|
||||
// Validate the asset before saving
|
||||
if ($asset->isValid() && $asset->save()) {
|
||||
$target = null;
|
||||
$location = null;
|
||||
|
||||
if ($userId = request('assigned_user')) {
|
||||
$target = User::find($userId);
|
||||
|
||||
if (!$target) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/hardware/message.create.target_not_found.user'));
|
||||
}
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
$location = $target->location_id;
|
||||
|
||||
} elseif ($assetId = request('assigned_asset')) {
|
||||
$target = Asset::find($assetId);
|
||||
|
||||
if (!$target) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/hardware/message.create.target_not_found.asset'));
|
||||
}
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
$location = $target->location_id;
|
||||
|
||||
} elseif ($locationId = request('assigned_location')) {
|
||||
$target = Location::find($locationId);
|
||||
|
||||
if (!$target) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/hardware/message.create.target_not_found.location'));
|
||||
}
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
@@ -463,7 +446,7 @@ class AssetsController extends Controller
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), 'Checkin on delete', $checkin_at, $originalValues));
|
||||
DB::table('assets')
|
||||
->where('id', $asset->id)
|
||||
->update(['assigned_to' => null, 'assigned_type' => null]);
|
||||
->update(['assigned_to' => null]);
|
||||
}
|
||||
|
||||
|
||||
@@ -475,7 +458,6 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$asset->delete();
|
||||
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
|
||||
@@ -908,7 +890,7 @@ class AssetsController extends Controller
|
||||
return redirect()->route('hardware.edit', $asset)->withErrors($asset->getErrors());
|
||||
}
|
||||
|
||||
$dt = Carbon::now()->addMonths( (int) $settings->audit_interval)->toDateString();
|
||||
$dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
|
||||
return view('hardware/audit')->with('asset', $asset)->with('item', $asset)->with('next_audit_date', $dt)->with('locations_list');
|
||||
}
|
||||
|
||||
|
||||
@@ -52,17 +52,11 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
|
||||
$asset_ids = $request->input('ids');
|
||||
|
||||
if ($request->input('bulk_actions') === 'checkout') {
|
||||
$request->session()->flashInput(['selected_assets' => $asset_ids]);
|
||||
return redirect()->route('hardware.bulkcheckout.show');
|
||||
}
|
||||
|
||||
if ($request->input('bulk_actions') === 'maintenance') {
|
||||
$request->session()->flashInput(['selected_assets' => $asset_ids]);
|
||||
return redirect()->route('maintenances.create');
|
||||
}
|
||||
|
||||
// Figure out where we need to send the user after the update is complete, and store that in the session
|
||||
$bulk_back_url = request()->headers->get('referer');
|
||||
session(['bulk_back_url' => $bulk_back_url]);
|
||||
@@ -568,10 +562,7 @@ class BulkAssetsController extends Controller
|
||||
public function showCheckout() : View
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
|
||||
$do_not_change = ['' => trans('general.do_not_change')];
|
||||
$status_label_list = $do_not_change + Helper::deployableStatusLabelList();
|
||||
return view('hardware/bulk-checkout')->with('statusLabel_list', $status_label_list);
|
||||
return view('hardware/bulk-checkout');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -603,13 +594,13 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
$checkout_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->get('checkout_at');
|
||||
$checkout_at = e($request->get('checkout_at'));
|
||||
}
|
||||
|
||||
$expected_checkin = '';
|
||||
|
||||
if ($request->filled('expected_checkin')) {
|
||||
$expected_checkin = $request->get('expected_checkin');
|
||||
$expected_checkin = e($request->get('expected_checkin'));
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
@@ -617,11 +608,6 @@ class BulkAssetsController extends Controller
|
||||
foreach ($assets as $asset) {
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
// See if there is a status label passed
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
}
|
||||
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);
|
||||
|
||||
//TODO - I think this logic is duplicated in the checkOut method?
|
||||
|
||||
@@ -650,7 +650,6 @@ class SettingsController extends Controller
|
||||
|
||||
$setting->alert_email = $alert_email;
|
||||
$setting->admin_cc_email = $admin_cc_email;
|
||||
$setting->admin_cc_always = $request->validated('admin_cc_always');
|
||||
$setting->alerts_enabled = $request->input('alerts_enabled', '0');
|
||||
$setting->alert_interval = $request->input('alert_interval');
|
||||
$setting->alert_threshold = $request->input('alert_threshold');
|
||||
|
||||
@@ -73,7 +73,6 @@ class Kernel extends HttpKernel
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'api-throttle' => \App\Http\Middleware\SetAPIResponseHeaders::class,
|
||||
'health' => null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SetAPIResponseHeaders extends ThrottleRequests
|
||||
{
|
||||
|
||||
/**
|
||||
* Add the rate limit headers to the response.
|
||||
*
|
||||
* This extends the original ThrottleRequests middleware to add the 'X-RateLimit-Reset' and 'Retry-After' headers, even
|
||||
* if the rate limit is not exceeded.
|
||||
* @param $maxAttempts
|
||||
* @param $remainingAttempts
|
||||
* @param $retryAfter
|
||||
* @param Response|null $response
|
||||
* @return array|int[]
|
||||
*/
|
||||
protected function getHeaders($maxAttempts, $remainingAttempts, $retryAfter = null, ?Response $response = null)
|
||||
{
|
||||
if ($response &&
|
||||
! is_null($response->headers->get('X-RateLimit-Remaining')) &&
|
||||
(int) $response->headers->get('X-RateLimit-Remaining') <= (int) $remainingAttempts) {
|
||||
$headers = [];
|
||||
$headers['Retry-After'] = $retryAfter; // this is the only line we changed
|
||||
$headers['X-RateLimit-Reset'] = $retryAfter; // this is the only line we changed
|
||||
$headers['X-RateLimit-Reset-Timestamp'] = $this->availableAt($retryAfter); // this is the only line we changed
|
||||
return $headers;
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'X-RateLimit-Limit' => $maxAttempts,
|
||||
'X-RateLimit-Remaining' => $remainingAttempts,
|
||||
];
|
||||
|
||||
if (! is_null($retryAfter)) {
|
||||
$headers['Retry-After'] = $retryAfter;
|
||||
$headers['X-RateLimit-Reset'] = $retryAfter; // this is the only line we changed
|
||||
$headers['X-RateLimit-Reset-Timestamp'] = $this->availableAt($retryAfter); // this is the only line we changed
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
protected function handleRequest($request, Closure $next, array $limits)
|
||||
{
|
||||
foreach ($limits as $limit) {
|
||||
if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {
|
||||
throw $this->buildException($request, $limit->key, $limit->maxAttempts, $limit->responseCallback);
|
||||
}
|
||||
|
||||
$this->limiter->hit($limit->key, $limit->decaySeconds);
|
||||
}
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
foreach ($limits as $limit) {
|
||||
$response = $this->addHeaders(
|
||||
$response,
|
||||
$limit->maxAttempts,
|
||||
$this->calculateRemainingAttempts($limit->key, $limit->maxAttempts),
|
||||
$this->getTimeUntilNextRetry($limit->key) // this is the only line we changed
|
||||
);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,8 +37,8 @@ class StoreLabelSettings extends FormRequest
|
||||
|
||||
return [
|
||||
'labels_per_page' => 'numeric',
|
||||
'labels_width' => 'numeric|min:0.1',
|
||||
'labels_height' => 'numeric|min:0.1',
|
||||
'labels_width' => 'numeric',
|
||||
'labels_height' => 'numeric',
|
||||
'labels_pmargin_left' => 'numeric|nullable',
|
||||
'labels_pmargin_right' => 'numeric|nullable',
|
||||
'labels_pmargin_top' => 'numeric|nullable',
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace App\Http\Requests;
|
||||
use App\Models\Accessory;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreNotificationSettings extends FormRequest
|
||||
{
|
||||
@@ -27,9 +26,6 @@ class StoreNotificationSettings extends FormRequest
|
||||
return [
|
||||
'alert_email' => 'email_array|nullable',
|
||||
'admin_cc_email' => 'email_array|nullable',
|
||||
'admin_cc_always' => [
|
||||
Rule::in('0', '1'),
|
||||
],
|
||||
'alert_threshold' => 'numeric|nullable',
|
||||
'alert_interval' => 'numeric|nullable|gt:0',
|
||||
'audit_warning_days' => 'numeric|nullable',
|
||||
|
||||
@@ -57,10 +57,6 @@ class LocationsTransformer
|
||||
'ldap_ou' => ($location->ldap_ou) ? e($location->ldap_ou) : null,
|
||||
'notes' => Helper::parseEscapedMarkedownInline($location->notes),
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
'created_by' => $location->adminuser ? [
|
||||
'id' => (int) $location->adminuser->id,
|
||||
'name'=> e($location->adminuser->present()->fullName),
|
||||
]: null,
|
||||
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
|
||||
'parent' => ($location->parent) ? [
|
||||
'id' => (int) $location->parent->id,
|
||||
|
||||
@@ -45,10 +45,6 @@ class SuppliersTransformer
|
||||
'components_count' => (int) $supplier->components_count,
|
||||
'notes' => ($supplier->notes) ? Helper::parseEscapedMarkedownInline($supplier->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($supplier->created_at, 'datetime'),
|
||||
'created_by' => $supplier->adminuser ? [
|
||||
'id' => (int) $supplier->adminuser->id,
|
||||
'name'=> e($supplier->adminuser->present()->fullName),
|
||||
]: null,
|
||||
'updated_at' => Helper::getFormattedDateObject($supplier->updated_at, 'datetime'),
|
||||
|
||||
];
|
||||
|
||||
@@ -80,16 +80,7 @@ class AssetImporter extends ItemImporter
|
||||
$asset_tag = Asset::autoincrement_asset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override asset if an ID was given
|
||||
\Log::debug('Finding asset by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$asset = Asset::find($this->findCsvMatch($row, 'id'));
|
||||
} else {
|
||||
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
|
||||
}
|
||||
|
||||
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
|
||||
if ($asset) {
|
||||
if (! $this->updating) {
|
||||
$exists_error = trans('general.import_asset_tag_exists', ['asset_tag' => $asset_tag]);
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
use App\Models\Category;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* When we are importing users via an Asset/etc import, we use createOrFetchUser() in
|
||||
* Importer\Importer.php. [ALG]
|
||||
*
|
||||
* Class CategoryImporter
|
||||
*/
|
||||
class CategoryImporter extends ItemImporter
|
||||
{
|
||||
protected $categories;
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
parent::__construct($filename);
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row);
|
||||
$this->createCategoryIfNotExists($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a category if a duplicate does not exist.
|
||||
* @todo Investigate how this should interact with Importer::createCategoryIfNotExists
|
||||
*
|
||||
* @author A. Gianotto
|
||||
* @since 6.1.0
|
||||
* @param array $row
|
||||
*/
|
||||
public function createCategoryIfNotExists(array $row)
|
||||
{
|
||||
|
||||
$editingCategory = false;
|
||||
|
||||
$category = Category::where('name', '=', $this->findCsvMatch($row, 'name'))->first();
|
||||
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override category if an ID was given
|
||||
\Log::debug('Finding category by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$category = Category::find($this->findCsvMatch($row, 'id'));
|
||||
}
|
||||
|
||||
|
||||
if ($category) {
|
||||
if (! $this->updating) {
|
||||
$this->log('A matching Category '.$this->item['name'].' already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log('Updating Category');
|
||||
$editingCategory = true;
|
||||
} else {
|
||||
$this->log('No Matching Category, Create a new one');
|
||||
$category = new Category;
|
||||
$category->created_by = auth()->id();
|
||||
}
|
||||
|
||||
// Pull the records from the CSV to determine their values
|
||||
$this->item['name'] = trim($this->findCsvMatch($row, 'name'));
|
||||
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
|
||||
$this->item['eula_text'] = trim($this->findCsvMatch($row, 'eula_text'));
|
||||
$this->item['category_type'] = trim($this->findCsvMatch($row, 'category_type'));
|
||||
$this->item['use_default_eula'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'use_default_eula'))) == 1) ? 1 : 0;
|
||||
$this->item['require_acceptance'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'require_acceptance'))) == 1) ? 1 : 0;
|
||||
$this->item['checkin_email'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'checkin_email'))) == 1) ? 1 : 0;
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
Log::debug(print_r($this->item, true));
|
||||
|
||||
|
||||
if ($editingCategory) {
|
||||
Log::debug('Updating existing category');
|
||||
$category->update($this->sanitizeItemForUpdating($category));
|
||||
} else {
|
||||
Log::debug('Creating category');
|
||||
$category->fill($this->sanitizeItemForStoring($category));
|
||||
}
|
||||
|
||||
if ($category->save()) {
|
||||
$this->log('Category '.$category->name.' created or updated from CSV import');
|
||||
return $category;
|
||||
|
||||
} else {
|
||||
Log::debug($category->getErrors());
|
||||
$this->logError($category, 'Category "'.$this->item['name'].'"');
|
||||
return $category->errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class ItemImporter extends Importer
|
||||
protected function determineCheckout($row)
|
||||
{
|
||||
// Locations don't get checked out to anyone/anything
|
||||
if ((get_class($this) == LocationImporter::class) || (get_class($this) == AssetModelImporter::class) || (get_class($this) == SupplierImporter::class) || (get_class($this) == ManufacturerImporter::class) || (get_class($this) == CategoryImporter::class)) {
|
||||
if ((get_class($this) == LocationImporter::class) || (get_class($this) == AssetModelImporter::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
use App\Models\Manufacturer;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* When we are importing users via an Asset/etc import, we use createOrFetchUser() in
|
||||
* Importer\Importer.php. [ALG]
|
||||
*
|
||||
* Class ManufacturerImporter
|
||||
*/
|
||||
class ManufacturerImporter extends ItemImporter
|
||||
{
|
||||
protected $manufacturers;
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
parent::__construct($filename);
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row);
|
||||
$this->createManufacturerIfNotExists($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a supplier if a duplicate does not exist.
|
||||
* @todo Investigate how this should interact with Importer::createManufacturerIfNotExists
|
||||
*
|
||||
* @author A. Gianotto
|
||||
* @since 6.1.0
|
||||
* @param array $row
|
||||
*/
|
||||
public function createManufacturerIfNotExists(array $row)
|
||||
{
|
||||
|
||||
$editingManufacturer = false;
|
||||
|
||||
$supplier = Manufacturer::where('name', '=', $this->findCsvMatch($row, 'name'))->first();
|
||||
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override supplier if an ID was given
|
||||
\Log::debug('Finding supplier by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$supplier = Manufacturer::find($this->findCsvMatch($row, 'id'));
|
||||
}
|
||||
|
||||
|
||||
if ($supplier) {
|
||||
if (! $this->updating) {
|
||||
$this->log('A matching Manufacturer '.$this->item['name'].' already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log('Updating Manufacturer');
|
||||
$editingManufacturer = true;
|
||||
} else {
|
||||
$this->log('No Matching Manufacturer, Create a new one');
|
||||
$supplier = new Manufacturer;
|
||||
$supplier->created_by = auth()->id();
|
||||
}
|
||||
|
||||
// Pull the records from the CSV to determine their values
|
||||
$this->item['name'] = trim($this->findCsvMatch($row, 'name'));
|
||||
$this->item['support_phone'] = trim($this->findCsvMatch($row, 'support_phone'));
|
||||
$this->item['fax'] = trim($this->findCsvMatch($row, 'fax'));
|
||||
$this->item['support_email'] = trim($this->findCsvMatch($row, 'support_email'));
|
||||
$this->item['contact'] = trim($this->findCsvMatch($row, 'contact'));
|
||||
$this->item['url'] = trim($this->findCsvMatch($row, 'url'));
|
||||
$this->item['support_url'] = trim($this->findCsvMatch($row, 'support_url'));
|
||||
$this->item['warranty_lookup_url'] = trim($this->findCsvMatch($row, 'warranty_lookup_url'));
|
||||
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
Log::debug(print_r($this->item, true));
|
||||
|
||||
|
||||
if ($editingManufacturer) {
|
||||
Log::debug('Updating existing supplier');
|
||||
$supplier->update($this->sanitizeItemForUpdating($supplier));
|
||||
} else {
|
||||
Log::debug('Creating supplier');
|
||||
$supplier->fill($this->sanitizeItemForStoring($supplier));
|
||||
}
|
||||
|
||||
if ($supplier->save()) {
|
||||
$this->log('Manufacturer '.$supplier->name.' created or updated from CSV import');
|
||||
return $supplier;
|
||||
|
||||
} else {
|
||||
Log::debug($supplier->getErrors());
|
||||
$this->logError($supplier, 'Manufacturer "'.$this->item['name'].'"');
|
||||
return $supplier->errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
use App\Models\Supplier;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* When we are importing users via an Asset/etc import, we use createOrFetchUser() in
|
||||
* Importer\Importer.php. [ALG]
|
||||
*
|
||||
* Class SupplierImporter
|
||||
*/
|
||||
class SupplierImporter extends ItemImporter
|
||||
{
|
||||
protected $suppliers;
|
||||
|
||||
public function __construct($filename)
|
||||
{
|
||||
parent::__construct($filename);
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row);
|
||||
$this->createSupplierIfNotExists($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a supplier if a duplicate does not exist.
|
||||
* @todo Investigate how this should interact with Importer::createSupplierIfNotExists
|
||||
*
|
||||
* @author A. Gianotto
|
||||
* @since 6.1.0
|
||||
* @param array $row
|
||||
*/
|
||||
public function createSupplierIfNotExists(array $row)
|
||||
{
|
||||
|
||||
$editingSupplier = false;
|
||||
|
||||
$supplier = Supplier::where('name', '=', $this->findCsvMatch($row, 'name'))->first();
|
||||
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override supplier if an ID was given
|
||||
\Log::debug('Finding supplier by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$supplier = Supplier::find($this->findCsvMatch($row, 'id'));
|
||||
}
|
||||
|
||||
|
||||
if ($supplier) {
|
||||
if (! $this->updating) {
|
||||
$this->log('A matching Supplier '.$this->item['name'].' already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log('Updating Supplier');
|
||||
$editingSupplier = true;
|
||||
} else {
|
||||
$this->log('No Matching Supplier, Create a new one');
|
||||
$supplier = new Supplier;
|
||||
$supplier->created_by = auth()->id();
|
||||
}
|
||||
|
||||
// Pull the records from the CSV to determine their values
|
||||
$this->item['name'] = trim($this->findCsvMatch($row, 'name'));
|
||||
$this->item['address'] = trim($this->findCsvMatch($row, 'address'));
|
||||
$this->item['address2'] = trim($this->findCsvMatch($row, 'address2'));
|
||||
$this->item['city'] = trim($this->findCsvMatch($row, 'city'));
|
||||
$this->item['state'] = trim($this->findCsvMatch($row, 'state'));
|
||||
$this->item['country'] = trim($this->findCsvMatch($row, 'country'));
|
||||
$this->item['zip'] = trim($this->findCsvMatch($row, 'zip'));
|
||||
$this->item['phone'] = trim($this->findCsvMatch($row, 'phone'));
|
||||
$this->item['fax'] = trim($this->findCsvMatch($row, 'fax'));
|
||||
$this->item['email'] = trim($this->findCsvMatch($row, 'email'));
|
||||
$this->item['contact'] = trim($this->findCsvMatch($row, 'contact'));
|
||||
$this->item['url'] = trim($this->findCsvMatch($row, 'url'));
|
||||
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
Log::debug(print_r($this->item, true));
|
||||
|
||||
|
||||
if ($editingSupplier) {
|
||||
Log::debug('Updating existing supplier');
|
||||
$supplier->update($this->sanitizeItemForUpdating($supplier));
|
||||
} else {
|
||||
Log::debug('Creating supplier');
|
||||
$supplier->fill($this->sanitizeItemForStoring($supplier));
|
||||
}
|
||||
|
||||
if ($supplier->save()) {
|
||||
$this->log('Supplier '.$supplier->name.' created or updated from CSV import');
|
||||
return $supplier;
|
||||
|
||||
} else {
|
||||
Log::debug($supplier->getErrors());
|
||||
$this->logError($supplier, 'Supplier "'.$this->item['name'].'"');
|
||||
return $supplier->errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -69,16 +69,16 @@ class CheckoutableListener
|
||||
return;
|
||||
}
|
||||
|
||||
$acceptance = $this->getCheckoutAcceptance($event);
|
||||
|
||||
$shouldSendEmailToUser = $this->shouldSendCheckoutEmailToUser($event->checkoutable);
|
||||
$shouldSendEmailToAlertAddress = $this->shouldSendEmailToAlertAddress($acceptance);
|
||||
$shouldSendEmailToAlertAddress = $this->shouldSendEmailToAlertAddress();
|
||||
$shouldSendWebhookNotification = $this->shouldSendWebhookNotification();
|
||||
|
||||
if (!$shouldSendEmailToUser && !$shouldSendEmailToAlertAddress && !$shouldSendWebhookNotification) {
|
||||
return;
|
||||
}
|
||||
|
||||
$acceptance = $this->getCheckoutAcceptance($event);
|
||||
|
||||
if ($shouldSendEmailToUser || $shouldSendEmailToAlertAddress) {
|
||||
$mailable = $this->getCheckoutMailType($event, $acceptance);
|
||||
$notifiable = $this->getNotifiableUser($event);
|
||||
@@ -419,19 +419,9 @@ class CheckoutableListener
|
||||
return false;
|
||||
}
|
||||
|
||||
private function shouldSendEmailToAlertAddress($acceptance = null): bool
|
||||
private function shouldSendEmailToAlertAddress(): bool
|
||||
{
|
||||
$setting = Setting::getSettings();
|
||||
|
||||
if (!$setting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_null($acceptance) && !$setting->admin_cc_always) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $setting->admin_cc_email;
|
||||
return Setting::getSettings() && Setting::getSettings()->admin_cc_email;
|
||||
}
|
||||
|
||||
private function getFormattedAlertAddresses(): array
|
||||
|
||||
@@ -35,14 +35,10 @@ class Importer extends Component
|
||||
public $accessories_fields;
|
||||
public $assets_fields;
|
||||
public $users_fields;
|
||||
public $assetmodels_fields;
|
||||
public $suppliers_fields;
|
||||
public $licenses_fields;
|
||||
public $locations_fields;
|
||||
public $consumables_fields;
|
||||
public $components_fields;
|
||||
public $manufacturers_fields;
|
||||
public $categories_fields;
|
||||
public $aliases_fields;
|
||||
|
||||
protected $rules = [
|
||||
@@ -89,6 +85,9 @@ class Importer extends Component
|
||||
case 'component':
|
||||
$results = $this->components_fields;
|
||||
break;
|
||||
case 'consumable':
|
||||
$results = $this->consumables_fields;
|
||||
break;
|
||||
case 'license':
|
||||
$results = $this->licenses_fields;
|
||||
break;
|
||||
@@ -98,14 +97,8 @@ class Importer extends Component
|
||||
case 'location':
|
||||
$results = $this->locations_fields;
|
||||
break;
|
||||
case 'supplier':
|
||||
$results = $this->suppliers_fields;
|
||||
break;
|
||||
case 'manufacturer':
|
||||
$results = $this->manufacturers_fields;
|
||||
break;
|
||||
case 'category':
|
||||
$results = $this->categories_fields;
|
||||
case 'user':
|
||||
$results = $this->users_fields;
|
||||
break;
|
||||
default:
|
||||
$results = [];
|
||||
@@ -135,7 +128,7 @@ class Importer extends Component
|
||||
//yes, this key *is* valid. Continue on to the next field.
|
||||
continue;
|
||||
} else {
|
||||
//no, this key is *INVALID* for this import type. Better set it to null,
|
||||
//no, this key is *INVALID* for this import type. Better set it to null
|
||||
// and we'll hope that the $aliases_fields or something else picks it up.
|
||||
$this->field_map[$i] = null; // fingers crossed! But it's not likely, tbh.
|
||||
} // TODO - strictly speaking, this isn't necessary here I don't think.
|
||||
@@ -156,7 +149,7 @@ class Importer extends Component
|
||||
// in "Accessories"!)
|
||||
if (array_key_exists($key, $this->columnOptions[$type])) {
|
||||
$this->field_map[$i] = $key;
|
||||
continue 3; // bust out of both of these loops and the surrounding one - e.g. move on to the next header
|
||||
continue 3; // bust out of both of these loops; as well as the surrounding one - e.g. move on to the next header
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,9 +171,6 @@ class Importer extends Component
|
||||
'license' => trans('general.licenses'),
|
||||
'location' => trans('general.locations'),
|
||||
'user' => trans('general.users'),
|
||||
'supplier' => trans('general.suppliers'),
|
||||
'manufacturer' => trans('general.manufacturers'),
|
||||
'category' => trans('general.categories'),
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -203,7 +193,6 @@ class Importer extends Component
|
||||
];
|
||||
|
||||
$this->assets_fields = [
|
||||
'id' => trans('general.id'),
|
||||
'asset_eol_date' => trans('admin/hardware/form.eol_date'),
|
||||
'asset_model' => trans('general.model_name'),
|
||||
'asset_notes' => trans('general.item_notes', ['item' => trans('admin/hardware/general.asset')]),
|
||||
@@ -343,7 +332,6 @@ class Importer extends Component
|
||||
|
||||
$this->locations_fields = [
|
||||
'id' => trans('general.id'),
|
||||
'name' => trans('general.name'),
|
||||
'address' => trans('general.address'),
|
||||
'address2' => trans('general.importer.address2'),
|
||||
'city' => trans('general.city'),
|
||||
@@ -352,52 +340,13 @@ class Importer extends Component
|
||||
'ldap_ou' => trans('admin/locations/table.ldap_ou'),
|
||||
'manager' => trans('general.importer.manager_full_name'),
|
||||
'manager_username' => trans('general.importer.manager_username'),
|
||||
'name' => trans('general.item_name_var', ['item' => trans('general.location')]),
|
||||
'notes' => trans('general.notes'),
|
||||
'parent_location' => trans('admin/locations/table.parent'),
|
||||
'state' => trans('general.state'),
|
||||
'zip' => trans('general.zip'),
|
||||
];
|
||||
|
||||
$this->suppliers_fields = [
|
||||
'id' => trans('general.id'),
|
||||
'name' => trans('general.name'),
|
||||
'address' => trans('general.address'),
|
||||
'address2' => trans('general.importer.address2'),
|
||||
'city' => trans('general.city'),
|
||||
'notes' => trans('general.notes'),
|
||||
'state' => trans('general.state'),
|
||||
'zip' => trans('general.zip'),
|
||||
'phone' => trans('general.phone'),
|
||||
'fax' => trans('general.fax'),
|
||||
'url' => trans('general.url'),
|
||||
'contact' => trans('general.contact'),
|
||||
'email' => trans('general.email'),
|
||||
];
|
||||
|
||||
$this->manufacturers_fields = [
|
||||
'id' => trans('general.id'),
|
||||
'name' => trans('general.name'),
|
||||
'notes' => trans('general.notes'),
|
||||
'support_phone' => trans('admin/manufacturers/table.support_phone'),
|
||||
'support_url' => trans('admin/manufacturers/table.support_url'),
|
||||
'support_email' => trans('admin/manufacturers/table.support_email'),
|
||||
'warranty_lookup_url' => trans('admin/manufacturers/table.warranty_lookup_url'),
|
||||
'url' => trans('general.url'),
|
||||
];
|
||||
|
||||
$this->categories_fields = [
|
||||
'id' => trans('general.id'),
|
||||
'name' => trans('general.name'),
|
||||
'notes' => trans('general.notes'),
|
||||
'category_type' => trans('admin/categories/general.import_category_type'),
|
||||
'eula_text' => trans('admin/categories/general.import_eula_text'),
|
||||
'use_default_eula' => trans('admin/categories/general.use_default_eula_column'),
|
||||
'require_acceptance' => trans('admin/categories/general.import_require_acceptance'),
|
||||
'checkin_email' => trans('admin/categories/general.import_checkin_email'),
|
||||
];
|
||||
|
||||
|
||||
|
||||
$this->assetmodels_fields = [
|
||||
'category' => trans('general.category'),
|
||||
'eol' => trans('general.eol'),
|
||||
@@ -422,8 +371,6 @@ class Importer extends Component
|
||||
'consumable name',
|
||||
'component name',
|
||||
'name',
|
||||
'supplier name',
|
||||
'location name',
|
||||
],
|
||||
'item_no' => [
|
||||
'item number',
|
||||
|
||||
@@ -113,13 +113,7 @@ class Actionlog extends SnipeModel
|
||||
} elseif (auth()->user() && auth()->user()->company) {
|
||||
$actionlog->company_id = auth()->user()->company_id;
|
||||
}
|
||||
|
||||
if ($actionlog->action_date == '') {
|
||||
$actionlog->action_date = Carbon::now();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -122,9 +122,9 @@ class Asset extends Depreciable
|
||||
'assigned_to' => ['nullable', 'integer', 'required_with:assigned_type'],
|
||||
'assigned_type' => ['nullable', 'required_with:assigned_to', 'in:'.User::class.",".Location::class.",".Asset::class],
|
||||
'requestable' => ['nullable', 'boolean'],
|
||||
'assigned_user' => ['integer', 'nullable', 'exists:users,id,deleted_at,NULL'],
|
||||
'assigned_location' => ['integer', 'nullable', 'exists:locations,id,deleted_at,NULL', 'fmcs_location'],
|
||||
'assigned_asset' => ['integer', 'nullable', 'exists:assets,id,deleted_at,NULL']
|
||||
'assigned_user' => ['nullable', 'exists:users,id,deleted_at,NULL'],
|
||||
'assigned_location' => ['nullable', 'exists:locations,id,deleted_at,NULL', 'fmcs_location'],
|
||||
'assigned_asset' => ['nullable', 'exists:assets,id,deleted_at,NULL']
|
||||
];
|
||||
|
||||
|
||||
@@ -963,7 +963,6 @@ class Asset extends Depreciable
|
||||
return $this->model->category->require_acceptance;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class AssetMaintenance extends Model implements ICompanyableChild
|
||||
protected $table = 'asset_maintenances';
|
||||
protected $rules = [
|
||||
'asset_id' => 'required|integer',
|
||||
'supplier_id' => 'nullable|integer',
|
||||
'supplier_id' => 'required|integer',
|
||||
'asset_maintenance_type' => 'required',
|
||||
'title' => 'required|max:100',
|
||||
'is_warranty' => 'boolean',
|
||||
|
||||
@@ -160,7 +160,7 @@ final class Company extends SnipeModel
|
||||
|
||||
|
||||
if (auth()->user()) {
|
||||
// Log::warning('Companyable is '.$companyable);
|
||||
Log::warning('Companyable is '.$companyable);
|
||||
$current_user_company_id = auth()->user()->company_id;
|
||||
$companyable_company_id = $companyable->company_id;
|
||||
return $current_user_company_id == null || $current_user_company_id == $companyable_company_id || auth()->user()->isSuperUser();
|
||||
|
||||
@@ -43,8 +43,8 @@ class DefaultLabel extends RectangleSheet
|
||||
|
||||
$this->textSize = Helper::convertUnit($settings->labels_fontsize, 'pt', 'in');
|
||||
|
||||
$this->labelWidth = $this->setLabelWidth($settings);
|
||||
$this->labelHeight = $this->setLabelHeight($settings);
|
||||
$this->labelWidth = $settings->labels_width;
|
||||
$this->labelHeight = $settings->labels_height;
|
||||
|
||||
$this->labelSpacingH = $settings->labels_display_sgutter;
|
||||
$this->labelSpacingV = $settings->labels_display_bgutter;
|
||||
@@ -181,25 +181,6 @@ class DefaultLabel extends RectangleSheet
|
||||
}
|
||||
}
|
||||
|
||||
private function setLabelWidth(Setting $settings)
|
||||
{
|
||||
$labelWidth = $settings->labels_width;
|
||||
|
||||
if ($labelWidth == 0) {
|
||||
$labelWidth = 0.1;
|
||||
}
|
||||
|
||||
return $labelWidth;
|
||||
}
|
||||
|
||||
private function setLabelHeight(?Setting $settings)
|
||||
{
|
||||
$labelHeight = $settings->labels_height;
|
||||
|
||||
if ($labelHeight == 0) {
|
||||
$labelHeight = 0.1;
|
||||
}
|
||||
|
||||
return $labelHeight;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -135,17 +135,6 @@ class Location extends SnipeModel
|
||||
return $this->hasMany(\App\Models\User::class, 'location_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the location -> admin user relationship
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function adminuser()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* Find assets with this location as their location_id
|
||||
*
|
||||
@@ -385,13 +374,4 @@ class Location extends SnipeModel
|
||||
{
|
||||
return $query->leftJoin('companies as company_sort', 'locations.company_id', '=', 'company_sort.id')->orderBy('company_sort.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to order on the user that created it
|
||||
*/
|
||||
public function scopeOrderByCreatedByName($query, $order)
|
||||
{
|
||||
return $query->leftJoin('users as admin_sort', 'locations.created_by', '=', 'admin_sort.id')->select('locations.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,10 +89,13 @@ trait Loggable
|
||||
$log->note = $note;
|
||||
$log->action_date = $action_date;
|
||||
|
||||
if (! $log->action_date) {
|
||||
$log->action_date = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$changed = [];
|
||||
$array_to_flip = array_keys($fields_array);
|
||||
$array_to_flip = array_merge($array_to_flip, ['name','status_id','location_id','expected_checkin']);
|
||||
$array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']);
|
||||
$originalValues = array_intersect_key($originalValues, array_flip($array_to_flip));
|
||||
|
||||
|
||||
@@ -179,7 +182,7 @@ trait Loggable
|
||||
$log->note = $note;
|
||||
$log->action_date = $action_date;
|
||||
|
||||
if (!$action_date) {
|
||||
if (! $log->action_date) {
|
||||
$log->action_date = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
@@ -190,7 +193,7 @@ trait Loggable
|
||||
$changed = [];
|
||||
|
||||
$array_to_flip = array_keys($fields_array);
|
||||
$array_to_flip = array_merge($array_to_flip, ['name','status_id','location_id','expected_checkin']);
|
||||
$array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']);
|
||||
|
||||
$originalValues = array_intersect_key($originalValues, array_flip($array_to_flip));
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class Supplier extends SnipeModel
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $searchableAttributes = ['name', 'notes', 'phone', 'fax', 'url', 'email', 'contact', 'address', 'address2', 'city', 'state', 'country', 'zip'];
|
||||
protected $searchableAttributes = ['name'];
|
||||
|
||||
/**
|
||||
* The relations and their attributes that should be included when searching the model.
|
||||
@@ -128,18 +128,6 @@ class Supplier extends SnipeModel
|
||||
return $this->hasMany(\App\Models\Consumable::class, 'supplier_id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Establishes the supplier -> admin user relationship
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function adminuser()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the supplier -> asset maintenances relationship
|
||||
*
|
||||
@@ -209,13 +197,4 @@ class Supplier extends SnipeModel
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to order on the user that created it
|
||||
*/
|
||||
public function scopeOrderByCreatedByName($query, $order)
|
||||
{
|
||||
return $query->leftJoin('users as admin_sort', 'suppliers.created_by', '=', 'admin_sort.id')->select('suppliers.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -551,25 +551,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the user -> eula relationship
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
* @since [v8.1.16]
|
||||
* @author [Godfrey Martinez] [<gmartinez@grokability.com>]
|
||||
*/
|
||||
public function eulas()
|
||||
{
|
||||
return $this->hasMany(Actionlog::class, 'target_id')
|
||||
->with('item')
|
||||
->select(['id', 'target_id', 'target_type', 'action_type', 'filename', 'accept_signature', 'created_at'])
|
||||
->where('target_type', self::class)
|
||||
->where('action_type', 'accepted')
|
||||
->whereNotNull('filename')
|
||||
->whereNotNull('accept_signature')
|
||||
->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the user -> requested assets relationship
|
||||
*
|
||||
|
||||
@@ -62,7 +62,6 @@ class AssetObserver
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $asset->id;
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->log_meta = json_encode($changed);
|
||||
@@ -109,7 +108,6 @@ class AssetObserver
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class; // can we instead say $logAction->item = $asset ?
|
||||
$logAction->item_id = $asset->id;
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
if($asset->imported) {
|
||||
@@ -130,7 +128,6 @@ class AssetObserver
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $asset->id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->logaction('delete');
|
||||
}
|
||||
@@ -146,7 +143,6 @@ class AssetObserver
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $asset->id;
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->logaction('restore');
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Presenters;
|
||||
|
||||
/**
|
||||
* Class AccessoryPresenter
|
||||
*/
|
||||
class HistoryPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* Json Column Layout for bootstrap table
|
||||
* @return string
|
||||
*/
|
||||
public static function dataTableLayout($serial = false)
|
||||
{
|
||||
$extra = [];
|
||||
$layout_start = [
|
||||
[
|
||||
'id' => 'id',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.id'),
|
||||
'visible' => false,
|
||||
'class' => 'hidden-xs',
|
||||
],
|
||||
[
|
||||
'field' => 'icon',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/hardware/table.icon'),
|
||||
'visible' => true,
|
||||
'class' => 'hidden-xs',
|
||||
'formatter' => 'iconFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'created_at',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.created_at'),
|
||||
'visible' => false,
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'created_by',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'title' => trans('general.created_by'),
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'action_date',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'title' => trans('general.action_date'),
|
||||
'visible' => false,
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'action_type',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.action'),
|
||||
'visible' => false,
|
||||
],
|
||||
[
|
||||
'field' => 'item',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.item'),
|
||||
'visible' => false,
|
||||
'formatter' => 'polymorphicItemFormatter',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
if ($serial) {
|
||||
$extra = [
|
||||
[
|
||||
'field' => 'item.serial',
|
||||
'title' => trans('admin/hardware/table.serial'),
|
||||
'visible' => false,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$layout_end = [
|
||||
[
|
||||
'field' => 'target',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.target'),
|
||||
'visible' => false,
|
||||
'formatter' => 'polymorphicItemFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'file',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.file_name'),
|
||||
'visible' => false,
|
||||
'formatter' => 'fileUploadNameFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'file_download',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.download'),
|
||||
'visible' => false,
|
||||
'formatter' => 'fileUploadFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'note',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'visible' => false,
|
||||
'title' => trans('general.notes'),
|
||||
'formatter' => 'notesFormatter'
|
||||
],
|
||||
[
|
||||
'field' => 'signature_file',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.signature'),
|
||||
'visible' => false,
|
||||
'formatter' => 'imageFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'log_meta',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'visible' => true,
|
||||
'title' => trans('admin/hardware/table.changed'),
|
||||
'formatter' => 'changeLogFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'remote_ip',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'visible' => true,
|
||||
'title' => trans('admin/settings/general.login_ip'),
|
||||
],
|
||||
[
|
||||
'field' => 'user_agent',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'visible' => true,
|
||||
'title' => trans('admin/settings/general.login_user_agent'),
|
||||
],
|
||||
[
|
||||
'field' => 'action_source',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'visible' => true,
|
||||
'title' => trans('general.action_source'),
|
||||
],
|
||||
];
|
||||
|
||||
$merged = array_merge($layout_start, $extra, $layout_end);
|
||||
return json_encode($merged);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -208,16 +208,7 @@ class LocationPresenter extends Presenter
|
||||
'title' => trans('general.created_at'),
|
||||
'visible' => false,
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'created_by',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.created_by'),
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
],[
|
||||
], [
|
||||
'field' => 'actions',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Presenters;
|
||||
|
||||
/**
|
||||
* Class LocationPresenter
|
||||
*/
|
||||
class SupplierPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* Json Column Layout for bootstrap table
|
||||
*/
|
||||
public static function dataTableLayout()
|
||||
{
|
||||
$layout = [
|
||||
[
|
||||
'field' => 'id',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.id'),
|
||||
'visible' => false,
|
||||
],
|
||||
[
|
||||
'field' => 'name',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => false,
|
||||
'title' => trans('general.name'),
|
||||
'visible' => true,
|
||||
'formatter' => 'suppliersLinkFormatter',
|
||||
], [
|
||||
'field' => 'image',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.image'),
|
||||
'visible' => true,
|
||||
'formatter' => 'imageFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'assets_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.assets'),
|
||||
'titleTooltip' => trans('general.assets'),
|
||||
'visible' => true,
|
||||
'class' => 'css-barcode',
|
||||
], [
|
||||
'field' => 'accessories_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.accessories'),
|
||||
'titleTooltip' => trans('general.accessories'),
|
||||
'visible' => true,
|
||||
'class' => 'css-accessory',
|
||||
],
|
||||
[
|
||||
'field' => 'licenses_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.licenses'),
|
||||
'titleTooltip' => trans('general.licenses'),
|
||||
'visible' => true,
|
||||
'class' => 'css-license',
|
||||
], [
|
||||
'field' => 'components_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.components'),
|
||||
'titleTooltip' => trans('general.components'),
|
||||
'visible' => true,
|
||||
'class' => 'css-component',
|
||||
], [
|
||||
'field' => 'consumables_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.consumables'),
|
||||
'titleTooltip' => trans('general.consumables'),
|
||||
'visible' => true,
|
||||
'class' => 'css-consumable',
|
||||
], [
|
||||
'field' => 'url',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.url'),
|
||||
'visible' => true,
|
||||
'formatter' => 'externalLinkFormatter',
|
||||
], [
|
||||
'field' => 'address',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.address'),
|
||||
'visible' => true,
|
||||
], [
|
||||
'field' => 'address2',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.address2'),
|
||||
'visible' => false,
|
||||
], [
|
||||
'field' => 'city',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.city'),
|
||||
'visible' => true,
|
||||
], [
|
||||
'field' => 'state',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.state'),
|
||||
'visible' => true,
|
||||
], [
|
||||
'field' => 'zip',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.zip'),
|
||||
'visible' => false,
|
||||
], [
|
||||
'field' => 'country',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/table.country'),
|
||||
'visible' => false,
|
||||
], [
|
||||
'field' => 'phone',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/users/table.phone'),
|
||||
'visible' => false,
|
||||
'formatter' => 'phoneFormatter',
|
||||
], [
|
||||
'field' => 'fax',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/suppliers/table.fax'),
|
||||
'visible' => false,
|
||||
'formatter' => 'phoneFormatter',
|
||||
], [
|
||||
'field' => 'notes',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'visible' => false,
|
||||
'title' => trans('general.notes'),
|
||||
], [
|
||||
'field' => 'created_at',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.created_at'),
|
||||
'visible' => false,
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
], [
|
||||
'field' => 'created_by',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.created_by'),
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
], [
|
||||
'field' => 'actions',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'switchable' => false,
|
||||
'title' => trans('table.actions'),
|
||||
'visible' => true,
|
||||
'formatter' => 'suppliersActionsFormatter',
|
||||
],
|
||||
];
|
||||
|
||||
return json_encode($layout);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Link to this supplier name
|
||||
* @return string
|
||||
*/
|
||||
public function nameUrl()
|
||||
{
|
||||
return (string) link_to_route('suppliers.show', $this->name, $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for Polymorphism.
|
||||
* @return mixed
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->model->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Url to view this item.
|
||||
* @return string
|
||||
*/
|
||||
public function viewUrl()
|
||||
{
|
||||
return route('suppliers.show', $this->id);
|
||||
}
|
||||
|
||||
public function glyph()
|
||||
{
|
||||
return '<x-icon type="suppliers" />';
|
||||
}
|
||||
|
||||
public function fullName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* This ONLY fires on 429 responses.
|
||||
*
|
||||
* https://laravel.com/docs/8.x/routing#rate-limiting
|
||||
*
|
||||
* @return void
|
||||
@@ -85,17 +83,9 @@ class RouteServiceProvider extends ServiceProvider
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
|
||||
// Rate limiter for API calls - this sends the correct API headers to show the user the remaining time they have to wait and gives them the 429 status code if they are throttled
|
||||
// Rate limiter for API calls
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(config('app.api_throttle_per_minute'))->by(optional($request->user())->id ?: $request->ip())
|
||||
->response(function ($request, $headers) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'messages' => 'Too many requests. Try again in '.$headers['Retry-After'].' seconds.',
|
||||
'status_code' => 429,
|
||||
'retryAfter' => $headers['Retry-After'] ?? 60,
|
||||
], 429, $headers);
|
||||
});
|
||||
return Limit::perMinute(config('app.api_throttle_per_minute'))->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
|
||||
// Rate limiter for forgotten password requests
|
||||
|
||||
@@ -25,16 +25,6 @@ class Label implements View
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
|
||||
/**
|
||||
* TCPDF output destination.
|
||||
* "I" - inline by default.
|
||||
* See TCPDF's Output method for details.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $destination = 'I';
|
||||
|
||||
public function __construct() {
|
||||
$this->data = new Collection();
|
||||
}
|
||||
@@ -150,9 +140,7 @@ class Label implements View
|
||||
$barcode2DTarget = $asset->serial;
|
||||
break;
|
||||
case 'location':
|
||||
$barcode2DTarget = $asset->location_id
|
||||
? route('locations.show', $asset->location_id)
|
||||
: null;
|
||||
$barcode2DTarget = route('locations.show', $asset->location_id);
|
||||
break;
|
||||
case 'hardware_id':
|
||||
default:
|
||||
@@ -232,7 +220,7 @@ class Label implements View
|
||||
$template->writeAll($pdf, $data);
|
||||
|
||||
$filename = $assets->count() > 1 ? 'assets.pdf' : $assets->first()->asset_tag.'.pdf';
|
||||
$pdf->Output($filename, $this->destination);
|
||||
$pdf->Output($filename, 'I');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
"eduardokum/laravel-mail-auto-embed": "^2.0",
|
||||
"enshrined/svg-sanitize": "^0.15.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"fakerphp/faker": "^1.24",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"intervention/image": "^2.5",
|
||||
"javiereguiluz/easyslugger": "^1.0",
|
||||
@@ -75,7 +74,8 @@
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
"tecnickcom/tcpdf": "^6.5",
|
||||
"unicodeveloper/laravel-password": "^1.0",
|
||||
"watson/validating": "^8.1"
|
||||
"watson/validating": "^8.1",
|
||||
"fakerphp/faker": "^1.16"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ldap": "*",
|
||||
|
||||
1767
composer.lock
generated
1767
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v8.1.15',
|
||||
'full_app_version' => 'v8.1.15 - build 18405-ge4314cf42',
|
||||
'build_version' => '18405',
|
||||
'app_version' => 'v8.1.4',
|
||||
'full_app_version' => 'v8.1.4 - build 18245-g101b8afb5',
|
||||
'build_version' => '18245',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'ge4314cf42',
|
||||
'full_hash' => 'v8.1.15-13-ge4314cf42',
|
||||
'hash_version' => 'g101b8afb5',
|
||||
'full_hash' => 'v8.1.4-180-g101b8afb5',
|
||||
'branch' => 'develop',
|
||||
);
|
||||
@@ -165,72 +165,4 @@ class ImportFactory extends Factory
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a supplier import type.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function suppliers()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
$fileBuilder = Importing\SuppliersImportFileBuilder::new();
|
||||
$attributes['name'] = "Supplier {$attributes['name']}";
|
||||
$attributes['import_type'] = 'supplier';
|
||||
$attributes['header_row'] = $fileBuilder->toCsv()[0];
|
||||
$attributes['first_row'] = $fileBuilder->firstRow();
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an supplier import type.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function locations()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
$fileBuilder = Importing\SuppliersImportFileBuilder::new();
|
||||
$attributes['name'] = "Location {$attributes['name']}";
|
||||
$attributes['import_type'] = 'location';
|
||||
$attributes['header_row'] = $fileBuilder->toCsv()[0];
|
||||
$attributes['first_row'] = $fileBuilder->firstRow();
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a supplier import type.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function manufacturers()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
$fileBuilder = Importing\ManufacturersImportFileBuilder::new();
|
||||
$attributes['name'] = "Manufacturer {$attributes['name']}";
|
||||
$attributes['import_type'] = 'manufacturer';
|
||||
$attributes['header_row'] = $fileBuilder->toCsv()[0];
|
||||
$attributes['first_row'] = $fileBuilder->firstRow();
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
|
||||
public function categories()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
$fileBuilder = Importing\CategoriesImportFileBuilder::new();
|
||||
$attributes['name'] = "Category {$attributes['name']}";
|
||||
$attributes['import_type'] = 'category';
|
||||
$attributes['header_row'] = $fileBuilder->toCsv()[0];
|
||||
$attributes['first_row'] = $fileBuilder->firstRow();
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
|
||||
Schema::table('action_logs', function (Blueprint $table) {
|
||||
$table->index(['action_date']);
|
||||
});
|
||||
|
||||
DB::update('update '.DB::getTablePrefix().'action_logs set action_date = created_at where created_at IS NOT NULL and action_date IS NULL');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->boolean('admin_cc_always')->after('admin_cc_email')->default(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->dropColumn('admin_cc_always');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('assets')->whereNotNull('assigned_type')->whereNull('assigned_to')->update(['assigned_type' => null]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('action_logs', function (Blueprint $table) {
|
||||
$table->index('deleted_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('action_logs', function (Blueprint $table) {
|
||||
$table->dropIndex('deleted_at');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('asset_maintenances', function (Blueprint $table) {
|
||||
$table->integer('supplier_id')->nullable()->default(null)->change();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
||||
@@ -21,7 +21,7 @@ services:
|
||||
- .env.dev.docker
|
||||
|
||||
mariadb:
|
||||
image: mariadb:11.4.7
|
||||
image: mariadb:11.5.2
|
||||
volumes:
|
||||
- db:/var/lib/mysql
|
||||
env_file:
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7.4.3
|
||||
image: redis:7.4.0
|
||||
|
||||
mailhog:
|
||||
image: mailhog/mailhog:v1.0.1
|
||||
|
||||
@@ -20,7 +20,7 @@ services:
|
||||
- .env
|
||||
|
||||
db:
|
||||
image: mariadb:11.4.7
|
||||
image: mariadb:11.5.2
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
|
||||
@@ -100,13 +100,9 @@ chown -R docker:root /var/www/html/storage/framework/cache
|
||||
# Fix php settings
|
||||
if [ -v "PHP_UPLOAD_LIMIT" ]
|
||||
then
|
||||
PHP_INI_FILE=$(find /etc/php/*/apache2/php.ini)
|
||||
if [ -e $PHP_INI_FILE ]
|
||||
then
|
||||
echo "Changing upload limit to ${PHP_UPLOAD_LIMIT}M in ${PHP_INI_FILE}"
|
||||
sed -i "s/^upload_max_filesize.*/upload_max_filesize = ${PHP_UPLOAD_LIMIT}M/" $PHP_INI_FILE
|
||||
sed -i "s/^post_max_size.*/post_max_size = ${PHP_UPLOAD_LIMIT}M/" $PHP_INI_FILE
|
||||
fi
|
||||
echo "Changing upload limit to ${PHP_UPLOAD_LIMIT}"
|
||||
sed -i "s/^upload_max_filesize.*/upload_max_filesize = ${PHP_UPLOAD_LIMIT}M/" /etc/php*/php.ini
|
||||
sed -i "s/^post_max_size.*/post_max_size = ${PHP_UPLOAD_LIMIT}M/" /etc/php*/php.ini
|
||||
fi
|
||||
|
||||
# If the Oauth DB files are not present copy the vendor files over to the db migrations
|
||||
@@ -124,9 +120,4 @@ php artisan migrate --force
|
||||
php artisan config:clear
|
||||
php artisan config:cache
|
||||
|
||||
# we do this after the artisan commands to ensure that if the laravel
|
||||
# log got created by root, we set the permissions back
|
||||
touch /var/www/html/storage/logs/laravel.log
|
||||
chown -R docker:root /var/www/html/storage/logs/laravel.log
|
||||
|
||||
exec supervisord -c /supervisord.conf
|
||||
|
||||
@@ -79,7 +79,6 @@ done
|
||||
chown -R apache:root /var/lib/snipeit/data/*
|
||||
chown -R apache:root /var/lib/snipeit/dumps
|
||||
chown -R apache:root /var/lib/snipeit/keys
|
||||
chown -R apache:root /var/www/html/storage/framework/cache
|
||||
|
||||
# Fix php settings
|
||||
if [ ! -z "${PHP_UPLOAD_LIMIT}" ]
|
||||
|
||||
@@ -99,7 +99,10 @@ then
|
||||
cp -a /var/www/html/vendor/laravel/passport/database/migrations/* /var/www/html/database/migrations/
|
||||
fi
|
||||
|
||||
# Create laravel log file
|
||||
touch /var/www/html/storage/logs/laravel.log
|
||||
# Add correct permissions for files and directories
|
||||
chown www-data:www-data /var/www/html/storage/logs/laravel.log
|
||||
chown -R www-data:www-data \
|
||||
/var/lib/snipeit/data \
|
||||
/var/lib/snipeit/dumps \
|
||||
@@ -111,11 +114,6 @@ php artisan migrate --force
|
||||
php artisan config:clear
|
||||
php artisan config:cache
|
||||
|
||||
# Create laravel log file
|
||||
touch /var/www/html/storage/logs/laravel.log
|
||||
# ensure it's owned by www:data in case it was created by root
|
||||
chown www-data:www-data /var/www/html/storage/logs/laravel.log
|
||||
|
||||
echo [INFO docker entrypoint] End script execution
|
||||
|
||||
exec "$@"
|
||||
exec "$@"
|
||||
11
public/js/dist/bootstrap-table.js
vendored
11
public/js/dist/bootstrap-table.js
vendored
File diff suppressed because one or more lines are too long
@@ -110,6 +110,6 @@
|
||||
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=7b315b9612b8fde8f9c5b0ddb6bba690",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=54d676a6ea8677dd48f6c4b3041292cf",
|
||||
"/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=60097b6b56d80cbc76257d4ecf6f57b4",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=783d3a8076337744f0176d60e1041ea4",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=8c6d7286f667eeb62a0a28a09851a6c3"
|
||||
}
|
||||
|
||||
261
public/vendor/livewire/livewire.esm.js
vendored
261
public/vendor/livewire/livewire.esm.js
vendored
@@ -2863,7 +2863,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
var Alpine20 = {
|
||||
var Alpine23 = {
|
||||
get reactive() {
|
||||
return reactive;
|
||||
},
|
||||
@@ -2876,7 +2876,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
get raw() {
|
||||
return raw;
|
||||
},
|
||||
version: "3.14.8",
|
||||
version: "3.14.9",
|
||||
flushAndStopDeferringMutations,
|
||||
dontAutoEvaluateFunctions,
|
||||
disableEffectScheduling,
|
||||
@@ -2929,7 +2929,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
data,
|
||||
bind: bind2
|
||||
};
|
||||
var alpine_default = Alpine20;
|
||||
var alpine_default = Alpine23;
|
||||
var import_reactivity10 = __toESM2(require_reactivity());
|
||||
magic("nextTick", () => nextTick);
|
||||
magic("dispatch", (el) => dispatch3.bind(dispatch3, el));
|
||||
@@ -3857,8 +3857,8 @@ var require_module_cjs2 = __commonJS({
|
||||
default: () => module_default
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.directive("collapse", collapse3);
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.directive("collapse", collapse3);
|
||||
collapse3.inline = (el, { modifiers }) => {
|
||||
if (!modifiers.includes("min"))
|
||||
return;
|
||||
@@ -3878,7 +3878,7 @@ var require_module_cjs2 = __commonJS({
|
||||
if (!el._x_isShown)
|
||||
el.style.overflow = "hidden";
|
||||
let setFunction = (el2, styles) => {
|
||||
let revertFunction = Alpine20.setStyles(el2, styles);
|
||||
let revertFunction = Alpine23.setStyles(el2, styles);
|
||||
return styles.height ? () => {
|
||||
} : revertFunction;
|
||||
};
|
||||
@@ -3901,7 +3901,7 @@ var require_module_cjs2 = __commonJS({
|
||||
if (current === full) {
|
||||
current = floor;
|
||||
}
|
||||
Alpine20.transition(el, Alpine20.setStyles, {
|
||||
Alpine23.transition(el, Alpine23.setStyles, {
|
||||
during: transitionStyles,
|
||||
start: { height: current + "px" },
|
||||
end: { height: full + "px" }
|
||||
@@ -3915,7 +3915,7 @@ var require_module_cjs2 = __commonJS({
|
||||
}, after = () => {
|
||||
}) {
|
||||
let full = el.getBoundingClientRect().height;
|
||||
Alpine20.transition(el, setFunction, {
|
||||
Alpine23.transition(el, setFunction, {
|
||||
during: transitionStyles,
|
||||
start: { height: full + "px" },
|
||||
end: { height: floor + "px" }
|
||||
@@ -4751,14 +4751,14 @@ var require_module_cjs3 = __commonJS({
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
var import_focus_trap = __toESM2(require_focus_trap());
|
||||
var import_tabbable = __toESM2(require_dist());
|
||||
function src_default(Alpine20) {
|
||||
function src_default(Alpine23) {
|
||||
let lastFocused;
|
||||
let currentFocused;
|
||||
window.addEventListener("focusin", () => {
|
||||
lastFocused = currentFocused;
|
||||
currentFocused = document.activeElement;
|
||||
});
|
||||
Alpine20.magic("focus", (el) => {
|
||||
Alpine23.magic("focus", (el) => {
|
||||
let within = el;
|
||||
return {
|
||||
__noscroll: false,
|
||||
@@ -4862,7 +4862,7 @@ var require_module_cjs3 = __commonJS({
|
||||
}
|
||||
};
|
||||
});
|
||||
Alpine20.directive("trap", Alpine20.skipDuringClone((el, { expression, modifiers }, { effect, evaluateLater, cleanup }) => {
|
||||
Alpine23.directive("trap", Alpine23.skipDuringClone((el, { expression, modifiers }, { effect, evaluateLater, cleanup }) => {
|
||||
let evaluator = evaluateLater(expression);
|
||||
let oldValue = false;
|
||||
let options = {
|
||||
@@ -4980,7 +4980,7 @@ var require_module_cjs4 = __commonJS({
|
||||
persist: () => src_default
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
function src_default(Alpine20) {
|
||||
function src_default(Alpine23) {
|
||||
let persist3 = () => {
|
||||
let alias;
|
||||
let storage;
|
||||
@@ -4995,11 +4995,11 @@ var require_module_cjs4 = __commonJS({
|
||||
setItem: dummy.set.bind(dummy)
|
||||
};
|
||||
}
|
||||
return Alpine20.interceptor((initialValue, getter, setter, path, key) => {
|
||||
return Alpine23.interceptor((initialValue, getter, setter, path, key) => {
|
||||
let lookup = alias || `_x_${path}`;
|
||||
let initial = storageHas(lookup, storage) ? storageGet(lookup, storage) : initialValue;
|
||||
setter(initial);
|
||||
Alpine20.effect(() => {
|
||||
Alpine23.effect(() => {
|
||||
let value = getter();
|
||||
storageSet(lookup, value, storage);
|
||||
setter(value);
|
||||
@@ -5015,12 +5015,12 @@ var require_module_cjs4 = __commonJS({
|
||||
};
|
||||
});
|
||||
};
|
||||
Object.defineProperty(Alpine20, "$persist", { get: () => persist3() });
|
||||
Alpine20.magic("persist", persist3);
|
||||
Alpine20.persist = (key, { get, set }, storage = localStorage) => {
|
||||
Object.defineProperty(Alpine23, "$persist", { get: () => persist3() });
|
||||
Alpine23.magic("persist", persist3);
|
||||
Alpine23.persist = (key, { get, set }, storage = localStorage) => {
|
||||
let initial = storageHas(key, storage) ? storageGet(key, storage) : get();
|
||||
set(initial);
|
||||
Alpine20.effect(() => {
|
||||
Alpine23.effect(() => {
|
||||
let value = get();
|
||||
storageSet(key, value, storage);
|
||||
set(value);
|
||||
@@ -5069,8 +5069,8 @@ var require_module_cjs5 = __commonJS({
|
||||
intersect: () => src_default
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.directive("intersect", Alpine20.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.directive("intersect", Alpine23.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
|
||||
let evaluate = evaluateLater(expression);
|
||||
let options = {
|
||||
rootMargin: getRootMargin(modifiers),
|
||||
@@ -5151,8 +5151,8 @@ var require_module_cjs6 = __commonJS({
|
||||
resize: () => src_default
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.directive("resize", Alpine20.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.directive("resize", Alpine23.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
|
||||
let evaluator = evaluateLater(expression);
|
||||
let evaluate = (width, height) => {
|
||||
evaluator(() => {
|
||||
@@ -6396,20 +6396,20 @@ var require_module_cjs7 = __commonJS({
|
||||
platform: platformWithCache
|
||||
});
|
||||
};
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.magic("anchor", (el) => {
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.magic("anchor", (el) => {
|
||||
if (!el._x_anchor)
|
||||
throw "Alpine: No x-anchor directive found on element using $anchor...";
|
||||
return el._x_anchor;
|
||||
});
|
||||
Alpine20.interceptClone((from, to) => {
|
||||
Alpine23.interceptClone((from, to) => {
|
||||
if (from && from._x_anchor && !to._x_anchor) {
|
||||
to._x_anchor = from._x_anchor;
|
||||
}
|
||||
});
|
||||
Alpine20.directive("anchor", Alpine20.skipDuringClone((el, { expression, modifiers, value }, { cleanup, evaluate: evaluate2 }) => {
|
||||
Alpine23.directive("anchor", Alpine23.skipDuringClone((el, { expression, modifiers, value }, { cleanup, evaluate: evaluate2 }) => {
|
||||
let { placement, offsetValue, unstyled } = getOptions(modifiers);
|
||||
el._x_anchor = Alpine20.reactive({ x: 0, y: 0 });
|
||||
el._x_anchor = Alpine23.reactive({ x: 0, y: 0 });
|
||||
let reference = evaluate2(expression);
|
||||
if (!reference)
|
||||
throw "Alpine: no element provided to x-anchor...";
|
||||
@@ -6784,7 +6784,8 @@ var require_module_cjs8 = __commonJS({
|
||||
return swapElements(from2, to);
|
||||
}
|
||||
let updateChildrenOnly = false;
|
||||
if (shouldSkip(updating, from2, to, () => updateChildrenOnly = true))
|
||||
let skipChildren = false;
|
||||
if (shouldSkipChildren(updating, () => skipChildren = true, from2, to, () => updateChildrenOnly = true))
|
||||
return;
|
||||
if (from2.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from2, to);
|
||||
@@ -6801,7 +6802,9 @@ var require_module_cjs8 = __commonJS({
|
||||
patchAttributes(from2, to);
|
||||
}
|
||||
updated(from2, to);
|
||||
patchChildren(from2, to);
|
||||
if (!skipChildren) {
|
||||
patchChildren(from2, to);
|
||||
}
|
||||
}
|
||||
function differentElementNamesTypesOrKeys(from2, to) {
|
||||
return from2.nodeType != to.nodeType || from2.nodeName != to.nodeName || getKey(from2) != getKey(to);
|
||||
@@ -7015,6 +7018,11 @@ var require_module_cjs8 = __commonJS({
|
||||
hook(...args, () => skip = true);
|
||||
return skip;
|
||||
}
|
||||
function shouldSkipChildren(hook, skipChildren, ...args) {
|
||||
let skip = false;
|
||||
hook(...args, () => skip = true, skipChildren);
|
||||
return skip;
|
||||
}
|
||||
var patched = false;
|
||||
function createElement(html) {
|
||||
const template = document.createElement("template");
|
||||
@@ -7095,8 +7103,8 @@ var require_module_cjs8 = __commonJS({
|
||||
to.setAttribute("id", fromId);
|
||||
to.id = fromId;
|
||||
}
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.morph = morph3;
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.morph = morph3;
|
||||
}
|
||||
var module_default = src_default;
|
||||
}
|
||||
@@ -7129,8 +7137,8 @@ var require_module_cjs9 = __commonJS({
|
||||
stripDown: () => stripDown
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
function src_default(Alpine20) {
|
||||
Alpine20.directive("mask", (el, { value, expression }, { effect, evaluateLater, cleanup }) => {
|
||||
function src_default(Alpine23) {
|
||||
Alpine23.directive("mask", (el, { value, expression }, { effect, evaluateLater, cleanup }) => {
|
||||
let templateFn = () => expression;
|
||||
let lastInputValue = "";
|
||||
queueMicrotask(() => {
|
||||
@@ -7139,7 +7147,7 @@ var require_module_cjs9 = __commonJS({
|
||||
effect(() => {
|
||||
templateFn = (input) => {
|
||||
let result;
|
||||
Alpine20.dontAutoEvaluateFunctions(() => {
|
||||
Alpine23.dontAutoEvaluateFunctions(() => {
|
||||
evaluator((value2) => {
|
||||
result = typeof value2 === "function" ? value2(input) : value2;
|
||||
}, { scope: {
|
||||
@@ -8188,6 +8196,7 @@ var aliases = {
|
||||
"on": "$on",
|
||||
"el": "$el",
|
||||
"id": "$id",
|
||||
"js": "$js",
|
||||
"get": "$get",
|
||||
"set": "$set",
|
||||
"call": "$call",
|
||||
@@ -8259,6 +8268,14 @@ wireProperty("$el", (component) => {
|
||||
wireProperty("$id", (component) => {
|
||||
return component.id;
|
||||
});
|
||||
wireProperty("$js", (component) => {
|
||||
let fn = component.addJsAction.bind(component);
|
||||
let jsActions = component.getJsActions();
|
||||
Object.keys(jsActions).forEach((name) => {
|
||||
fn[name] = component.getJsAction(name);
|
||||
});
|
||||
return fn;
|
||||
});
|
||||
wireProperty("$set", (component) => async (property, value, live = true) => {
|
||||
dataSet(component.reactive, property, value);
|
||||
if (live) {
|
||||
@@ -8354,6 +8371,7 @@ var Component = class {
|
||||
this.ephemeral = extractData(deepClone(this.snapshot.data));
|
||||
this.reactive = Alpine.reactive(this.ephemeral);
|
||||
this.queuedUpdates = {};
|
||||
this.jsActions = {};
|
||||
this.$wire = generateWireObject(this, this.reactive);
|
||||
this.cleanups = [];
|
||||
this.processEffects(this.effects);
|
||||
@@ -8429,6 +8447,18 @@ var Component = class {
|
||||
}
|
||||
el.setAttribute("wire:effects", JSON.stringify(effects));
|
||||
}
|
||||
addJsAction(name, action) {
|
||||
this.jsActions[name] = action;
|
||||
}
|
||||
hasJsAction(name) {
|
||||
return this.jsActions[name] !== void 0;
|
||||
}
|
||||
getJsAction(name) {
|
||||
return this.jsActions[name].bind(this.$wire);
|
||||
}
|
||||
getJsActions() {
|
||||
return this.jsActions;
|
||||
}
|
||||
addCleanup(cleanup) {
|
||||
this.cleanups.push(cleanup);
|
||||
}
|
||||
@@ -9111,6 +9141,7 @@ var attributesExemptFromScriptTagHashing = [
|
||||
];
|
||||
function swapCurrentPageWithNewHtml(html, andThen) {
|
||||
let newDocument = new DOMParser().parseFromString(html, "text/html");
|
||||
let newHtml = newDocument.documentElement;
|
||||
let newBody = document.adoptNode(newDocument.body);
|
||||
let newHead = document.adoptNode(newDocument.head);
|
||||
oldBodyScriptTagHashes = oldBodyScriptTagHashes.concat(Array.from(document.body.querySelectorAll("script")).map((i) => {
|
||||
@@ -9118,6 +9149,7 @@ function swapCurrentPageWithNewHtml(html, andThen) {
|
||||
}));
|
||||
let afterRemoteScriptsHaveLoaded = () => {
|
||||
};
|
||||
replaceHtmlAttributes(newHtml);
|
||||
mergeNewHead(newHead).finally(() => {
|
||||
afterRemoteScriptsHaveLoaded();
|
||||
});
|
||||
@@ -9137,6 +9169,21 @@ function prepNewBodyScriptTagsToRun(newBody, oldBodyScriptTagHashes2) {
|
||||
i.replaceWith(cloneScriptTag(i));
|
||||
});
|
||||
}
|
||||
function replaceHtmlAttributes(newHtmlElement) {
|
||||
let currentHtmlElement = document.documentElement;
|
||||
Array.from(newHtmlElement.attributes).forEach((attr) => {
|
||||
const name = attr.name;
|
||||
const value = attr.value;
|
||||
if (currentHtmlElement.getAttribute(name) !== value) {
|
||||
currentHtmlElement.setAttribute(name, value);
|
||||
}
|
||||
});
|
||||
Array.from(currentHtmlElement.attributes).forEach((attr) => {
|
||||
if (!newHtmlElement.hasAttribute(attr.name)) {
|
||||
currentHtmlElement.removeAttribute(attr.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
function mergeNewHead(newHead) {
|
||||
let children = Array.from(document.head.children);
|
||||
let headChildrenHtmlLookup = children.map((i) => i.outerHTML);
|
||||
@@ -9240,8 +9287,8 @@ var enablePersist = true;
|
||||
var showProgressBar = true;
|
||||
var restoreScroll = true;
|
||||
var autofocus = false;
|
||||
function navigate_default(Alpine20) {
|
||||
Alpine20.navigate = (url) => {
|
||||
function navigate_default(Alpine23) {
|
||||
Alpine23.navigate = (url) => {
|
||||
let destination = createUrlObjectFromString(url);
|
||||
let prevented = fireEventForOtherLibrariesToHookInto("alpine:navigate", {
|
||||
url: destination,
|
||||
@@ -9252,11 +9299,11 @@ function navigate_default(Alpine20) {
|
||||
return;
|
||||
navigateTo(destination);
|
||||
};
|
||||
Alpine20.navigate.disableProgressBar = () => {
|
||||
Alpine23.navigate.disableProgressBar = () => {
|
||||
showProgressBar = false;
|
||||
};
|
||||
Alpine20.addInitSelector(() => `[${Alpine20.prefixed("navigate")}]`);
|
||||
Alpine20.directive("navigate", (el, { modifiers }) => {
|
||||
Alpine23.addInitSelector(() => `[${Alpine23.prefixed("navigate")}]`);
|
||||
Alpine23.directive("navigate", (el, { modifiers }) => {
|
||||
let shouldPrefetchOnHover = modifiers.includes("hover");
|
||||
shouldPrefetchOnHover && whenThisLinkIsHoveredFor(el, 60, () => {
|
||||
let destination = extractDestinationFromLink(el);
|
||||
@@ -9293,7 +9340,7 @@ function navigate_default(Alpine20) {
|
||||
showProgressBar && finishAndHideProgressBar();
|
||||
cleanupAlpineElementsOnThePageThatArentInsideAPersistedElement();
|
||||
updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks();
|
||||
preventAlpineFromPickingUpDomChanges(Alpine20, (andAfterAllThis) => {
|
||||
preventAlpineFromPickingUpDomChanges(Alpine23, (andAfterAllThis) => {
|
||||
enablePersist && storePersistantElementsForLater((persistedEl) => {
|
||||
packUpPersistedTeleports(persistedEl);
|
||||
packUpPersistedPopovers(persistedEl);
|
||||
@@ -9315,7 +9362,7 @@ function navigate_default(Alpine20) {
|
||||
setTimeout(() => {
|
||||
autofocus && autofocusElementsWithTheAutofocusAttribute();
|
||||
});
|
||||
nowInitializeAlpineOnTheNewPage(Alpine20);
|
||||
nowInitializeAlpineOnTheNewPage(Alpine23);
|
||||
fireEventForOtherLibrariesToHookInto("alpine:navigated");
|
||||
});
|
||||
});
|
||||
@@ -9348,7 +9395,7 @@ function navigate_default(Alpine20) {
|
||||
storeScrollInformationInHtmlBeforeNavigatingAway();
|
||||
fireEventForOtherLibrariesToHookInto("alpine:navigating");
|
||||
updateCurrentPageHtmlInSnapshotCacheForLaterBackButtonClicks(currentPageUrl, currentPageKey);
|
||||
preventAlpineFromPickingUpDomChanges(Alpine20, (andAfterAllThis) => {
|
||||
preventAlpineFromPickingUpDomChanges(Alpine23, (andAfterAllThis) => {
|
||||
enablePersist && storePersistantElementsForLater((persistedEl) => {
|
||||
packUpPersistedTeleports(persistedEl);
|
||||
packUpPersistedPopovers(persistedEl);
|
||||
@@ -9363,7 +9410,7 @@ function navigate_default(Alpine20) {
|
||||
restoreScrollPositionOrScrollToTop();
|
||||
andAfterAllThis(() => {
|
||||
autofocus && autofocusElementsWithTheAutofocusAttribute();
|
||||
nowInitializeAlpineOnTheNewPage(Alpine20);
|
||||
nowInitializeAlpineOnTheNewPage(Alpine23);
|
||||
fireEventForOtherLibrariesToHookInto("alpine:navigated");
|
||||
});
|
||||
});
|
||||
@@ -9378,10 +9425,10 @@ function fetchHtmlOrUsePrefetchedHtml(fromDestination, callback) {
|
||||
fetchHtml(fromDestination, callback);
|
||||
});
|
||||
}
|
||||
function preventAlpineFromPickingUpDomChanges(Alpine20, callback) {
|
||||
Alpine20.stopObservingMutations();
|
||||
function preventAlpineFromPickingUpDomChanges(Alpine23, callback) {
|
||||
Alpine23.stopObservingMutations();
|
||||
callback((afterAllThis) => {
|
||||
Alpine20.startObservingMutations();
|
||||
Alpine23.startObservingMutations();
|
||||
queueMicrotask(() => {
|
||||
afterAllThis();
|
||||
});
|
||||
@@ -9396,8 +9443,8 @@ function fireEventForOtherLibrariesToHookInto(name, detail) {
|
||||
document.dispatchEvent(event);
|
||||
return event.defaultPrevented;
|
||||
}
|
||||
function nowInitializeAlpineOnTheNewPage(Alpine20) {
|
||||
Alpine20.initTree(document.body, void 0, (el, skip) => {
|
||||
function nowInitializeAlpineOnTheNewPage(Alpine23) {
|
||||
Alpine23.initTree(document.body, void 0, (el, skip) => {
|
||||
if (el._x_wasPersisted)
|
||||
skip();
|
||||
});
|
||||
@@ -9420,8 +9467,8 @@ function cleanupAlpineElementsOnThePageThatArentInsideAPersistedElement() {
|
||||
}
|
||||
|
||||
// js/plugins/history/index.js
|
||||
function history2(Alpine20) {
|
||||
Alpine20.magic("queryString", (el, { interceptor }) => {
|
||||
function history2(Alpine23) {
|
||||
Alpine23.magic("queryString", (el, { interceptor }) => {
|
||||
let alias;
|
||||
let alwaysShow = false;
|
||||
let usePush = false;
|
||||
@@ -9430,9 +9477,9 @@ function history2(Alpine20) {
|
||||
let { initial, replace: replace2, push: push2, pop } = track(queryKey, initialSeedValue, alwaysShow);
|
||||
setter(initial);
|
||||
if (!usePush) {
|
||||
Alpine20.effect(() => replace2(getter()));
|
||||
Alpine23.effect(() => replace2(getter()));
|
||||
} else {
|
||||
Alpine20.effect(() => push2(getter()));
|
||||
Alpine23.effect(() => push2(getter()));
|
||||
pop(async (newValue) => {
|
||||
setter(newValue);
|
||||
let tillTheEndOfTheMicrotaskQueue = () => Promise.resolve();
|
||||
@@ -9455,7 +9502,7 @@ function history2(Alpine20) {
|
||||
};
|
||||
});
|
||||
});
|
||||
Alpine20.history = { track };
|
||||
Alpine23.history = { track };
|
||||
}
|
||||
function track(name, initialSeedValue, alwaysShow = false, except = null) {
|
||||
let { has, get, set, remove } = queryStringUtils();
|
||||
@@ -9519,14 +9566,22 @@ function replace(url, key, object) {
|
||||
if (!state.alpine)
|
||||
state.alpine = {};
|
||||
state.alpine[key] = unwrap(object);
|
||||
window.history.replaceState(state, "", url.toString());
|
||||
try {
|
||||
window.history.replaceState(state, "", url.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function push(url, key, object) {
|
||||
let state = window.history.state || {};
|
||||
if (!state.alpine)
|
||||
state.alpine = {};
|
||||
state = { alpine: { ...state.alpine, ...{ [key]: unwrap(object) } } };
|
||||
window.history.pushState(state, "", url.toString());
|
||||
try {
|
||||
window.history.pushState(state, "", url.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function unwrap(object) {
|
||||
if (object === void 0)
|
||||
@@ -9697,7 +9752,7 @@ function ensureLivewireScriptIsntMisplaced() {
|
||||
}
|
||||
|
||||
// js/index.js
|
||||
var import_alpinejs18 = __toESM(require_module_cjs());
|
||||
var import_alpinejs21 = __toESM(require_module_cjs());
|
||||
|
||||
// js/features/supportListeners.js
|
||||
on("effect", ({ component, effects }) => {
|
||||
@@ -9754,7 +9809,7 @@ on("effect", ({ component, effects }) => {
|
||||
onlyIfScriptHasntBeenRunAlreadyForThisComponent(component, key, () => {
|
||||
let scriptContent = extractScriptTagContent(content);
|
||||
import_alpinejs6.default.dontAutoEvaluateFunctions(() => {
|
||||
import_alpinejs6.default.evaluate(component.el, scriptContent, { "$wire": component.$wire });
|
||||
import_alpinejs6.default.evaluate(component.el, scriptContent, { "$wire": component.$wire, "$js": component.$wire.$js });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -9827,6 +9882,10 @@ function cloneScriptTag2(el) {
|
||||
|
||||
// js/features/supportJsEvaluation.js
|
||||
var import_alpinejs7 = __toESM(require_module_cjs());
|
||||
import_alpinejs7.default.magic("js", (el) => {
|
||||
let component = closestComponent(el);
|
||||
return component.$wire.js;
|
||||
});
|
||||
on("effect", ({ component, effects }) => {
|
||||
let js = effects.js;
|
||||
let xjs = effects.xjs;
|
||||
@@ -9838,8 +9897,9 @@ on("effect", ({ component, effects }) => {
|
||||
});
|
||||
}
|
||||
if (xjs) {
|
||||
xjs.forEach((expression) => {
|
||||
import_alpinejs7.default.evaluate(component.el, expression);
|
||||
xjs.forEach(({ expression, params }) => {
|
||||
params = Object.values(params);
|
||||
import_alpinejs7.default.evaluate(component.el, expression, { scope: component.jsActions, params });
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -9860,10 +9920,10 @@ function morph2(component, el, html) {
|
||||
to.__livewire = component;
|
||||
trigger("morph", { el, toEl: to, component });
|
||||
import_alpinejs8.default.morph(el, to, {
|
||||
updating: (el2, toEl, childrenOnly, skip) => {
|
||||
updating: (el2, toEl, childrenOnly, skip, skipChildren) => {
|
||||
if (isntElement(el2))
|
||||
return;
|
||||
trigger("morph.updating", { el: el2, toEl, component, skip, childrenOnly });
|
||||
trigger("morph.updating", { el: el2, toEl, component, skip, childrenOnly, skipChildren });
|
||||
if (el2.__livewire_replace === true)
|
||||
el2.innerHTML = toEl.innerHTML;
|
||||
if (el2.__livewire_replace_self === true) {
|
||||
@@ -9874,6 +9934,8 @@ function morph2(component, el, html) {
|
||||
return skip();
|
||||
if (el2.__livewire_ignore_self === true)
|
||||
childrenOnly();
|
||||
if (el2.__livewire_ignore_children === true)
|
||||
return skipChildren();
|
||||
if (isComponentRootEl(el2) && el2.getAttribute("wire:id") !== component.id)
|
||||
return skip();
|
||||
if (isComponentRootEl(el2))
|
||||
@@ -10309,6 +10371,14 @@ on("morph.added", ({ el }) => {
|
||||
el.__addedByMorph = true;
|
||||
});
|
||||
directive("transition", ({ el, directive: directive2, component, cleanup }) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:show")) {
|
||||
import_alpinejs11.default.bind(el, {
|
||||
[directive2.rawName.replace("wire:transition", "x-transition")]: directive2.expression
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
let visibility = import_alpinejs11.default.reactive({ state: el.__addedByMorph ? false : true });
|
||||
import_alpinejs11.default.bind(el, {
|
||||
[directive2.rawName.replace("wire:", "x-")]: "",
|
||||
@@ -10446,8 +10516,10 @@ globalDirective("current", ({ el, directive: directive2, cleanup }) => {
|
||||
let refreshCurrent = (url) => {
|
||||
if (pathMatches(hrefUrl, url, options)) {
|
||||
el.classList.add(...classes);
|
||||
el.setAttribute("data-current", "");
|
||||
} else {
|
||||
el.classList.remove(...classes);
|
||||
el.removeAttribute("data-current");
|
||||
}
|
||||
};
|
||||
refreshCurrent(new URL(window.location.href));
|
||||
@@ -10735,15 +10807,25 @@ directive("replace", ({ el, directive: directive2 }) => {
|
||||
directive("ignore", ({ el, directive: directive2 }) => {
|
||||
if (directive2.modifiers.includes("self")) {
|
||||
el.__livewire_ignore_self = true;
|
||||
} else if (directive2.modifiers.includes("children")) {
|
||||
el.__livewire_ignore_children = true;
|
||||
} else {
|
||||
el.__livewire_ignore = true;
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-cloak.js
|
||||
var import_alpinejs15 = __toESM(require_module_cjs());
|
||||
import_alpinejs15.default.interceptInit((el) => {
|
||||
if (el.hasAttribute("wire:cloak")) {
|
||||
import_alpinejs15.default.mutateDom(() => el.removeAttribute("wire:cloak"));
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-dirty.js
|
||||
var refreshDirtyStatesByComponent = new WeakBag();
|
||||
on("commit", ({ component, succeed }) => {
|
||||
succeed(() => {
|
||||
on("commit", ({ component, respond }) => {
|
||||
respond(() => {
|
||||
setTimeout(() => {
|
||||
refreshDirtyStatesByComponent.each(component, (i) => i(false));
|
||||
});
|
||||
@@ -10751,7 +10833,6 @@ on("commit", ({ component, succeed }) => {
|
||||
});
|
||||
directive("dirty", ({ el, directive: directive2, component }) => {
|
||||
let targets = dirtyTargets(el);
|
||||
let dirty = Alpine.reactive({ state: false });
|
||||
let oldIsDirty = false;
|
||||
let initialDisplay = el.style.display;
|
||||
let refreshDirtyState = (isDirty) => {
|
||||
@@ -10790,7 +10871,7 @@ function dirtyTargets(el) {
|
||||
}
|
||||
|
||||
// js/directives/wire-model.js
|
||||
var import_alpinejs15 = __toESM(require_module_cjs());
|
||||
var import_alpinejs16 = __toESM(require_module_cjs());
|
||||
directive("model", ({ el, directive: directive2, component, cleanup }) => {
|
||||
let { expression, modifiers } = directive2;
|
||||
if (!expression) {
|
||||
@@ -10808,7 +10889,7 @@ directive("model", ({ el, directive: directive2, component, cleanup }) => {
|
||||
let isDebounced = modifiers.includes("debounce");
|
||||
let update = expression.startsWith("$parent") ? () => component.$wire.$parent.$commit() : () => component.$wire.$commit();
|
||||
let debouncedUpdate = isTextInput(el) && !isDebounced && isLive ? debounce(update, 150) : update;
|
||||
import_alpinejs15.default.bind(el, {
|
||||
import_alpinejs16.default.bind(el, {
|
||||
["@change"]() {
|
||||
isLazy && update();
|
||||
},
|
||||
@@ -10864,14 +10945,14 @@ function debounce(func, wait) {
|
||||
}
|
||||
|
||||
// js/directives/wire-init.js
|
||||
var import_alpinejs16 = __toESM(require_module_cjs());
|
||||
var import_alpinejs17 = __toESM(require_module_cjs());
|
||||
directive("init", ({ el, directive: directive2 }) => {
|
||||
let fullMethod = directive2.expression ?? "$refresh";
|
||||
import_alpinejs16.default.evaluate(el, `$wire.${fullMethod}`);
|
||||
import_alpinejs17.default.evaluate(el, `$wire.${fullMethod}`);
|
||||
});
|
||||
|
||||
// js/directives/wire-poll.js
|
||||
var import_alpinejs17 = __toESM(require_module_cjs());
|
||||
var import_alpinejs18 = __toESM(require_module_cjs());
|
||||
directive("poll", ({ el, directive: directive2 }) => {
|
||||
let interval = extractDurationFrom(directive2.modifiers, 2e3);
|
||||
let { start: start2, pauseWhile, throttleWhile, stopWhen } = poll(() => {
|
||||
@@ -10885,7 +10966,7 @@ directive("poll", ({ el, directive: directive2 }) => {
|
||||
stopWhen(() => theElementIsDisconnected(el));
|
||||
});
|
||||
function triggerComponentRequest(el, directive2) {
|
||||
import_alpinejs17.default.evaluate(el, directive2.expression ? "$wire." + directive2.expression : "$wire.$commit()");
|
||||
import_alpinejs18.default.evaluate(el, directive2.expression ? "$wire." + directive2.expression : "$wire.$commit()");
|
||||
}
|
||||
function poll(callback, interval = 2e3) {
|
||||
let pauseConditions = [];
|
||||
@@ -10973,6 +11054,40 @@ function extractDurationFrom(modifiers, defaultDuration) {
|
||||
return durationInMilliSeconds || defaultDuration;
|
||||
}
|
||||
|
||||
// js/directives/wire-show.js
|
||||
var import_alpinejs19 = __toESM(require_module_cjs());
|
||||
import_alpinejs19.default.interceptInit((el) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:show")) {
|
||||
let { name, value } = el.attributes[i];
|
||||
let modifierString = name.split("wire:show")[1];
|
||||
let expression = value.startsWith("!") ? "!$wire." + value.slice(1).trim() : "$wire." + value.trim();
|
||||
import_alpinejs19.default.bind(el, {
|
||||
["x-show" + modifierString]() {
|
||||
return import_alpinejs19.default.evaluate(el, expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-text.js
|
||||
var import_alpinejs20 = __toESM(require_module_cjs());
|
||||
import_alpinejs20.default.interceptInit((el) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:text")) {
|
||||
let { name, value } = el.attributes[i];
|
||||
let modifierString = name.split("wire:text")[1];
|
||||
let expression = value.startsWith("!") ? "!$wire." + value.slice(1).trim() : "$wire." + value.trim();
|
||||
import_alpinejs20.default.bind(el, {
|
||||
["x-text" + modifierString]() {
|
||||
return import_alpinejs20.default.evaluate(el, expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// js/index.js
|
||||
var Livewire2 = {
|
||||
directive,
|
||||
@@ -10988,7 +11103,7 @@ var Livewire2 = {
|
||||
dispatch: dispatchGlobal,
|
||||
on: on2,
|
||||
get navigate() {
|
||||
return import_alpinejs18.default.navigate;
|
||||
return import_alpinejs21.default.navigate;
|
||||
}
|
||||
};
|
||||
var warnAboutMultipleInstancesOf = (entity) => console.warn(`Detected multiple instances of ${entity} running`);
|
||||
@@ -10997,7 +11112,7 @@ if (window.Livewire)
|
||||
if (window.Alpine)
|
||||
warnAboutMultipleInstancesOf("Alpine");
|
||||
window.Livewire = Livewire2;
|
||||
window.Alpine = import_alpinejs18.default;
|
||||
window.Alpine = import_alpinejs21.default;
|
||||
if (window.livewireScriptConfig === void 0) {
|
||||
window.Alpine.__fromLivewire = true;
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
@@ -11007,7 +11122,7 @@ if (window.livewireScriptConfig === void 0) {
|
||||
Livewire2.start();
|
||||
});
|
||||
}
|
||||
var export_Alpine = import_alpinejs18.default;
|
||||
var export_Alpine = import_alpinejs21.default;
|
||||
export {
|
||||
export_Alpine as Alpine,
|
||||
Livewire2 as Livewire
|
||||
|
||||
6
public/vendor/livewire/livewire.esm.js.map
vendored
6
public/vendor/livewire/livewire.esm.js.map
vendored
File diff suppressed because one or more lines are too long
138
public/vendor/livewire/livewire.js
vendored
138
public/vendor/livewire/livewire.js
vendored
@@ -2295,7 +2295,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
get raw() {
|
||||
return raw;
|
||||
},
|
||||
version: "3.14.8",
|
||||
version: "3.14.9",
|
||||
flushAndStopDeferringMutations,
|
||||
dontAutoEvaluateFunctions,
|
||||
disableEffectScheduling,
|
||||
@@ -4363,6 +4363,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
"on": "$on",
|
||||
"el": "$el",
|
||||
"id": "$id",
|
||||
"js": "$js",
|
||||
"get": "$get",
|
||||
"set": "$set",
|
||||
"call": "$call",
|
||||
@@ -4434,6 +4435,14 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
wireProperty("$id", (component) => {
|
||||
return component.id;
|
||||
});
|
||||
wireProperty("$js", (component) => {
|
||||
let fn = component.addJsAction.bind(component);
|
||||
let jsActions = component.getJsActions();
|
||||
Object.keys(jsActions).forEach((name) => {
|
||||
fn[name] = component.getJsAction(name);
|
||||
});
|
||||
return fn;
|
||||
});
|
||||
wireProperty("$set", (component) => async (property, value, live = true) => {
|
||||
dataSet(component.reactive, property, value);
|
||||
if (live) {
|
||||
@@ -4529,6 +4538,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
this.ephemeral = extractData(deepClone(this.snapshot.data));
|
||||
this.reactive = Alpine.reactive(this.ephemeral);
|
||||
this.queuedUpdates = {};
|
||||
this.jsActions = {};
|
||||
this.$wire = generateWireObject(this, this.reactive);
|
||||
this.cleanups = [];
|
||||
this.processEffects(this.effects);
|
||||
@@ -4604,6 +4614,18 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
}
|
||||
el.setAttribute("wire:effects", JSON.stringify(effects));
|
||||
}
|
||||
addJsAction(name, action) {
|
||||
this.jsActions[name] = action;
|
||||
}
|
||||
hasJsAction(name) {
|
||||
return this.jsActions[name] !== void 0;
|
||||
}
|
||||
getJsAction(name) {
|
||||
return this.jsActions[name].bind(this.$wire);
|
||||
}
|
||||
getJsActions() {
|
||||
return this.jsActions;
|
||||
}
|
||||
addCleanup(cleanup2) {
|
||||
this.cleanups.push(cleanup2);
|
||||
}
|
||||
@@ -7715,6 +7737,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
];
|
||||
function swapCurrentPageWithNewHtml(html, andThen) {
|
||||
let newDocument = new DOMParser().parseFromString(html, "text/html");
|
||||
let newHtml = newDocument.documentElement;
|
||||
let newBody = document.adoptNode(newDocument.body);
|
||||
let newHead = document.adoptNode(newDocument.head);
|
||||
oldBodyScriptTagHashes = oldBodyScriptTagHashes.concat(Array.from(document.body.querySelectorAll("script")).map((i) => {
|
||||
@@ -7722,6 +7745,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
}));
|
||||
let afterRemoteScriptsHaveLoaded = () => {
|
||||
};
|
||||
replaceHtmlAttributes(newHtml);
|
||||
mergeNewHead(newHead).finally(() => {
|
||||
afterRemoteScriptsHaveLoaded();
|
||||
});
|
||||
@@ -7741,6 +7765,21 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
i.replaceWith(cloneScriptTag(i));
|
||||
});
|
||||
}
|
||||
function replaceHtmlAttributes(newHtmlElement) {
|
||||
let currentHtmlElement = document.documentElement;
|
||||
Array.from(newHtmlElement.attributes).forEach((attr) => {
|
||||
const name = attr.name;
|
||||
const value = attr.value;
|
||||
if (currentHtmlElement.getAttribute(name) !== value) {
|
||||
currentHtmlElement.setAttribute(name, value);
|
||||
}
|
||||
});
|
||||
Array.from(currentHtmlElement.attributes).forEach((attr) => {
|
||||
if (!newHtmlElement.hasAttribute(attr.name)) {
|
||||
currentHtmlElement.removeAttribute(attr.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
function mergeNewHead(newHead) {
|
||||
let children = Array.from(document.head.children);
|
||||
let headChildrenHtmlLookup = children.map((i) => i.outerHTML);
|
||||
@@ -8123,14 +8162,22 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
if (!state.alpine)
|
||||
state.alpine = {};
|
||||
state.alpine[key] = unwrap(object);
|
||||
window.history.replaceState(state, "", url.toString());
|
||||
try {
|
||||
window.history.replaceState(state, "", url.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function push(url, key, object) {
|
||||
let state = window.history.state || {};
|
||||
if (!state.alpine)
|
||||
state.alpine = {};
|
||||
state = { alpine: { ...state.alpine, ...{ [key]: unwrap(object) } } };
|
||||
window.history.pushState(state, "", url.toString());
|
||||
try {
|
||||
window.history.pushState(state, "", url.toString());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function unwrap(object) {
|
||||
if (object === void 0)
|
||||
@@ -8251,7 +8298,8 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
return swapElements(from2, to);
|
||||
}
|
||||
let updateChildrenOnly = false;
|
||||
if (shouldSkip(updating, from2, to, () => updateChildrenOnly = true))
|
||||
let skipChildren = false;
|
||||
if (shouldSkipChildren(updating, () => skipChildren = true, from2, to, () => updateChildrenOnly = true))
|
||||
return;
|
||||
if (from2.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from2, to);
|
||||
@@ -8268,7 +8316,9 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
patchAttributes(from2, to);
|
||||
}
|
||||
updated(from2, to);
|
||||
patchChildren(from2, to);
|
||||
if (!skipChildren) {
|
||||
patchChildren(from2, to);
|
||||
}
|
||||
}
|
||||
function differentElementNamesTypesOrKeys(from2, to) {
|
||||
return from2.nodeType != to.nodeType || from2.nodeName != to.nodeName || getKey(from2) != getKey(to);
|
||||
@@ -8482,6 +8532,11 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
hook(...args, () => skip = true);
|
||||
return skip;
|
||||
}
|
||||
function shouldSkipChildren(hook, skipChildren, ...args) {
|
||||
let skip = false;
|
||||
hook(...args, () => skip = true, skipChildren);
|
||||
return skip;
|
||||
}
|
||||
var patched = false;
|
||||
function createElement(html) {
|
||||
const template = document.createElement("template");
|
||||
@@ -8861,7 +8916,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
onlyIfScriptHasntBeenRunAlreadyForThisComponent(component, key, () => {
|
||||
let scriptContent = extractScriptTagContent(content);
|
||||
module_default.dontAutoEvaluateFunctions(() => {
|
||||
module_default.evaluate(component.el, scriptContent, { "$wire": component.$wire });
|
||||
module_default.evaluate(component.el, scriptContent, { "$wire": component.$wire, "$js": component.$wire.$js });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8933,6 +8988,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
}
|
||||
|
||||
// js/features/supportJsEvaluation.js
|
||||
module_default.magic("js", (el) => {
|
||||
let component = closestComponent(el);
|
||||
return component.$wire.js;
|
||||
});
|
||||
on2("effect", ({ component, effects }) => {
|
||||
let js = effects.js;
|
||||
let xjs = effects.xjs;
|
||||
@@ -8944,8 +9003,9 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
});
|
||||
}
|
||||
if (xjs) {
|
||||
xjs.forEach((expression) => {
|
||||
module_default.evaluate(component.el, expression);
|
||||
xjs.forEach(({ expression, params }) => {
|
||||
params = Object.values(params);
|
||||
module_default.evaluate(component.el, expression, { scope: component.jsActions, params });
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -8965,10 +9025,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
to.__livewire = component;
|
||||
trigger2("morph", { el, toEl: to, component });
|
||||
module_default.morph(el, to, {
|
||||
updating: (el2, toEl, childrenOnly, skip) => {
|
||||
updating: (el2, toEl, childrenOnly, skip, skipChildren) => {
|
||||
if (isntElement(el2))
|
||||
return;
|
||||
trigger2("morph.updating", { el: el2, toEl, component, skip, childrenOnly });
|
||||
trigger2("morph.updating", { el: el2, toEl, component, skip, childrenOnly, skipChildren });
|
||||
if (el2.__livewire_replace === true)
|
||||
el2.innerHTML = toEl.innerHTML;
|
||||
if (el2.__livewire_replace_self === true) {
|
||||
@@ -8979,6 +9039,8 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
return skip();
|
||||
if (el2.__livewire_ignore_self === true)
|
||||
childrenOnly();
|
||||
if (el2.__livewire_ignore_children === true)
|
||||
return skipChildren();
|
||||
if (isComponentRootEl(el2) && el2.getAttribute("wire:id") !== component.id)
|
||||
return skip();
|
||||
if (isComponentRootEl(el2))
|
||||
@@ -9411,6 +9473,14 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
el.__addedByMorph = true;
|
||||
});
|
||||
directive2("transition", ({ el, directive: directive3, component, cleanup: cleanup2 }) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:show")) {
|
||||
module_default.bind(el, {
|
||||
[directive3.rawName.replace("wire:transition", "x-transition")]: directive3.expression
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
let visibility = module_default.reactive({ state: el.__addedByMorph ? false : true });
|
||||
module_default.bind(el, {
|
||||
[directive3.rawName.replace("wire:", "x-")]: "",
|
||||
@@ -9545,8 +9615,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
let refreshCurrent = (url) => {
|
||||
if (pathMatches(hrefUrl, url, options)) {
|
||||
el.classList.add(...classes);
|
||||
el.setAttribute("data-current", "");
|
||||
} else {
|
||||
el.classList.remove(...classes);
|
||||
el.removeAttribute("data-current");
|
||||
}
|
||||
};
|
||||
refreshCurrent(new URL(window.location.href));
|
||||
@@ -9834,15 +9906,24 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
directive2("ignore", ({ el, directive: directive3 }) => {
|
||||
if (directive3.modifiers.includes("self")) {
|
||||
el.__livewire_ignore_self = true;
|
||||
} else if (directive3.modifiers.includes("children")) {
|
||||
el.__livewire_ignore_children = true;
|
||||
} else {
|
||||
el.__livewire_ignore = true;
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-cloak.js
|
||||
module_default.interceptInit((el) => {
|
||||
if (el.hasAttribute("wire:cloak")) {
|
||||
module_default.mutateDom(() => el.removeAttribute("wire:cloak"));
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-dirty.js
|
||||
var refreshDirtyStatesByComponent = new WeakBag();
|
||||
on2("commit", ({ component, succeed }) => {
|
||||
succeed(() => {
|
||||
on2("commit", ({ component, respond }) => {
|
||||
respond(() => {
|
||||
setTimeout(() => {
|
||||
refreshDirtyStatesByComponent.each(component, (i) => i(false));
|
||||
});
|
||||
@@ -9850,7 +9931,6 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
});
|
||||
directive2("dirty", ({ el, directive: directive3, component }) => {
|
||||
let targets = dirtyTargets(el);
|
||||
let dirty = Alpine.reactive({ state: false });
|
||||
let oldIsDirty = false;
|
||||
let initialDisplay = el.style.display;
|
||||
let refreshDirtyState = (isDirty) => {
|
||||
@@ -10069,6 +10149,38 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el);
|
||||
return durationInMilliSeconds || defaultDuration;
|
||||
}
|
||||
|
||||
// js/directives/wire-show.js
|
||||
module_default.interceptInit((el) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:show")) {
|
||||
let { name, value } = el.attributes[i];
|
||||
let modifierString = name.split("wire:show")[1];
|
||||
let expression = value.startsWith("!") ? "!$wire." + value.slice(1).trim() : "$wire." + value.trim();
|
||||
module_default.bind(el, {
|
||||
["x-show" + modifierString]() {
|
||||
return module_default.evaluate(el, expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// js/directives/wire-text.js
|
||||
module_default.interceptInit((el) => {
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
if (el.attributes[i].name.startsWith("wire:text")) {
|
||||
let { name, value } = el.attributes[i];
|
||||
let modifierString = name.split("wire:text")[1];
|
||||
let expression = value.startsWith("!") ? "!$wire." + value.slice(1).trim() : "$wire." + value.trim();
|
||||
module_default.bind(el, {
|
||||
["x-text" + modifierString]() {
|
||||
return module_default.evaluate(el, expression);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// js/index.js
|
||||
var Livewire2 = {
|
||||
directive: directive2,
|
||||
|
||||
12
public/vendor/livewire/livewire.min.js
vendored
12
public/vendor/livewire/livewire.min.js
vendored
File diff suppressed because one or more lines are too long
6
public/vendor/livewire/livewire.min.js.map
vendored
6
public/vendor/livewire/livewire.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@@ -1,2 +1,2 @@
|
||||
|
||||
{"/livewire.js":"951e6947"}
|
||||
{"/livewire.js":"df3a17f2"}
|
||||
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'manage' => 'crwdns6501:0crwdne6501:0',
|
||||
'field' => 'crwdns1487:0crwdne1487:0',
|
||||
'about_fieldsets_title' => 'crwdns1488:0crwdne1488:0',
|
||||
'about_fieldsets_text' => 'crwdns13242:0crwdne13242:0',
|
||||
'about_fieldsets_text' => 'crwdns13226:0crwdne13226:0',
|
||||
'custom_format' => 'crwdns6505:0crwdne6505:0',
|
||||
'encrypt_field' => 'crwdns1792:0crwdne1792:0',
|
||||
'encrypt_field_help' => 'crwdns1683:0crwdne1683:0',
|
||||
|
||||
@@ -49,11 +49,12 @@ return [
|
||||
'error_redirect' => 'crwdns11843:0crwdne11843:0',
|
||||
'error_misc' => 'crwdns11383:0crwdne11383:0',
|
||||
'webhook_fail' => 'crwdns12830:0crwdne12830:0',
|
||||
'webhook_channel_not_found' => 'crwdns12876:0crwdne12876:0',
|
||||
'ms_teams_deprecation' => 'crwdns13246:0crwdne13246:0',
|
||||
'webhook_channel_not_found' => 'crwdns12876:0crwdne12876:0'
|
||||
],
|
||||
|
||||
'location_scoping' => [
|
||||
'not_saved' => 'crwdns13053:0crwdne13053:0',
|
||||
'mismatch' => 'crwdns13055:0crwdne13055:0',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -521,7 +521,7 @@ return [
|
||||
'checked_out_to_fields' => 'crwdns12214:0crwdne12214:0',
|
||||
'percent_complete' => 'crwdns11811:0crwdne11811:0',
|
||||
'uploading' => 'crwdns11813:0crwdne11813:0',
|
||||
'upload_error' => 'crwdns13244:0crwdne13244:0',
|
||||
'upload_error' => 'crwdns11884:0crwdne11884:0',
|
||||
'copy_to_clipboard' => 'crwdns11837:0crwdne11837:0',
|
||||
'copied' => 'crwdns11839:0crwdne11839:0',
|
||||
'status_compatibility' => 'crwdns11910:0crwdne11910:0',
|
||||
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'manage' => 'Manage',
|
||||
'field' => 'veld',
|
||||
'about_fieldsets_title' => 'Oor Fieldsets',
|
||||
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used for specific asset model types.',
|
||||
'about_fieldsets_text' => 'Veldstelle stel jou in staat om groepe van persoonlike velde te skep wat gereeld hergebruik word vir spesifieke tipe bates.',
|
||||
'custom_format' => 'Custom Regex format...',
|
||||
'encrypt_field' => 'Enkripteer die waarde van hierdie veld in die databasis',
|
||||
'encrypt_field_help' => 'WAARSKUWING: Om \'n veld te enkripteer, maak dit onondersoekbaar.',
|
||||
|
||||
@@ -49,11 +49,12 @@ return [
|
||||
'error_redirect' => 'ERROR: 301/302 :endpoint returns a redirect. For security reasons, we don’t follow redirects. Please use the actual endpoint.',
|
||||
'error_misc' => 'Something went wrong. :( ',
|
||||
'webhook_fail' => ' webhook notification failed: Check to make sure the URL is still valid.',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.',
|
||||
'ms_teams_deprecation' => 'The selected Microsoft Teams webhook URL will be deprecated Dec 31st, 2025. Please use a workflow URL. Microsoft\'s documentation on creating a workflow can be found <a href="https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498" target="_blank"> here.</a>',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.'
|
||||
],
|
||||
|
||||
'location_scoping' => [
|
||||
'not_saved' => 'Your settings were not saved.',
|
||||
'mismatch' => 'There is 1 item in the database that need your attention before you can enable location scoping.|There are :count items in the database that need your attention before you can enable location scoping.',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'about' => 'About Status Types',
|
||||
'about' => 'Oor Status Etikette',
|
||||
'archived' => 'argief',
|
||||
'create' => 'Skep statusetiket',
|
||||
'color' => 'Grafiek Kleur',
|
||||
'default_label' => 'Default Label',
|
||||
'default_label_help' => 'This is used to ensure your most commonly used status labels appear at the top of the select box when creating/editing assets.',
|
||||
'deployable' => 'verbintenis',
|
||||
'info' => 'Status label types are used to describe the various states your assets could be in. They may be out for repair, lost/stolen, etc. You can create new status labels for your deployable, pending and archived assets according to your own workflow. For more information, <a href="https://snipe-it.readme.io/docs/overview#status-labels" target="_blank">see the documentation <i class="fa fa-external-link"></i></a>.',
|
||||
'info' => 'Statusetikette word gebruik om die verskillende state waarin u bates kan wees, te beskryf. Hulle kan dalk herstel, verlore / gesteel wees, ens. U kan nuwe statusetikette skep vir ontplooibare, hangende en geargiveerde bates.',
|
||||
'name' => 'Status Naam',
|
||||
'pending' => 'hangende',
|
||||
'status_type' => 'Status Tipe',
|
||||
|
||||
@@ -522,7 +522,7 @@ return [
|
||||
'checked_out_to_fields' => 'Checked Out To Fields',
|
||||
'percent_complete' => '% volledige',
|
||||
'uploading' => 'Uploading... ',
|
||||
'upload_error' => 'Error uploading file. Please check that you have no empty rows or duplicated column names in your CSV, and that the server permissions allow uploads.',
|
||||
'upload_error' => 'Error uploading file. Please check that there are no empty rows and that no column names are duplicated.',
|
||||
'copy_to_clipboard' => 'Copy to Clipboard',
|
||||
'copied' => 'Copied!',
|
||||
'status_compatibility' => 'If assets are already assigned, they cannot be changed to a non-deployable status type and this value change will be skipped.',
|
||||
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'manage' => 'Manage',
|
||||
'field' => 'Field',
|
||||
'about_fieldsets_title' => 'About Fieldsets',
|
||||
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used for specific asset model types.',
|
||||
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used used for specific asset model types.',
|
||||
'custom_format' => 'Custom Regex format...',
|
||||
'encrypt_field' => 'Encrypt the value of this field in the database',
|
||||
'encrypt_field_help' => 'WARNING: Encrypting a field makes it unsearchable.',
|
||||
|
||||
@@ -49,11 +49,12 @@ return [
|
||||
'error_redirect' => 'ERROR: 301/302 :endpoint returns a redirect. For security reasons, we don’t follow redirects. Please use the actual endpoint.',
|
||||
'error_misc' => 'Something went wrong. :( ',
|
||||
'webhook_fail' => ' webhook notification failed: Check to make sure the URL is still valid.',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.',
|
||||
'ms_teams_deprecation' => 'The selected Microsoft Teams webhook URL will be deprecated Dec 31st, 2025. Please use a workflow URL. Microsoft\'s documentation on creating a workflow can be found <a href="https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498" target="_blank"> here.</a>',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.'
|
||||
],
|
||||
|
||||
'location_scoping' => [
|
||||
'not_saved' => 'Your settings were not saved.',
|
||||
'mismatch' => 'There is 1 item in the database that need your attention before you can enable location scoping.|There are :count items in the database that need your attention before you can enable location scoping.',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'about' => 'About Status Types',
|
||||
'about' => 'About Status Labels',
|
||||
'archived' => 'የተመኸደረ',
|
||||
'create' => 'Create Status Label',
|
||||
'color' => 'Chart Color',
|
||||
'default_label' => 'Default Label',
|
||||
'default_label_help' => 'This is used to ensure your most commonly used status labels appear at the top of the select box when creating/editing assets.',
|
||||
'deployable' => 'Deployable',
|
||||
'info' => 'Status label types are used to describe the various states your assets could be in. They may be out for repair, lost/stolen, etc. You can create new status labels for your deployable, pending and archived assets according to your own workflow. For more information, <a href="https://snipe-it.readme.io/docs/overview#status-labels" target="_blank">see the documentation <i class="fa fa-external-link"></i></a>.',
|
||||
'info' => 'Status labels are used to describe the various states your assets could be in. They may be out for repair, lost/stolen, etc. You can create new status labels for deployable, pending and archived assets.',
|
||||
'name' => 'Status Name',
|
||||
'pending' => 'Pending',
|
||||
'status_type' => 'Status Type',
|
||||
|
||||
@@ -522,7 +522,7 @@ return [
|
||||
'checked_out_to_fields' => 'Checked Out To Fields',
|
||||
'percent_complete' => '% complete',
|
||||
'uploading' => 'Uploading... ',
|
||||
'upload_error' => 'Error uploading file. Please check that you have no empty rows or duplicated column names in your CSV, and that the server permissions allow uploads.',
|
||||
'upload_error' => 'Error uploading file. Please check that there are no empty rows and that no column names are duplicated.',
|
||||
'copy_to_clipboard' => 'Copy to Clipboard',
|
||||
'copied' => 'Copied!',
|
||||
'status_compatibility' => 'If assets are already assigned, they cannot be changed to a non-deployable status type and this value change will be skipped.',
|
||||
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'manage' => 'إدارة',
|
||||
'field' => 'حقل',
|
||||
'about_fieldsets_title' => 'حول مجموعة الحقول',
|
||||
'about_fieldsets_text' => 'مجموعات الحقول تسمح لك بإنشاء مجموعات من الحقول المخصصة التي يعاد استخدامها في كثير من الأحيان لأنواع معينة من نماذج الأصول.',
|
||||
'about_fieldsets_text' => '(مجموعات الحقول) تسمح لك بإنشاء مجموعات من الحقول اللتي يمكن إعادة إستخدامها مع موديل محدد.',
|
||||
'custom_format' => 'تنسيق Regex المخصص...',
|
||||
'encrypt_field' => 'تشفير قيمة هذا الحقل في قاعدة البيانات',
|
||||
'encrypt_field_help' => 'تحذير: تشفير الحقل يجعله غير قابل للبحث.',
|
||||
|
||||
@@ -49,11 +49,12 @@ return [
|
||||
'error_redirect' => 'خطأ: 301/302 :endpoint يرجع إعادة توجيه. لأسباب أمنية، نحن لا نتابع إعادة التوجيه. الرجاء استخدام نقطة النهاية الفعلية.',
|
||||
'error_misc' => 'حدث خطأ ما. :( ',
|
||||
'webhook_fail' => ' webhook notification failed: Check to make sure the URL is still valid.',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.',
|
||||
'ms_teams_deprecation' => 'The selected Microsoft Teams webhook URL will be deprecated Dec 31st, 2025. Please use a workflow URL. Microsoft\'s documentation on creating a workflow can be found <a href="https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498" target="_blank"> here.</a>',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.'
|
||||
],
|
||||
|
||||
'location_scoping' => [
|
||||
'not_saved' => 'Your settings were not saved.',
|
||||
'mismatch' => 'There is 1 item in the database that need your attention before you can enable location scoping.|There are :count items in the database that need your attention before you can enable location scoping.',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'about' => 'About Status Types',
|
||||
'about' => 'حول تسميات الحالة',
|
||||
'archived' => 'مؤرشف',
|
||||
'create' => 'إنشاء تسمية الحالة',
|
||||
'color' => 'لون الرسم البياني',
|
||||
'default_label' => 'الوسم الافتراضي',
|
||||
'default_label_help' => 'يستخدم هذا للتأكد من أن تسميات الحالة الأكثر استخداما تظهر في الجزء العلوي من المربع المحدد عند إنشاء/تحرير الأصول.',
|
||||
'deployable' => 'قابل للتوزيع',
|
||||
'info' => 'Status label types are used to describe the various states your assets could be in. They may be out for repair, lost/stolen, etc. You can create new status labels for your deployable, pending and archived assets according to your own workflow. For more information, <a href="https://snipe-it.readme.io/docs/overview#status-labels" target="_blank">see the documentation <i class="fa fa-external-link"></i></a>.',
|
||||
'info' => 'يتم استخدام تسميات الحالة لوصف الحالات المحتملة للأصول التابعة لك. قد تكون قيد الصيانة أو ضمن المفقودة أو المسروقة، وما إلى ذلك. يمكنك إنشاء تسميات حالة جديدة للأصول القابلة للتوزيع وقيد الانتظار والمؤرشفة.',
|
||||
'name' => 'اسم الحالة',
|
||||
'pending' => 'قيد الانتظار',
|
||||
'status_type' => 'نوع الحالة',
|
||||
|
||||
@@ -522,7 +522,7 @@ return [
|
||||
'checked_out_to_fields' => 'Checked Out To Fields',
|
||||
'percent_complete' => '% اكتمال',
|
||||
'uploading' => 'تحميل... ',
|
||||
'upload_error' => 'Error uploading file. Please check that you have no empty rows or duplicated column names in your CSV, and that the server permissions allow uploads.',
|
||||
'upload_error' => 'خطأ في تحميل الملف. الرجاء التحقق من أنه لا توجد صفوف فارغة وأنه لا يوجد تكرار لأسماء الأعمدة.',
|
||||
'copy_to_clipboard' => 'نسخ إلى الحافظة',
|
||||
'copied' => 'نسخ!',
|
||||
'status_compatibility' => 'إذا تم تعيين الأصول بالفعل، فإنه لا يمكن تغييرها إلى نوع حالة غير قابل للنشر وسيتم تخطي هذا التغيير في القيمة.',
|
||||
|
||||
@@ -18,7 +18,7 @@ return array(
|
||||
'confirm' => 'Сигурни ли сте, че желаете да изтриете този компонент?',
|
||||
'error' => 'Възникна проблем при изтриването на компонента. Моля опитайте отново.',
|
||||
'success' => 'Компонентът бе изтрит успешно.',
|
||||
'error_qty' => 'Някой компоненти от този тип са все още изписани. Моля проверете ги и пробвайте отново.',
|
||||
'error_qty' => 'Some components of this type are still checked out. Please check them in and try again.',
|
||||
),
|
||||
|
||||
'checkout' => array(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
return array(
|
||||
|
||||
'invalid_category_type' => 'Категоряита трябва да бъде от консумативи.',
|
||||
'invalid_category_type' => 'The category must be a consumable category.',
|
||||
'does_not_exist' => 'Консуматива не съществува.',
|
||||
|
||||
'create' => array(
|
||||
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'manage' => 'Управление',
|
||||
'field' => 'Поле',
|
||||
'about_fieldsets_title' => 'Относно Fieldsets',
|
||||
'about_fieldsets_text' => '"Група от полета" позволяват създаването на групи от персонализирани полета, които се използват и преизползват често за специфични типове модели на активи.',
|
||||
'about_fieldsets_text' => 'Fieldsets позволяват създаването на групи от персонализирани полета, които се използват и преизползват често за специфични типове модели на активи.',
|
||||
'custom_format' => 'Персонализиран формат...',
|
||||
'encrypt_field' => 'Шифроване на стойността на това поле в базата данни',
|
||||
'encrypt_field_help' => 'ВНИМАНИЕ: Шифроване на поле го прави невалидно за търсене.',
|
||||
@@ -57,8 +57,8 @@ return [
|
||||
'show_in_requestable_list_short' => 'Покажи в списъка на изискуемите артикули',
|
||||
'show_in_requestable_list' => 'Покажи стойноста в списъка на изискуемите артикули. Криптираните полета няма да се покажат',
|
||||
'encrypted_options' => 'Това поле е криптирано, затова някой настройки няма да бъдат налични.',
|
||||
'display_checkin' => 'Покажи в форма за вписване',
|
||||
'display_checkout' => 'Покажи в форма за изписване',
|
||||
'display_audit' => 'Покажи в форма за одит',
|
||||
'display_checkin' => 'Display in checkin forms',
|
||||
'display_checkout' => 'Display in checkout forms',
|
||||
'display_audit' => 'Display in audit forms',
|
||||
|
||||
];
|
||||
|
||||
@@ -5,7 +5,7 @@ return array(
|
||||
'field' => array(
|
||||
'invalid' => 'Това поле не съществува.',
|
||||
'already_added' => 'Вече е добавено поле',
|
||||
'none_selected' => 'Не е избрано поле',
|
||||
'none_selected' => 'No field selected',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Поле не беше създадено, моля опитайте отново.',
|
||||
|
||||
@@ -14,7 +14,7 @@ return [
|
||||
Нямате нагласена амортизация.
|
||||
Моля настройте поне една амортизация за да видите справката.',
|
||||
'depreciation_method' => 'Справка за амортизации',
|
||||
'linear_depreciation' => 'Линеен (по подразбиране)',
|
||||
'half_1' => 'Полугодишна, винаги се приложена',
|
||||
'half_2' => 'Полугодишна, приложена с условие',
|
||||
'linear_depreciation' => 'Linear (Default)',
|
||||
'half_1' => 'Half-year convention, always applied',
|
||||
'half_2' => 'Half-year convention, applied with condition',
|
||||
];
|
||||
|
||||
@@ -55,11 +55,11 @@ return [
|
||||
'asset_location_update_default' => 'Актуализиране на местоположението по подразбиране',
|
||||
'asset_location_update_actual' => 'Актуализиране само на местоположението',
|
||||
'asset_not_deployable' => 'Актива не може да бъде предоставен. Този активк не може да бъде изписан.',
|
||||
'asset_not_deployable_checkin' => 'Статуса на този актив е със забрана за изписване. Използвайки този статус ще впише актива обратно.',
|
||||
'asset_deployable' => 'Този актив може да бъде изписан.',
|
||||
'asset_not_deployable_checkin' => 'That asset status is not deployable. Using this status label will checkin the asset.',
|
||||
'asset_deployable' => 'This asset can be checked out.',
|
||||
'processing_spinner' => 'Обработка...(Това може да отнеме време при големи файлове)',
|
||||
'processing' => 'В процес на изпълнение... ',
|
||||
'optional_infos' => 'Допълнителна информация',
|
||||
'order_details' => 'Информация за състоянието на поръчка',
|
||||
'calc_eol' => 'Ако нулирате EOL датата, ще се използва EOL дата базирана на дата на закупуване + EOL норма.',
|
||||
'calc_eol' => 'If nulling the EOL date, use automatic EOL calculation based on the purchase date and EOL rate.',
|
||||
];
|
||||
|
||||
@@ -6,7 +6,7 @@ return [
|
||||
'archived' => 'Архивиран',
|
||||
'asset' => 'Актив',
|
||||
'bulk_checkout' => 'Общо отписване',
|
||||
'bulk_checkin' => 'Общо вписване',
|
||||
'bulk_checkin' => 'Bulk Checkin',
|
||||
'checkin' => 'Връщане на актив',
|
||||
'checkout' => 'Изписване на актив',
|
||||
'clone' => 'Копиране на актив',
|
||||
@@ -27,7 +27,7 @@ return [
|
||||
'undeployable_tooltip' => 'Този актив е забранен за изписване и не може да се изпише в момента.',
|
||||
'view' => 'Преглед на актив',
|
||||
'csv_error' => 'Имате грешка във вашият CSV файл:',
|
||||
'import_text' => '<p>Качи CSV файл, който съдържа историята на активите. Активите и потребителите ТРЯБВА да ги има създадени в системата в противен слуай няма да се импортират. При импортиране на историята на активите, съвпадението се прави по техния инвентарен номер. Ще се опитаме да намерим потребителя на база неговото потребителско име и критерия който сте избрали по-долу. Ще се опита да намери съвпадение по формата на потребителско име избран в <code>Admin > General Settings</code>.</p><p>Полетата включени в CSV файла, трябва да съвпадат с <strong>Инвентарен номер, Име, Дата на изписване, Дата на вписване</strong>. Всякакви допълнителни полета ще бъдат игнорирани. </p><p> Празна дата на вписване или дата в бъдещето ще изпише актива към асоцийрания потребител. Ако не се включи колона с дата на вписване, същата ще бъде създадена със текущата дата.</p> ',
|
||||
'import_text' => '<p>Upload a CSV that contains asset history. The assets and users MUST already exist in the system, or they will be skipped. Matching assets for history import happens against the asset tag. We will try to find a matching user based on the user\'s name you provide, and the criteria you select below. If you do not select any criteria below, it will simply try to match on the username format you configured in the <code>Admin > General Settings</code>.</p><p>Fields included in the CSV must match the headers: <strong>Asset Tag, Name, Checkout Date, Checkin Date</strong>. Any additional fields will be ignored. </p><p>Checkin Date: blank or future checkin dates will checkout items to associated user. Excluding the Checkin Date column will create a checkin date with todays date.</p> ',
|
||||
'csv_import_match_f-l' => 'Опитай да намериш съвпадение на потребителите по <strong>Име.Фамилия</strong> (<code>Иван.Иванов</code>)',
|
||||
'csv_import_match_initial_last' => 'Опитай да намериш съвпадение на потребителите по <strong>Първа буква, Фамилия</strong> (<code>ииванов</code>)',
|
||||
'csv_import_match_first' => 'Опитай да намериш съвпадение на потребителите по <strong>Име</strong> (<code>Иван</code>)',
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
|
||||
return [
|
||||
|
||||
'undeployable' => '<strong>Внимание:</strong> Този актив е маркиран, като забранен за изписване. Ако статусът е променен, моля обновете актива.',
|
||||
'undeployable' => '<strong>Warning: </strong> This asset has been marked as currently undeployable. If this status has changed, please update the asset status.',
|
||||
'does_not_exist' => 'Активът не съществува.',
|
||||
'does_not_exist_var' => 'Активът с етике :asset_tag не е намерен.',
|
||||
'no_tag' => 'Не е предоставен етикет на актив.',
|
||||
'does_not_exist_or_not_requestable' => 'Актива не съществува или не може да бъде предоставян.',
|
||||
'assoc_users' => 'Активът е изписан на потребител и не може да бъде изтрит. Моля впишете го обратно и след това опитайте да го изтриете отново.',
|
||||
'warning_audit_date_mismatch' => 'Следващата дата на одит на този актив (:next_audit_date) е преди последната дата на одит (:last_audit_date). Моля, актуализирайте следващата дата на одита.',
|
||||
'labels_generated' => 'Етиката е успешно генериран.',
|
||||
'error_generating_labels' => 'Грешка при генериране на етикети.',
|
||||
'no_assets_selected' => 'Няма избрани активи.',
|
||||
'labels_generated' => 'Labels were successfully generated.',
|
||||
'error_generating_labels' => 'Error while generating labels.',
|
||||
'no_assets_selected' => 'No assets selected.',
|
||||
|
||||
'create' => [
|
||||
'error' => 'Активът не беше създаден. Моля опитайте отново.',
|
||||
'success' => 'Активът създаден успешно.',
|
||||
'success_linked' => 'Артикул с етикет :tag беше създаден успешно. <strong><a href=":link" style="color: white;">Щракнете тук за да го видите</a></strong>.',
|
||||
'multi_success_linked' => 'Актив с етикет :links беше създаден успешно.|:count активи бяха създадено успешно. :links.',
|
||||
'partial_failure' => 'Грешка при създаване на актив. Съобщението за грешка е: :failures|:count актива не бяха създадени. Съобщението за грешка е: :failures',
|
||||
'multi_success_linked' => 'Asset with tag :links was created successfully.|:count assets were created succesfully. :links.',
|
||||
'partial_failure' => 'An asset was unable to be created. Reason: :failures|:count assets were unable to be created. Reasons: :failures',
|
||||
],
|
||||
|
||||
'update' => [
|
||||
@@ -56,24 +56,24 @@ return [
|
||||
],
|
||||
|
||||
'import' => [
|
||||
'import_button' => 'Импортирай',
|
||||
'import_button' => 'Process Import',
|
||||
'error' => 'Някои елементи не бяха въведени правилно.',
|
||||
'errorDetail' => 'Следните елементи не бяха въведени поради грешки.',
|
||||
'success' => 'Вашият файл беше въведен.',
|
||||
'file_delete_success' => 'Вашият файл беше изтрит успешно.',
|
||||
'file_delete_error' => 'Файлът не е в състояние да бъде изтрит',
|
||||
'file_missing' => 'Избраният файл липсва',
|
||||
'file_already_deleted' => 'Избрания файл беше вече изтрит',
|
||||
'file_already_deleted' => 'The file selected was already deleted',
|
||||
'header_row_has_malformed_characters' => 'Един или повече атрибути на заглавния ред съдържат неправилни UTF-8 символи',
|
||||
'content_row_has_malformed_characters' => 'Един или повече атрибути на заглавния ред съдържат неправилни UTF-8 символи',
|
||||
'transliterate_failure' => 'Транслитерацията от :encoding към UTF-8 беше неуспешна, поради невалидни символи'
|
||||
'transliterate_failure' => 'Transliteration from :encoding to UTF-8 failed due to invalid characters in input'
|
||||
],
|
||||
|
||||
|
||||
'delete' => [
|
||||
'confirm' => 'Сигурни ли сте, че желаете изтриване на актива?',
|
||||
'error' => 'Проблем при изтриване на актива. Моля опитайте отново.',
|
||||
'assigned_to_error' => '{1}Актива: :asset_tag е изписан. Впишете го обратно преди изтриване.|[2,*] Активите :asset_tag са изписани. Впишете ги обратно преди изтриване.',
|
||||
'assigned_to_error' => '{1}Asset Tag: :asset_tag is currently checked out. Check in this device before deletion.|[2,*]Asset Tags: :asset_tag are currently checked out. Check in these devices before deletion.',
|
||||
'nothing_updated' => 'Няма избрани активи, така че нищо не бе изтрито.',
|
||||
'success' => 'Активът е изтрит успешно.',
|
||||
],
|
||||
@@ -87,8 +87,8 @@ return [
|
||||
],
|
||||
|
||||
'multi-checkout' => [
|
||||
'error' => 'Актива не беше изписан, моля опитайте отново|Активите не бяха изписани, моля опитайте отново',
|
||||
'success' => 'Актива е изписан успешно.|Активите са изписани успешно.',
|
||||
'error' => 'Asset was not checked out, please try again|Assets were not checked out, please try again',
|
||||
'success' => 'Asset checked out successfully.|Assets checked out successfully.',
|
||||
],
|
||||
|
||||
'checkin' => [
|
||||
@@ -100,9 +100,9 @@ return [
|
||||
],
|
||||
|
||||
'requests' => [
|
||||
'error' => 'Опитат беше неуспешен, моля опитайте отново.',
|
||||
'success' => 'Заявката е успешно подадена.',
|
||||
'canceled' => 'Заявката е отменена.',
|
||||
'error' => 'Request was not successful, please try again.',
|
||||
'success' => 'Request successfully submitted.',
|
||||
'canceled' => 'Request successfully canceled.',
|
||||
'cancel' => 'Отмени тази заявка за артикул',
|
||||
],
|
||||
|
||||
|
||||
@@ -47,5 +47,5 @@ return [
|
||||
'kit_deleted' => 'Комплектът беше изтрит',
|
||||
'kit_model_updated' => 'Модела беше успешно обновен',
|
||||
'kit_model_detached' => 'Модела беше премахнат успешно',
|
||||
'model_already_attached' => 'Модела е добавен в комплекта',
|
||||
'model_already_attached' => 'Model already attached to kit',
|
||||
];
|
||||
|
||||
@@ -14,7 +14,7 @@ return array(
|
||||
'info' => 'Информация за лиценз',
|
||||
'license_seats' => 'Потребителски лицензи',
|
||||
'seat' => 'Потребителски лиценз',
|
||||
'seat_count' => 'Брой места :count',
|
||||
'seat_count' => 'Seat :count',
|
||||
'seats' => 'Потребителски лицензи',
|
||||
'software_licenses' => 'Софтуерни лицензи',
|
||||
'user' => 'Потребител',
|
||||
@@ -24,12 +24,12 @@ return array(
|
||||
[
|
||||
'checkin_all' => [
|
||||
'button' => 'Връщане на всички бройки',
|
||||
'modal' => 'Това действие ще впише едно работно място. | Това действие ще впише всички :checkedout_seats_count работни места от този лиценз.',
|
||||
'modal' => 'This action will checkin one seat. | This action will checkin all :checkedout_seats_count seats for this license.',
|
||||
'enabled_tooltip' => 'Вписване на всички бройки от този лиценз за потребителите и активите',
|
||||
'disabled_tooltip' => 'Това е забранено защото няма изписани бройки',
|
||||
'disabled_tooltip_reassignable' => 'Това е деактивирано, защото лиценза не може да се прехвърля',
|
||||
'success' => 'Лиценза е заведен успешно! | Всички лицензи са заведени успешно!',
|
||||
'log_msg' => 'Вписване чрез групово лиценз вписване в GUI',
|
||||
'log_msg' => 'Checked in via bulk license checkin in license GUI',
|
||||
],
|
||||
|
||||
'checkout_all' => [
|
||||
|
||||
@@ -44,13 +44,13 @@ return array(
|
||||
'error' => 'Възникна проблем при изписването на лиценза. Моля, опитайте отново.',
|
||||
'success' => 'Лицензът е изписан',
|
||||
'not_enough_seats' => 'Няма достатъчно лицензи за изписване',
|
||||
'mismatch' => 'Броя лицензни места не отговаря на броя лицензи',
|
||||
'unavailable' => 'Този лиценз за работно място не е наличен за изписване.',
|
||||
'mismatch' => 'The license seat provided does not match the license',
|
||||
'unavailable' => 'This seat is not available for checkout.',
|
||||
),
|
||||
|
||||
'checkin' => array(
|
||||
'error' => 'Възникна проблем при вписването на лиценза. Моля, опитайте отново.',
|
||||
'not_reassignable' => 'Лиценза не може да се прехвърля',
|
||||
'not_reassignable' => 'License not reassignable',
|
||||
'success' => 'Лицензът е вписан'
|
||||
),
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
return array(
|
||||
|
||||
'does_not_exist' => 'Местоположението не съществува.',
|
||||
'assoc_users' => 'Това местоположение не може да бъде изтрито, защото има поне един запис на актив или потребител, зачислен към него или съдържа под локаций. Моля обновете вашите записи, така че да не съдържат това местоположение и пробвайте да го изтриете отново. ',
|
||||
'assoc_users' => 'This location is not currently deletable because it is the location of record for at least one asset or user, has assets assigned to it, or is the parent location of another location. Please update your records to no longer reference this location and try again ',
|
||||
'assoc_assets' => 'Местоположението е свързано с поне един актив и не може да бъде изтрито. Моля, актуализирайте активите, така че да не са свързани с това местоположение и опитайте отново. ',
|
||||
'assoc_child_loc' => 'В избраното местоположение е присъединено едно или повече местоположения. Моля преместете ги в друго и опитайте отново.',
|
||||
'assigned_assets' => 'Изписани Активи',
|
||||
'current_location' => 'Текущо местоположение',
|
||||
'open_map' => 'Отвори в :map_provider_icon карти',
|
||||
'open_map' => 'Open in :map_provider_icon Maps',
|
||||
|
||||
|
||||
'create' => array(
|
||||
@@ -22,8 +22,8 @@ return array(
|
||||
),
|
||||
|
||||
'restore' => array(
|
||||
'error' => 'Местоположението не беше възстановено, моля опитайте отново',
|
||||
'success' => 'Местоположението е възстановено.'
|
||||
'error' => 'Location was not restored, please try again',
|
||||
'success' => 'Location restored successfully.'
|
||||
),
|
||||
|
||||
'delete' => array(
|
||||
|
||||
@@ -39,5 +39,5 @@ return [
|
||||
'signed_by_finance_auditor' => 'Подписан от (счетоводител):',
|
||||
'signed_by_location_manager' => 'Подписан от (мениджър):',
|
||||
'signed_by' => 'Подписано от:',
|
||||
'clone' => 'Клонирай местоположението',
|
||||
'clone' => 'Clone Location',
|
||||
];
|
||||
|
||||
@@ -7,7 +7,7 @@ return array(
|
||||
'no_association' => 'ВНИМАНИЕ! Модела за този актив е неправилен или липсва!',
|
||||
'no_association_fix' => 'Това ще счупи нещата по много лош начин. Редактирайте артикула сега и го зачислете към модел.',
|
||||
'assoc_users' => 'Този модел е асоцииран с един или повече активи и не може да бъде изтрит. Моля изтрийте активите и опитайте отново.',
|
||||
'invalid_category_type' => 'Тази категоря трябва да бъде за модели.',
|
||||
'invalid_category_type' => 'This category must be an asset category.',
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Моделът не беше създаден. Моля опитайте отново.',
|
||||
|
||||
@@ -4,7 +4,7 @@ return [
|
||||
'info' => 'Изберете опциите, които желаете за справката за активи.',
|
||||
'deleted_user' => 'Изтрит потребител',
|
||||
'send_reminder' => 'Изпрати напомняне',
|
||||
'cannot_send_reminder' => 'Потребителя е бил изтрит или няма валиден е-майл адрес и не може да получи напомняне',
|
||||
'cannot_send_reminder' => 'User has been deleted or does not have an email address so cannot receive a reminder',
|
||||
'reminder_sent' => 'Напомнянето изпратено',
|
||||
'acceptance_deleted' => 'Заявката за приемане е изтрита',
|
||||
'acceptance_request' => 'Заявка за приемане',
|
||||
@@ -15,9 +15,9 @@ return [
|
||||
'user_country' => 'Държава на потребителя',
|
||||
'user_zip' => 'Пощенски код на потребителя'
|
||||
],
|
||||
'open_saved_template' => 'Отвори записан шаблон',
|
||||
'save_template' => 'Запиши шаблон',
|
||||
'select_a_template' => 'Избери шаблон',
|
||||
'template_name' => 'Име на шаблон',
|
||||
'update_template' => 'Обнови шаблон',
|
||||
'open_saved_template' => 'Open Saved Template',
|
||||
'save_template' => 'Save Template',
|
||||
'select_a_template' => 'Select a Template',
|
||||
'template_name' => 'Template Name',
|
||||
'update_template' => 'Update Template',
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ return [
|
||||
'ad_append_domain' => 'Добави името на домейна към потребителското име',
|
||||
'ad_append_domain_help' => 'От потребителя не се изисква да въвежда "username@domain.local", достатъчно е да напише само "username".',
|
||||
'admin_cc_email' => 'CC електронна поща',
|
||||
'admin_cc_email_help' => 'Изпращай копие на известията за вписване/изписване на следния е-майл адрес.',
|
||||
'admin_cc_email_help' => 'Send a copy of checkin/checkout emails to this address.',
|
||||
'admin_settings' => 'Админ настройки',
|
||||
'is_ad' => 'Това е активна директория на сървър',
|
||||
'alerts' => 'Известия',
|
||||
@@ -31,18 +31,18 @@ return [
|
||||
'backups' => 'Архивиране',
|
||||
'backups_help' => 'Създаване, сваляне и възстановяване на архиви ',
|
||||
'backups_restoring' => 'Възстановяване от архив',
|
||||
'backups_clean' => 'Почисти архива на базата преди възстановяване',
|
||||
'backups_clean_helptext' => "Това може да е полесно при смяна на версията на базата",
|
||||
'backups_clean' => 'Clean the backed-up database before restore',
|
||||
'backups_clean_helptext' => "This can be useful if you're changing between database versions",
|
||||
'backups_upload' => 'Качване на архив',
|
||||
'backups_path' => 'Архивите на сървъра са записани в <code>:path</code>',
|
||||
'backups_restore_warning' => 'Използвайте бутона за възстановяване <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> ,за да възстановите архивно копие. (Това не работи с S3 файлова система или Docker.)<br><br>Вашата <strong>цяла :app_name датабаза и всички качени файлове ще бъдат заменени</strong> от съдържанието на архива. ',
|
||||
'backups_restore_warning' => 'Use the restore button <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> to restore from a previous backup. (This does not currently work with S3 file storage or Docker.)<br><br>Your <strong>entire :app_name database and any uploaded files will be completely replaced</strong> by what\'s in the backup file ',
|
||||
'backups_logged_out' => 'Всички потребители, включително и вие, ще бъдат отписани след възстановяването.',
|
||||
'backups_large' => 'Много големите архиви може да не могат да се възстановят поради изтичане на времето на сесията и ще трябва да се възстановят ръчно през команден ред. ',
|
||||
'barcode_settings' => 'Настройки на баркод',
|
||||
'confirm_purge' => 'Потвърдете пречистване ',
|
||||
'confirm_purge_help' => 'Моля да потвърдите изтриването като въведете думата "DELETE" в полето. Изтриването не може да се прекрати и всички записи който са маркирани за истриване, ще бъдат безвъзвратно изтрити. (Добре е да направите архив преди това.)',
|
||||
'custom_css' => 'Потребителски CSS',
|
||||
'custom_css_placeholder' => 'Добавете ваш персонализиран CSS',
|
||||
'custom_css_placeholder' => 'Add your custom CSS',
|
||||
'custom_css_help' => 'Включете вашите CSS правила тук. Не използвайте <style></style> тагове.',
|
||||
'custom_forgot_pass_url' => 'Персонализиран адрес за възстановяване на паролата',
|
||||
'custom_forgot_pass_url_help' => 'Това URL ще замени вградения механизъм за възстановяване на паролата на входния екран, което е полезно за потребителите, използващи външни оторизации като LDAP. Това ефективно ще спре възможността за възстановяване на паролата за потребителите, управлявани през Sinpe-it.',
|
||||
@@ -50,28 +50,28 @@ return [
|
||||
'dashboard_message_help' => 'Този текст ще се появи на таблото на всички потребители с права за достъп до таблото.',
|
||||
'default_currency' => 'Валута по подразбиране',
|
||||
'default_eula_text' => 'EULA по подразбиране',
|
||||
'default_eula_text_placeholder' => 'Добавете ваш EULA',
|
||||
'default_eula_text_placeholder' => 'Add your default EULA text',
|
||||
'default_language' => 'Език по подразбиране',
|
||||
'default_eula_help_text' => 'Можете да асоциирате специфична EULA към всяка избрана категория.',
|
||||
'acceptance_note' => 'Добавете бележка за вашето решение (По желание)',
|
||||
'display_asset_name' => 'Визуализиране на актив',
|
||||
'display_checkout_date' => 'Визуализиране на дата на изписване',
|
||||
'display_eol' => 'Визуализиране на EOL в таблиците',
|
||||
'display_qr' => 'Показвай 2D баркод',
|
||||
'display_qr' => 'Display 2D barcode',
|
||||
'display_alt_barcode' => 'Показване на 1D баркод',
|
||||
'barcode_type' => '2D тип на баркод',
|
||||
'alt_barcode_type' => '1D тип на баркод',
|
||||
'enabled' => 'Активно',
|
||||
'eula_settings' => 'Настройки на EULA',
|
||||
'eula_markdown' => 'Съдържанието на EULA може да бъде форматирано с <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>.',
|
||||
'empty_row_count' => 'Отместване на началото на полето (Празни редове)',
|
||||
'empty_row_count_help' => 'Полетата ще започнат да се попълват след като празните редове се презкочат в началото на етикета.',
|
||||
'empty_row_count' => 'Field Start Offset (Empty Rows)',
|
||||
'empty_row_count_help' => 'Fields will begin populating after this many empty rows are skipped at the top of the label.',
|
||||
'favicon' => 'Favicon',
|
||||
'favicon_format' => 'Приетите файлови формати са ico, png, и gif. Другите формати на снимки може да не работят в всъчки браузъри.',
|
||||
'favicon_size' => 'Favicons трябва да бъдат квадратна снимка с размери, 16х16 пиксела.',
|
||||
'footer_text' => 'Допълнителен текст във футъра',
|
||||
'footer_text_help' => 'Този текст ще се визуализира в дясната част на футъра. Връзки могат да бъдат добавяни с използването на <a href="https://help.github.com/articles/github-flavored-markdown/">Github тип markdown</a>. Нови редове, хедър тагове, изображения и т.н. могат да доведат до непредвидими резултати.',
|
||||
'footer_text_placeholder' => 'Опционален текст на долния колонтитул',
|
||||
'footer_text_placeholder' => 'Optional footer text',
|
||||
'general_settings' => 'Общи настройки',
|
||||
'general_settings_help' => 'Общи условия и други',
|
||||
'generate_backup' => 'Създаване на архив',
|
||||
@@ -97,7 +97,7 @@ return [
|
||||
'ldap_login_sync_help' => 'Това единствено проверява дали LDAP може да се синхронизира успешно. Ако вашата LDAP заявка за оторизация не е коректна е възможно потребителите да не могат да влязат. НЕОБХОДИМО Е ДА ЗАПИШЕТЕ LDAP НАСТРОЙКИТЕ ПРЕДИ ТОВА.',
|
||||
'ldap_manager' => 'LDAP мениджър',
|
||||
'ldap_server' => 'LDAP сървър',
|
||||
'ldap_server_help' => 'Това трябва да започва с Idap:// (for unencrypted) или Idaps:// (for TLS or SSL)',
|
||||
'ldap_server_help' => 'This should start with ldap:// (for unencrypted) or ldaps:// (for TLS or SSL)',
|
||||
'ldap_server_cert' => 'Валидация на LDAP SSL сертификата',
|
||||
'ldap_server_cert_ignore' => 'Допускане на невалиден SSL сертификат',
|
||||
'ldap_server_cert_help' => 'Изберете тази опция ако използвате самоподписан SSL сертификат.',
|
||||
@@ -111,8 +111,8 @@ return [
|
||||
'ldap_pword' => 'LDAP парола на потребител за връзка',
|
||||
'ldap_basedn' => 'Базов DN',
|
||||
'ldap_filter' => 'LDAP филтър',
|
||||
'ldap_pw_sync' => 'Кеш за LDAP Пароли',
|
||||
'ldap_pw_sync_help' => 'Махнете отметката, ако не желаете да се пази кеш за LDAP пароли, като локален хеш. Забранявайки този опция означава, че вашите потребители няма да могат да се впишат ако не работи LDAP сървъра поради някаква причина.',
|
||||
'ldap_pw_sync' => 'Cache LDAP Passwords',
|
||||
'ldap_pw_sync_help' => 'Uncheck this box if you do not wish to keep LDAP passwords cached as local hashed passwords. Disabling this means that your users may not be able to login if your LDAP server is unreachable for some reason.',
|
||||
'ldap_username_field' => 'Поле за потребителско име',
|
||||
'ldap_lname_field' => 'Фамилия',
|
||||
'ldap_fname_field' => 'LDAP собствено име',
|
||||
@@ -120,8 +120,8 @@ return [
|
||||
'ldap_version' => 'LDAP версия',
|
||||
'ldap_active_flag' => 'LDAP флаг за активност',
|
||||
'ldap_activated_flag_help' => 'Тази стойност определя дали синхронизирания потребител може да се логва в Snipe-IT. <strong>Не се премахва възможността да се изписват активи към потребителя</strong> и полето трябва да бъде <strong>attribute name</strong> от вашата AD/LDAP, а не <strong>неговата стройност</strong>. <br><br>Ако това поле не съществува във вашата AD/LDAP или стойността е <code>0</code> или <code>false</code> <strong>достъпа на потребителя ще бъде забранен</strong>. Ако стойността в AD/LDAP полето е <code>1</code> или <code>true</code> означава че потребителя може да се логва. Когато това поле е празно във вашата AD се приема <code>userAccountControl</code> атрибута, който обикновенно позволява не блокираните потребители да се логват.',
|
||||
'ldap_invert_active_flag' => 'LDAP Инвертиране на активния флаг',
|
||||
'ldap_invert_active_flag_help' => 'Ако е включено, когато стойноста на полето LDAP Active Flag е <code>0</code> или <code>false</code> потребителя ще е активен.',
|
||||
'ldap_invert_active_flag' => 'LDAP Invert Active Flag',
|
||||
'ldap_invert_active_flag_help' => 'If enabled: when the value returned by LDAP Active Flag is <code>0</code> or <code>false</code> the user account will be active.',
|
||||
'ldap_emp_num' => 'LDAP номер на служител',
|
||||
'ldap_email' => 'LDAP електронна поща',
|
||||
'ldap_test' => 'Тест LDAP',
|
||||
@@ -136,7 +136,7 @@ return [
|
||||
'login_user_agent' => 'Потребителски агент',
|
||||
'login_help' => 'Списък на опитите за достъп',
|
||||
'login_note' => 'Вход забележка',
|
||||
'login_note_placeholder' => "Ако нямате потребител или сте намерили загубено устройство принадлежащо на тази компания, моля свържете се на официалният им телефон.",
|
||||
'login_note_placeholder' => "If you do not have a login or have found a device belonging to this company, please call technical support at 888-555-1212. Thank you.",
|
||||
'login_note_help' => 'По избор включете няколко изречения на екрана за вход, например, за да помогнете на хора, които са намерили изгубено или откраднато устройство. Това поле приема <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
|
||||
'login_remote_user_text' => 'Опции за вход с Remote User',
|
||||
'login_remote_user_enabled_text' => 'Включване на вход с HTTP хедър Remote User',
|
||||
@@ -152,15 +152,15 @@ return [
|
||||
'logo_print_assets_help' => 'Показвай логото при печат на листа с артикули ',
|
||||
'full_multiple_companies_support_help_text' => 'Ограничаване на потребителите (включително административните) до активите на собствената им компания.',
|
||||
'full_multiple_companies_support_text' => 'Поддръжка на множество компании',
|
||||
'scope_locations_fmcs_support_text' => 'Подружка на множество местоположения и много фирми',
|
||||
'scope_locations_fmcs_support_help_text' => 'Ограничи местоположенията до техните избрани фирми.',
|
||||
'scope_locations_fmcs_check_button' => 'Проверка за съвместимост',
|
||||
'scope_locations_fmcs_support_disabled_text' => 'Тази опция е забранена, защото имате конфликт на настройката на местоположение на :count или повече артикула.',
|
||||
'scope_locations_fmcs_support_text' => 'Scope Locations with Full Multiple Companies Support',
|
||||
'scope_locations_fmcs_support_help_text' => 'Restrict locations to their selected company.',
|
||||
'scope_locations_fmcs_check_button' => 'Check Compatibility',
|
||||
'scope_locations_fmcs_support_disabled_text' => 'This option is disabled because you have conflicting locations set for :count or more items.',
|
||||
'show_in_model_list' => 'Показване в падащите менюта на моделите',
|
||||
'optional' => 'незадължително',
|
||||
'per_page' => 'Резултати на страница',
|
||||
'php' => 'PHP версия',
|
||||
'php_info' => 'PHP инфо',
|
||||
'php_info' => 'PHP info',
|
||||
'php_overview' => 'PHP',
|
||||
'php_overview_help' => 'PHP Системна информация',
|
||||
'php_gd_info' => 'Необходимо е да инсталирате php-gd, за да визуализирате QR кодове. Моля прегледайте инструкцията за инсталация.',
|
||||
|
||||
@@ -49,11 +49,12 @@ return [
|
||||
'error_redirect' => 'Грешка 301/302 :endpoint върна пренасочване. От съображения за сигурност, ние не отваряме пренасочванията. Моля ползвайте действителната крайна точка.',
|
||||
'error_misc' => 'Възникна грешка. :( ',
|
||||
'webhook_fail' => ' webhook notification failed: Check to make sure the URL is still valid.',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.',
|
||||
'ms_teams_deprecation' => 'The selected Microsoft Teams webhook URL will be deprecated Dec 31st, 2025. Please use a workflow URL. Microsoft\'s documentation on creating a workflow can be found <a href="https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498" target="_blank"> here.</a>',
|
||||
'webhook_channel_not_found' => ' webhook channel not found.'
|
||||
],
|
||||
|
||||
'location_scoping' => [
|
||||
'not_saved' => 'Your settings were not saved.',
|
||||
'mismatch' => 'There is 1 item in the database that need your attention before you can enable location scoping.|There are :count items in the database that need your attention before you can enable location scoping.',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'about' => 'About Status Types',
|
||||
'about' => 'Относно статус етикетите',
|
||||
'archived' => 'Архивирани',
|
||||
'create' => 'Създаване на статус етикет',
|
||||
'color' => 'Цвят на диаграма',
|
||||
'default_label' => 'Етикет по подразбиране',
|
||||
'default_label_help' => 'Позиционира най-често използваните етикети в началото на падащото меню за избор при създаване и редактиране на активи.',
|
||||
'deployable' => 'Може да бъде предоставен',
|
||||
'info' => 'Status label types are used to describe the various states your assets could be in. They may be out for repair, lost/stolen, etc. You can create new status labels for your deployable, pending and archived assets according to your own workflow. For more information, <a href="https://snipe-it.readme.io/docs/overview#status-labels" target="_blank">see the documentation <i class="fa fa-external-link"></i></a>.',
|
||||
'info' => 'Статусите се използват за описване на различните състояния на Вашите активи. Например, това са Предаден за ремонт, Изгубен/откраднат и др. Можете да създавате нови статуси за активите, които могат да бъдат предоставяни, очакващи набавяне и архивирани.',
|
||||
'name' => 'Статус',
|
||||
'pending' => 'Изчакване',
|
||||
'status_type' => 'Тип на статуса',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user