refactor: ♻️ make changeCustomOrder generic
This commit is contained in:
parent
074320d79c
commit
0a07237aa7
9 changed files with 130 additions and 70 deletions
|
|
@ -4,11 +4,10 @@ namespace App\Http\Controllers\Bo;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Aisles\StoreAisleRequest;
|
||||
use App\Http\Requests\Bo\Aisles\UpdateAisleOrderRequest;
|
||||
use App\Http\Requests\Bo\Aisles\UpdateAisleRequest;
|
||||
use App\Models\Aisle;
|
||||
use App\Models\Network;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -16,7 +15,7 @@ use Illuminate\Support\Str;
|
|||
|
||||
class AisleController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
use UpdateModelOrder;
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
|
|
@ -68,7 +67,6 @@ class AisleController extends Controller
|
|||
return view('bo.pages.aisles.index', compact('aisleModels', 'networkModels', 'selectedNetwork', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
|
|
@ -183,34 +181,4 @@ class AisleController extends Controller
|
|||
{
|
||||
return $this->create($aisle->replicate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ticket priority.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Aisles\UpdateAisleOrderRequest $request
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return void
|
||||
*/
|
||||
public function changeCustomOrder(UpdateAisleOrderRequest $request, Aisle $aisle)
|
||||
{
|
||||
$newOrder = $request->validated('order');
|
||||
|
||||
return DB::transaction(function () use ($aisle, $newOrder) {
|
||||
// Update all tickets who will be moved with this priority update.
|
||||
$request = Aisle::query()
|
||||
->where('network_id', $aisle->network_id)
|
||||
->whereNot('id', $aisle->id)
|
||||
->whereBetween('order', [min($aisle->order, $newOrder), max($aisle->order, $newOrder)]);
|
||||
$aisle->order < $newOrder ? $request->decrement('order', 1) : $request->increment('order', 1);
|
||||
|
||||
// Update the aisle.
|
||||
$aisle->order = $newOrder;
|
||||
if (!$aisle->saveOrFail()) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
};
|
||||
|
||||
return redirect()->back()->with('success', trans('crud.messages.order_changed'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Aisles;
|
||||
|
||||
|
||||
class UpdateAisleRequest extends StoreAisleRequest
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Aisles;
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use App\Models\Aisle;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateAisleOrderRequest extends FormRequest
|
||||
class UpdateOrderRequest extends FormRequest
|
||||
{
|
||||
private \App\Models\Aisle $aisle;
|
||||
/**
|
||||
* Attribute model needed.
|
||||
*
|
||||
* @var Model $orderable
|
||||
*/
|
||||
|
||||
private Model $orderableModel;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
|
@ -26,8 +32,8 @@ class UpdateAisleOrderRequest extends FormRequest
|
|||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->aisle = $this->route('aisle');
|
||||
$this->max = Aisle::query()->where('network_id', $this->aisle->network_id)->max('order');
|
||||
$this->orderableModel = collect($this->route()->parameters())
|
||||
->first(fn($param) => $param instanceof Model);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,9 +48,9 @@ class UpdateAisleOrderRequest extends FormRequest
|
|||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
sprintf('max:%s', $this->max),
|
||||
sprintf('max:%s', $this->orderableModel->max('order')),
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->aisle && intval($value) === $this->aisle->order) {
|
||||
if ($this->orderableModel && intval($value) === $this->orderableModel->order) {
|
||||
$fail("La valeur de {$attribute} doit être différente de la valeur actuelle.");
|
||||
}
|
||||
},
|
||||
|
|
@ -4,6 +4,7 @@ namespace App\Models;
|
|||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use App\Traits\Models\Orderable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
|
@ -12,6 +13,7 @@ class Aisle extends Model
|
|||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
use Orderable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -81,29 +83,6 @@ class Aisle extends Model
|
|||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order after the last element of the list.
|
||||
*
|
||||
* @param self $model
|
||||
* @param boolean $isDeletion
|
||||
* @return void
|
||||
*/
|
||||
private static function setOrder(self $model, bool $isDeletion = false): void
|
||||
{
|
||||
$maxOrder = \intval(self::query()->where('network_id', $model->network_id)->max('order'));
|
||||
|
||||
if ($isDeletion) {
|
||||
$request = Aisle::query()
|
||||
->where('network_id', $model->network_id)
|
||||
->whereNot('id', $model->id)
|
||||
->whereBetween('order', [$model->order, $maxOrder]);
|
||||
$request->decrement('order', 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$model->order = $maxOrder + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the limit of published models is reached.
|
||||
*
|
||||
|
|
@ -125,6 +104,16 @@ class Aisle extends Model
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group ordering by network_id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderGroupField(): string
|
||||
{
|
||||
return 'network_id';
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
|
|
|
|||
44
app/Traits/Controllers/UpdateModelOrder.php
Normal file
44
app/Traits/Controllers/UpdateModelOrder.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Controllers;
|
||||
|
||||
use App\Http\Requests\Bo\UpdateOrderRequest;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
trait UpdateModelOrder
|
||||
{
|
||||
/**
|
||||
* Updates the model order and shifts affected siblings accordingly
|
||||
*
|
||||
* @param UpdateOrderRequest $request
|
||||
* @param Model $model
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function changeCustomOrder(UpdateOrderRequest $request, Model $model): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$newOrder = $request->validated('order');
|
||||
|
||||
return DB::transaction(function () use ($model, $newOrder): RedirectResponse {
|
||||
$groupField = $model->getOrderGroupField();
|
||||
|
||||
$query = $model::query()
|
||||
->whereKeyNot($model)
|
||||
->whereBetween('order', [min($model->order, $newOrder), max($model->order, $newOrder)]);
|
||||
|
||||
if ($groupField) {
|
||||
$query->where($groupField, $model->{$groupField});
|
||||
}
|
||||
|
||||
$model->order < $newOrder ? $query->decrement('order', 1) : $query->increment('order', 1);
|
||||
|
||||
$model->order = $newOrder;
|
||||
if (!$model->saveOrFail()) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
};
|
||||
|
||||
return back()->with('success', trans('crud.messages.order_changed'));
|
||||
});
|
||||
}
|
||||
}
|
||||
53
app/Traits/Models/Orderable.php
Normal file
53
app/Traits/Models/Orderable.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait Orderable
|
||||
{
|
||||
/**
|
||||
* Returns the grouping field used for ordering.
|
||||
* Returns null if the order is global
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getOrderGroupField(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order after the last element of the list.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param bool $isDeletion
|
||||
* @return void
|
||||
*/
|
||||
public static function setOrder(Model $model, bool $isDeletion = false): void
|
||||
{
|
||||
$groupField = $model->getOrderGroupField();
|
||||
$maxOrderQuery = $model::query();
|
||||
|
||||
if ($groupField) {
|
||||
$maxOrderQuery->where($groupField, $model->{$groupField});
|
||||
}
|
||||
|
||||
$maxOrder = \intval($maxOrderQuery->max('order'));
|
||||
|
||||
if ($isDeletion) {
|
||||
$query = $model::query()
|
||||
->whereKeyNot($model)
|
||||
->whereBetween('order', [$model->order, $maxOrder]);
|
||||
|
||||
if ($groupField) {
|
||||
$query->where($groupField, $model->{$groupField});
|
||||
}
|
||||
|
||||
$query->decrement('order', 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$model->order = $maxOrder + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
<i class="fa-solid fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<form class="px-4 py-3" action="{{ route('bo.aisles.change-order', ['aisle' => $model]) }}" method="POST">
|
||||
<form class="px-4 py-3" action="{{ route("bo.$routeName.change-order", [Str::singular($routeName) => $model]) }}" method="POST">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<div class="mb-3">
|
||||
<label for="order-{{ $model->id }}" class="form-label">{{ __('Nouvel ordre') }}</label>
|
||||
<label for="order-{{ $model->getKey() }}" class="form-label">{{ __('Nouvel ordre') }}</label>
|
||||
<input type="number" class="form-input" id="order-{{ $model->id }}" placeholder="1" name="order" min="1">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">{{ _('Sauvegarder') }}</button>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
@endphp
|
||||
@if (request()->network && empty(request()->search) && Session::get("$routeName.sort_col") === 'order')
|
||||
@include('bo.modules.change-model-order-select', [
|
||||
'model' => $aisleModel,
|
||||
'routeName' => 'aisles',
|
||||
'model' => $aisleModel,
|
||||
])
|
||||
@endif
|
||||
<td class="text-center align-middle">{{ $aisleModel->name }}</td>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
Tous les rayons
|
||||
</option>
|
||||
@foreach ($networkModels as $networkModel)
|
||||
<option value="{{ $networkModel->id }}" @if ($selectedNetwork === $networkModel->id) selected @endif>
|
||||
<option value="{{ $networkModel->getKey() }}" @if ($selectedNetwork === $networkModel->getKey()) selected @endif>
|
||||
{{ $networkModel->title }}
|
||||
</option>
|
||||
@endforeach
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue