diff --git a/app/Http/Controllers/Bo/TicketController.php b/app/Http/Controllers/Bo/TicketController.php index ce4164e..0b4fe66 100644 --- a/app/Http/Controllers/Bo/TicketController.php +++ b/app/Http/Controllers/Bo/TicketController.php @@ -17,6 +17,7 @@ use App\Http\Requests\Bo\UpdateChangeOrderRequest; use App\Http\Requests\Bo\UpdateMessage; use App\Http\Requests\Bo\UpdateTicket; use App\Http\Requests\Bo\LinkTicket; +use App\Http\Requests\Bo\UpdateTicketPriorityRequest; use App\Lib\Helpers\FileStorageHelper; use App\Lib\Helpers\ToolboxHelper; use App\Mail\NewTicket; @@ -878,4 +879,34 @@ class TicketController extends Controller return redirect()->back()->with('success', trans('crud.messages.order_changed')); }); } + + /** + * Update ticket priority. + * + * @param UpdateTicketPriorityRequest $request + * @param Ticket $ticket + * @return void + */ + public function changePriority(UpdateTicketPriorityRequest $request, Ticket $ticket) + { + $newPriority = $request->validated('priority'); + + return DB::transaction(function () use ($ticket, $newPriority) { + // Update all tickets who will be moved with this priority update. + $request = Ticket::query() + ->where('site_id', $ticket->site_id) + ->whereNot('status', TicketStatusEnum::archived) + ->whereNot('id', $ticket->id) + ->whereBetween('order', [min($ticket->order, $newPriority), max($ticket->order, $newPriority)]); + $ticket->order < $newPriority ? $request->decrement('order', 1) : $request->increment('order', 1); + + // Update the ticket. + $ticket->order = $newPriority; + if (!$ticket->saveOrFail()) { + return back()->with('error', trans('crud.messages.order_not_changed')); + }; + + return redirect()->back()->with('success', trans('crud.messages.order_changed')); + }); + } } diff --git a/app/Http/Requests/Bo/UpdateTicketPriorityRequest.php b/app/Http/Requests/Bo/UpdateTicketPriorityRequest.php new file mode 100644 index 0000000..f3a5d45 --- /dev/null +++ b/app/Http/Requests/Bo/UpdateTicketPriorityRequest.php @@ -0,0 +1,57 @@ +check(); + } + + /** + * Prepare the data for validation. + * + * @return void + */ + protected function prepareForValidation(): void + { + $this->ticket = $this->route('ticket'); + $max = Ticket::query()->where('site_id', $this->ticket->site_id)->max('order'); + + $this->merge([ + 'priority' => min($this->integer('priority'), $max) + ]); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + return [ + 'priority' => [ + 'required', + 'integer', + 'min:1', + function ($attribute, $value, $fail) { + if ($this->ticket && intval($value) === $this->ticket->order) { + $fail("La valeur de {$attribute} doit être différente de la valeur actuelle."); + } + }, + ], + ]; + } +} diff --git a/app/Models/Ticket.php b/app/Models/Ticket.php index 7286312..b96617b 100644 --- a/app/Models/Ticket.php +++ b/app/Models/Ticket.php @@ -63,8 +63,8 @@ class Ticket extends Model protected static function booted() { static::creating(function (Ticket $ticket) { - // If bug force the ticket status on new. All the others are estimateTodo. self::setOrder($ticket); + // If bug force the ticket status on new. All the others are estimateTodo. if ($ticket->type->equals(TicketTypeEnum::bug)) { $ticket->status = TicketStatusEnum::new; } else { @@ -108,9 +108,18 @@ class Ticket extends Model */ private static function setOrder(self $model, bool $isArchived = false): void { - $model->order = \intval( - self::query()->where('status', $isArchived ? '=' : '!=', TicketStatusEnum::archived)->max('order') - ) + 1; + $maxOrder = \intval(self::query()->where('status', '!=', TicketStatusEnum::archived)->max('order')); + if ($isArchived) { + $request = Ticket::query() + ->where('site_id', $model->site_id) + ->whereNot('status', TicketStatusEnum::archived) + ->whereNot('id', $model->id) + ->whereBetween('order', [$model->order, $maxOrder]); + $request->decrement('order', 1); + $model->order = 0; + return; + } + $model->order = $maxOrder + 1; } diff --git a/database/migrations/2025_11_19_142520_reorder_all_tickets.php b/database/migrations/2025_11_19_142520_reorder_all_tickets.php new file mode 100644 index 0000000..56fb9e2 --- /dev/null +++ b/database/migrations/2025_11_19_142520_reorder_all_tickets.php @@ -0,0 +1,36 @@ +each(function (Site $site) { + $tickets = $site->tickets()->whereNot('status', TicketStatusEnum::archived)->orderBy('order')->get(); + $order = 1; + foreach ($tickets as $ticket) { + $ticket->order = $order; + $ticket->saveOrFail(); + $order++; + } + }); + Ticket::query()->where('status', TicketStatusEnum::archived)->update([ + 'order' => 0 + ]); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // Nothing to revert. + } +}; diff --git a/resources/ts/bo/utilities/fontawesome.ts b/resources/ts/bo/utilities/fontawesome.ts index f3568c8..d2efeb3 100644 --- a/resources/ts/bo/utilities/fontawesome.ts +++ b/resources/ts/bo/utilities/fontawesome.ts @@ -66,7 +66,8 @@ import { faUsers, faWandMagic, faXmark, - faLinkSlash + faLinkSlash, + faChevronDown } from "@fortawesome/free-solid-svg-icons"; config.autoReplaceSvg = false; @@ -132,6 +133,7 @@ library.add(faLinkSlash); // Front library.add(faChevronLeft); library.add(faChevronRight); +library.add(faChevronDown); library.add(faBan); library.add(faDownload); library.add(faUsers); diff --git a/resources/views/bo/modules/change-model-order-select.blade.php b/resources/views/bo/modules/change-model-order-select.blade.php new file mode 100644 index 0000000..2b5b48e --- /dev/null +++ b/resources/views/bo/modules/change-model-order-select.blade.php @@ -0,0 +1,23 @@ +