refactor(forms): Integrate WithSortOrder trait into various forms and streamline sort order handling after deletions for improved code maintainability.

This commit is contained in:
Yoga Pangestu 2025-12-14 16:54:26 +07:00
parent 307cdeec44
commit e995391719
6 changed files with 118 additions and 191 deletions

View File

@ -4,13 +4,14 @@
use App\Models\Brand;
use App\Traits\WithMediaHandler;
use App\Traits\WithSortOrder;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;
class BrandForm extends Form
{
use WithMediaHandler;
use WithMediaHandler, WithSortOrder;
public ?Brand $brand = null;
@ -77,49 +78,16 @@ public function update(): void
public function delete(): void
{
$this->brand->delete();
Brand::where('sort_order', '>', $this->brand->sort_order)
->orderBy('sort_order')
->get()
->each(function ($cat) {
$cat->update(['sort_order' => $cat->sort_order - 1]);
});
$this->adjustSortOrderAfterDelete($this->brand);
}
public function sortOrder(string $direction): void
protected function getModelClass(): string
{
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = Brand::where('sort_order', '<', $this->brand->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = Brand::where('sort_order', '>', $this->brand->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $this->brand->sort_order;
$this->brand->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$this->brand->update(['sort_order' => Brand::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$this->brand->update(['sort_order' => Brand::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
return Brand::class;
}
protected function normalizeSortOrder(): void
protected function getModelInstance(): Brand
{
$categories = Brand::orderBy('sort_order')->get();
foreach ($categories as $index => $brand) {
$brand->update(['sort_order' => $index + 1]);
}
return $this->brand;
}
}

View File

@ -3,12 +3,15 @@
namespace App\Livewire\Forms\Studio\Catalog;
use App\Models\Category;
use App\Traits\WithSortOrder;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;
class CategoryForm extends Form
{
use WithSortOrder;
public ?Category $category = null;
public string $name = '';
@ -68,49 +71,16 @@ public function update(): void
public function delete(): void
{
$this->category->delete();
Category::where('sort_order', '>', $this->category->sort_order)
->orderBy('sort_order')
->get()
->each(function ($cat) {
$cat->update(['sort_order' => $cat->sort_order - 1]);
});
$this->adjustSortOrderAfterDelete($this->category);
}
public function sortOrder(string $direction): void
protected function getModelClass(): string
{
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = Category::where('sort_order', '<', $this->category->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = Category::where('sort_order', '>', $this->category->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $this->category->sort_order;
$this->category->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$this->category->update(['sort_order' => Category::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$this->category->update(['sort_order' => Category::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
return Category::class;
}
protected function normalizeSortOrder(): void
protected function getModelInstance(): Category
{
$categories = Category::orderBy('sort_order')->get();
foreach ($categories as $index => $category) {
$category->update(['sort_order' => $index + 1]);
}
return $this->category;
}
}

View File

@ -3,11 +3,14 @@
namespace App\Livewire\Forms\Studio\Feature;
use App\Models\ChooseUs;
use App\Traits\WithSortOrder;
use Illuminate\Support\Facades\DB;
use Livewire\Form;
class ChooseUsForm extends Form
{
use WithSortOrder;
public ?ChooseUs $chooseUs = null;
public string $name = '';
@ -67,49 +70,16 @@ public function update(): void
public function delete(): void
{
$this->chooseUs->delete();
ChooseUs::where('sort_order', '>', $this->chooseUs->sort_order)
->orderBy('sort_order')
->get()
->each(function ($cat) {
$cat->update(['sort_order' => $cat->sort_order - 1]);
});
$this->adjustSortOrderAfterDelete($this->chooseUs);
}
public function sortOrder(string $direction): void
protected function getModelClass(): string
{
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = ChooseUs::where('sort_order', '<', $this->chooseUs->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = ChooseUs::where('sort_order', '>', $this->chooseUs->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $this->chooseUs->sort_order;
$this->chooseUs->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$this->chooseUs->update(['sort_order' => ChooseUs::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$this->chooseUs->update(['sort_order' => ChooseUs::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
return ChooseUs::class;
}
protected function normalizeSortOrder(): void
protected function getModelInstance(): ChooseUs
{
$chooseUss = ChooseUs::orderBy('sort_order')->get();
foreach ($chooseUss as $index => $chooseUs) {
$chooseUs->update(['sort_order' => $index + 1]);
}
return $this->chooseUs;
}
}

View File

@ -3,11 +3,14 @@
namespace App\Livewire\Forms\Studio\Feature;
use App\Models\PerfumeFeature;
use App\Traits\WithSortOrder;
use Illuminate\Support\Facades\DB;
use Livewire\Form;
class PerfumeFeatureForm extends Form
{
use WithSortOrder;
public ?PerfumeFeature $perfumeFeature = null;
public string $name = '';
@ -67,49 +70,16 @@ public function update(): void
public function delete(): void
{
$this->perfumeFeature->delete();
PerfumeFeature::where('sort_order', '>', $this->perfumeFeature->sort_order)
->orderBy('sort_order')
->get()
->each(function ($cat) {
$cat->update(['sort_order' => $cat->sort_order - 1]);
});
$this->adjustSortOrderAfterDelete($this->perfumeFeature);
}
public function sortOrder(string $direction): void
protected function getModelClass(): string
{
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = PerfumeFeature::where('sort_order', '<', $this->perfumeFeature->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = PerfumeFeature::where('sort_order', '>', $this->perfumeFeature->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $this->perfumeFeature->sort_order;
$this->perfumeFeature->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$this->perfumeFeature->update(['sort_order' => PerfumeFeature::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$this->perfumeFeature->update(['sort_order' => PerfumeFeature::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
return PerfumeFeature::class;
}
protected function normalizeSortOrder(): void
protected function getModelInstance(): PerfumeFeature
{
$perfumeFeatures = PerfumeFeature::orderBy('sort_order')->get();
foreach ($perfumeFeatures as $index => $perfumeFeature) {
$perfumeFeature->update(['sort_order' => $index + 1]);
}
return $this->perfumeFeature;
}
}

View File

@ -3,11 +3,14 @@
namespace App\Livewire\Forms\Studio\Information;
use App\Models\Faq;
use App\Traits\WithSortOrder;
use Illuminate\Support\Facades\DB;
use Livewire\Form;
class FaqForm extends Form
{
use WithSortOrder;
public ?Faq $faq = null;
public string $question = '';
@ -67,49 +70,16 @@ public function update(): void
public function delete(): void
{
$this->faq->delete();
Faq::where('sort_order', '>', $this->faq->sort_order)
->orderBy('sort_order')
->get()
->each(function ($cat) {
$cat->update(['sort_order' => $cat->sort_order - 1]);
});
$this->adjustSortOrderAfterDelete($this->faq);
}
public function sortOrder(string $direction): void
protected function getModelClass(): string
{
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = Faq::where('sort_order', '<', $this->faq->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = Faq::where('sort_order', '>', $this->faq->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $this->faq->sort_order;
$this->faq->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$this->faq->update(['sort_order' => Faq::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$this->faq->update(['sort_order' => Faq::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
return Faq::class;
}
protected function normalizeSortOrder(): void
protected function getModelInstance(): Faq
{
$categories = Faq::orderBy('sort_order')->get();
foreach ($categories as $index => $faq) {
$faq->update(['sort_order' => $index + 1]);
}
return $this->faq;
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Traits;
trait WithSortOrder
{
/**
* Get the model class for this sortable entity
*/
abstract protected function getModelClass(): string;
/**
* Get the current model instance
*/
abstract protected function getModelInstance();
/**
* Adjust sort order after deletion
*/
protected function adjustSortOrderAfterDelete($deletedModel): void
{
$modelClass = $this->getModelClass();
$modelClass::where('sort_order', '>', $deletedModel->sort_order)
->orderBy('sort_order')
->get()
->each(function ($item) {
$item->update(['sort_order' => $item->sort_order - 1]);
});
}
/**
* Handle sort order changes (up, down, first, last)
*/
public function sortOrder(string $direction): void
{
$modelClass = $this->getModelClass();
$model = $this->getModelInstance();
if (in_array($direction, ['up', 'down'])) {
$swap = null;
if ($direction === 'up') {
$swap = $modelClass::where('sort_order', '<', $model->sort_order)
->orderByDesc('sort_order')
->first();
} else {
$swap = $modelClass::where('sort_order', '>', $model->sort_order)
->orderBy('sort_order')
->first();
}
if ($swap) {
$temp = $model->sort_order;
$model->update(['sort_order' => $swap->sort_order]);
$swap->update(['sort_order' => $temp]);
}
} elseif ($direction === 'first') {
$model->update(['sort_order' => $modelClass::min('sort_order') - 1]);
$this->normalizeSortOrder();
} elseif ($direction === 'last') {
$model->update(['sort_order' => $modelClass::max('sort_order') + 1]);
$this->normalizeSortOrder();
}
}
/**
* Normalize sort order to ensure consecutive numbering
*/
protected function normalizeSortOrder(): void
{
$modelClass = $this->getModelClass();
$items = $modelClass::orderBy('sort_order')->get();
foreach ($items as $index => $item) {
$item->update(['sort_order' => $index + 1]);
}
}
}