feat: re-order products with a select system like support-web - #94
This commit is contained in:
parent
6e7bbe0681
commit
f9e0448fb6
6 changed files with 155 additions and 7 deletions
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Bo;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\ProductRequest;
|
||||
use App\Http\Requests\Bo\UpdateProductOrderRequest;
|
||||
use App\Models\OldSlug;
|
||||
use App\Models\FoodProduct;
|
||||
use App\Models\ToolProduct;
|
||||
|
|
@ -18,6 +19,7 @@ use App\Traits\Controllers\ChangesModelOrder;
|
|||
use App\Traits\Controllers\UpdateModelStatus;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
|
|
@ -867,4 +869,35 @@ class ProductsController extends Controller
|
|||
$products = Product::where('star', 1)->paginate(10);
|
||||
return view('bo.products.starred', compact('products'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update product order.
|
||||
*
|
||||
* @param UpdateProductOrderRequest $request
|
||||
* @param Product $product
|
||||
* @return void
|
||||
*/
|
||||
public function changeSelectedOrder(UpdateProductOrderRequest $request, Product $product)
|
||||
{
|
||||
// Laravel 8 style ... validated() never returns a string.
|
||||
$validated = $request->validated();
|
||||
$newOrder = $validated['order'];
|
||||
|
||||
return DB::transaction(function () use ($product, $newOrder) {
|
||||
// Update all products who will be moved with this order update.
|
||||
// Includes soft deleted to avoid problems if we restore them.
|
||||
$request = Product::withTrashed()
|
||||
->where('id', '!=', $product->id)
|
||||
->whereBetween('order', [min($product->order, $newOrder), max($product->order, $newOrder)]);
|
||||
$product->order < $newOrder ? $request->decrement('order', 1) : $request->increment('order', 1);
|
||||
|
||||
// Update the product.
|
||||
$product->order = $newOrder;
|
||||
if (!$product->saveOrFail()) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
};
|
||||
|
||||
return redirect()->back()->with('success', trans('crud.messages.order_changed'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
57
app/Http/Requests/Bo/UpdateProductOrderRequest.php
Normal file
57
app/Http/Requests/Bo/UpdateProductOrderRequest.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateProductOrderRequest extends FormRequest
|
||||
{
|
||||
private $product;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->product = $this->route('product');
|
||||
$max = Product::query()->max('order');
|
||||
|
||||
$this->merge([
|
||||
'order' => min($this->input('order'), $max)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'order' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->product && intval($value) === $this->product->order) {
|
||||
$fail("La valeur de {$attribute} doit être différente de la valeur actuelle.");
|
||||
}
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$products = Product::withTrashed()->orderBy('order')->get();
|
||||
$order = 1;
|
||||
foreach ($products as $product) {
|
||||
$product->order = $order;
|
||||
$product->saveOrFail();
|
||||
$order++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Nothing to revert.
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<td class="text-center align-middle">
|
||||
<div class="d-flex justify-content-center align-items-center">
|
||||
<b class="mx-3">{{ $value ?? '' }}</b>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fa-solid fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<form class="px-4 py-3" action="{{ route('bo.product.change-selected-order', ['product' => $model]) }}" method="POST">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<div class="mb-3">
|
||||
<label for="order-{{ $model->id }}" class="form-label">{{ __('Nouvelle position') }}</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>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($products as $product)
|
||||
@foreach ($products as $key => $product)
|
||||
<tr>
|
||||
@if(count(Config::get('theme.enum_product_types'))>1)
|
||||
<td>
|
||||
|
|
@ -110,11 +110,9 @@
|
|||
</button>
|
||||
</form>
|
||||
</td>
|
||||
@php $routeName = request()->route()->getName(); @endphp
|
||||
@include('bo.modules.change-model-order', [
|
||||
'routeName' => 'products',
|
||||
'models' => $products,
|
||||
'model' => $product
|
||||
@include('bo.modules.change-model-order-select', [
|
||||
'model' => $product,
|
||||
'value' => $key + 1 + ($products->currentPage() - 1) * $products->perPage(),
|
||||
])
|
||||
<td class="text-center">
|
||||
<a href="{{ route('bo.products.edit', $product->id) }}" class="btn btn-sm btn-primary">Éditer</a>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@ Route::name('auth.')
|
|||
|
||||
Route::prefix('bo')
|
||||
->name('bo.')
|
||||
->middleware(['auth', 'is-admin', 'admin-secure'])
|
||||
->middleware([
|
||||
'auth',
|
||||
'is-admin',
|
||||
'admin-secure'
|
||||
])
|
||||
->group(function () {
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
Route::match(['get', 'put'], '/content/{key}', [ContentController::class, 'manage'])
|
||||
|
|
@ -71,6 +75,10 @@ Route::prefix('bo')
|
|||
->name('products.change-published');
|
||||
Route::get('/products/change-order/{product}/{direction}', [ProductsController::class, 'changeOrder'])
|
||||
->where('direction', 'up|down')->name('products.change-order');
|
||||
Route::patch('/products/{product}/change-selected-order', [
|
||||
ProductsController::class,
|
||||
'changeSelectedOrder'
|
||||
])->name('product.change-selected-order');
|
||||
// Slides.
|
||||
Route::resource('slides', SlidesController::class)->except(['show']);
|
||||
Route::resource('sliders', SlidersController::class)->except(['show']);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue