diff --git a/Modules/Helpdesk/Livewire/KanbanBoard.php b/Modules/Helpdesk/Livewire/KanbanBoard.php index 15ab7ba..202148a 100644 --- a/Modules/Helpdesk/Livewire/KanbanBoard.php +++ b/Modules/Helpdesk/Livewire/KanbanBoard.php @@ -81,12 +81,12 @@ final class KanbanBoard extends Component Auth::user(), ); - $message = 'Ticket '.$freshTicket->reference.' moved from '.$oldStatusName.' to '.$status->name.'.'; + $message = 'Ticket ' . $freshTicket->reference . ' moved from ' . $oldStatusName . ' to ' . $status->name . '.'; session()->flash('success', $message); $this->refreshBoard(); $this->dispatch('helpdesk-kanban-moved', ticketId: (int) $freshTicket->id, statusId: (int) $freshTicket->status_id); - $this->dispatch('thredary:toast', type: 'success', title: 'Ticket moved', message: $message); + $this->dispatch('helpdesk:toast', type: 'success', title: 'Ticket moved', message: $message); } finally { $this->isMovingTicket = false; } @@ -124,12 +124,12 @@ final class KanbanBoard extends Component $fresh = $ticket->fresh(['status', 'priority', 'category', 'project', 'team', 'board']) ?? $ticket; $workflow->dispatch($fresh, 'ticket.updated', Auth::user()); - $message = 'Ticket '.$fresh->reference.' moved from '.$oldBoardName.' to '.$board->name.'.'; + $message = 'Ticket ' . $fresh->reference . ' moved from ' . $oldBoardName . ' to ' . $board->name . '.'; session()->flash('success', $message); $this->refreshBoard(); $this->dispatch('helpdesk-kanban-moved', ticketId: (int) $fresh->id, statusId: (int) $fresh->status_id); - $this->dispatch('thredary:toast', type: 'success', title: 'Board changed', message: $message); + $this->dispatch('helpdesk:toast', type: 'success', title: 'Board changed', message: $message); } /** @@ -234,7 +234,7 @@ final class KanbanBoard extends Component /** * Resolve the selected board from an already-loaded board collection. * - * @param Collection $boards + * @param Collection $boards */ private function resolveSelectedBoard(Collection $boards): ?KanbanBoardModel { diff --git a/Modules/Helpdesk/Policies/TicketPolicy.php b/Modules/Helpdesk/Policies/TicketPolicy.php index 1f47afe..73cd9ab 100644 --- a/Modules/Helpdesk/Policies/TicketPolicy.php +++ b/Modules/Helpdesk/Policies/TicketPolicy.php @@ -16,9 +16,16 @@ final class TicketPolicy public function view(User $user, Ticket $ticket): bool { - return $this->isPrivileged($user) - || ($user->isHelpdeskAgent() && ((int) $ticket->agent_id === (int) $user->id || (int) $ticket->user_id === (int) $user->id)) - || (int) $ticket->user_id === (int) $user->id; + if ($this->isHelpdeskAdmin($user)) { + return true; + } + + if ($this->isHelpdeskAgent($user)) { + return (int) $ticket->agent_id === (int) $user->id + || (int) $ticket->user_id === (int) $user->id; + } + + return (int) $ticket->user_id === (int) $user->id; } public function create(User $user): bool @@ -26,10 +33,29 @@ final class TicketPolicy return true; } + /** + * Helpdesk workflow updates. + * + * Admins can update every Helpdesk ticket. + * + * Agents can update any ticket that is visible to them under the Helpdesk + * visibility rules. This is important for Kanban drag/drop: a card must + * never be displayed as movable and then fail authorization on drop. + * + * Normal requesters cannot change workflow/status/assignment data. + */ public function update(User $user, Ticket $ticket): bool { - return $this->isPrivileged($user) - || ($user->isHelpdeskAgent() && (int) $ticket->agent_id === (int) $user->id); + if ($this->isHelpdeskAdmin($user)) { + return true; + } + + if (! $this->isHelpdeskAgent($user)) { + return false; + } + + return (int) $ticket->agent_id === (int) $user->id + || (int) $ticket->user_id === (int) $user->id; } public function comment(User $user, Ticket $ticket): bool @@ -39,11 +65,36 @@ final class TicketPolicy public function delete(User $user, Ticket $ticket): bool { - return $this->isPrivileged($user); + return $this->isHelpdeskAdmin($user); } - private function isPrivileged(User $user): bool + private function isHelpdeskAdmin(User $user): bool { - return $user->isHelpdeskAdmin(); + if (method_exists($user, 'isHelpdeskAdmin')) { + return $user->isHelpdeskAdmin(); + } + + if ((bool) ($user->helpdesk_admin ?? false)) { + return true; + } + + if (method_exists($user, 'isAdmin')) { + return $user->isAdmin(); + } + + if (method_exists($user, 'isMpbaPlatformAdmin')) { + return $user->isMpbaPlatformAdmin(); + } + + return false; + } + + private function isHelpdeskAgent(User $user): bool + { + if (method_exists($user, 'isHelpdeskAgent')) { + return $user->isHelpdeskAgent(); + } + + return (bool) ($user->helpdesk_agent ?? false); } } diff --git a/resources/themes/backend/assets/css/app.css b/resources/themes/backend/assets/css/app.css index 23f31c4..3239a57 100644 --- a/resources/themes/backend/assets/css/app.css +++ b/resources/themes/backend/assets/css/app.css @@ -13,31 +13,6 @@ @theme { --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - - --color-zinc-50: #fafafa; - --color-zinc-100: #f5f5f5; - --color-zinc-200: #e5e5e5; - --color-zinc-300: #d4d4d4; - --color-zinc-400: #a3a3a3; - --color-zinc-500: #737373; - --color-zinc-600: #525252; - --color-zinc-700: #404040; - --color-zinc-800: #262626; - --color-zinc-900: #171717; - --color-zinc-950: #0a0a0a; - - /* Keep Flux controls on the same Helpdesk/Core blue accent. */ - --color-accent: #2563eb; - --color-accent-content: #1d4ed8; - --color-accent-foreground: #ffffff; -} - -@layer theme { - .dark { - --color-accent: #60a5fa; - --color-accent-content: #93c5fd; - --color-accent-foreground: #172554; - } } @layer base { @@ -49,17 +24,3 @@ border-color: var(--color-gray-200, currentColor); } } - -[data-flux-field]:not(ui-radio, ui-checkbox) { - @apply grid gap-2; -} - -[data-flux-label] { - @apply !mb-0 !leading-tight; -} - -input:focus[data-flux-control], -textarea:focus[data-flux-control], -select:focus[data-flux-control] { - @apply outline-hidden ring-2 ring-accent ring-offset-2 ring-offset-accent-foreground; -} diff --git a/resources/themes/backend/assets/css/helpdesk.css b/resources/themes/backend/assets/css/helpdesk.css index 82d953f..16f7afa 100644 --- a/resources/themes/backend/assets/css/helpdesk.css +++ b/resources/themes/backend/assets/css/helpdesk.css @@ -1,148 +1,974 @@ -/* - * Helpdesk backend colour system. - * One palette is shared across dashboard, tickets, Kanban, support and settings. - */ - -:root { - --hd-primary-50: #eff6ff; - --hd-primary-100: #dbeafe; - --hd-primary-200: #bfdbfe; - --hd-primary-300: #93c5fd; - --hd-primary-400: #60a5fa; - --hd-primary-500: #3b82f6; - --hd-primary-600: #2563eb; - --hd-primary-700: #1d4ed8; - --hd-primary-800: #1e40af; - --hd-primary-900: #1e3a8a; - - --hd-surface: #ffffff; - --hd-surface-muted: #f8fafc; - --hd-border: #e2e8f0; - --hd-text: #0f172a; - --hd-text-muted: #64748b; -} - -.dark { - --hd-surface: #18181b; - --hd-surface-muted: #27272a; - --hd-border: #3f3f46; - --hd-text: #f4f4f5; - --hd-text-muted: #a1a1aa; -} - -.hd-helpdesk-surface { - color: var(--hd-text); -} - -.hd-helpdesk-surface a:not([data-flux-button]) { - color: var(--hd-primary-600); -} - -.dark .hd-helpdesk-surface a:not([data-flux-button]) { - color: var(--hd-primary-400); -} - -/* Shared cards/panels */ -.hd-card, -.hd-panel { - border: 1px solid var(--hd-border); - background: var(--hd-surface); - border-radius: 0.875rem; -} - -.hd-card-header, -.hd-panel-header { - border-bottom: 1px solid var(--hd-border); - background: var(--hd-surface-muted); -} - -/* Shared Helpdesk buttons where plain HTML buttons are used. */ -.hd-button-primary { +.hd-helpdesk-surface .hd-btn, +.hd-btn { display: inline-flex; align-items: center; justify-content: center; - gap: 0.5rem; - border-radius: 0.5rem; - background: var(--hd-primary-600); - color: #fff; - font-weight: 600; - padding: 0.55rem 0.9rem; - transition: background-color .15s ease, box-shadow .15s ease; + gap: .5rem; + border-radius: .85rem; + padding: .62rem 1.05rem; + font-size: .875rem; + line-height: 1.25rem; + font-weight: 800; + color: #ffffff !important; + text-decoration: none !important; + border: 1px solid rgba(255,255,255,.14); + box-shadow: 0 12px 28px rgba(0,0,0,.22); + transition: background-color .15s ease, transform .15s ease, box-shadow .15s ease; +} +.hd-helpdesk-surface .hd-btn:hover, +.hd-btn:hover { + transform: translateY(-1px); + box-shadow: 0 16px 34px rgba(0,0,0,.30); +} +.hd-helpdesk-surface .hd-btn-sm, +.hd-btn-sm { + border-radius: .65rem; + padding: .42rem .78rem; + font-size: .8125rem; +} +.hd-helpdesk-surface .hd-btn-blue, +.hd-btn-blue { background: #2563eb !important; } +.hd-helpdesk-surface .hd-btn-blue:hover, +.hd-btn-blue:hover { background: #1d4ed8 !important; } +.hd-helpdesk-surface .hd-btn-green, +.hd-btn-green { background: #16a34a !important; } +.hd-helpdesk-surface .hd-btn-green:hover, +.hd-btn-green:hover { background: #15803d !important; } +.hd-helpdesk-surface .hd-btn-amber, +.hd-btn-amber { background: #f59e0b !important; } +.hd-helpdesk-surface .hd-btn-amber:hover, +.hd-btn-amber:hover { background: #d97706 !important; } +.hd-helpdesk-surface .hd-btn-red, +.hd-btn-red { background: #dc2626 !important; } +.hd-helpdesk-surface .hd-btn-red:hover, +.hd-btn-red:hover { background: #b91c1c !important; } +.hd-helpdesk-surface .hd-btn-violet, +.hd-btn-violet { background: #7c3aed !important; } +.hd-helpdesk-surface .hd-btn-violet:hover, +.hd-btn-violet:hover { background: #6d28d9 !important; } + +.hd-helpdesk-surface button[type="submit"], +.hd-helpdesk-surface button[data-flux-button][type="submit"] { + background: #16a34a !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="reset"], +.hd-helpdesk-surface button[wire\:target^="reset"] { + background: #f59e0b !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="edit"], +.hd-helpdesk-surface button[wire\:target^="edit"] { + background: #2563eb !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="delete"], +.hd-helpdesk-surface button[wire\:target^="delete"] { + background: #dc2626 !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; } -.hd-button-primary:hover { - background: var(--hd-primary-700); -} - -.hd-button-primary:focus-visible { - outline: 2px solid var(--hd-primary-400); - outline-offset: 2px; -} - -/* Fields */ -.hd-select, -.hd-input, -.hd-textarea { +.hd-select { width: 100%; - border: 1px solid var(--hd-border); - background: var(--hd-surface); - color: var(--hd-text); - border-radius: 0.5rem; + min-height: 3.35rem; + border-radius: 1rem; + border: 1px solid #3f3f46 !important; + background: #09090b !important; + color: #f4f4f5 !important; + padding: .78rem 3rem .78rem 1rem; + font-weight: 800; + outline: none; + box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 12px 26px rgba(0,0,0,.24); +} +.hd-select:focus { + border-color: #60a5fa !important; + box-shadow: 0 0 0 3px rgba(96,165,250,.38), inset 0 1px 0 rgba(255,255,255,.05); } -.hd-select:focus, -.hd-input:focus, -.hd-textarea:focus { - border-color: var(--hd-primary-500); - outline: 2px solid color-mix(in srgb, var(--hd-primary-500) 25%, transparent); - outline-offset: 1px; +.helpdesk-ticket-form, +.helpdesk-ticket-form * { + -webkit-tap-highlight-color: transparent; +} +.helpdesk-ticket-form input, +.helpdesk-ticket-form textarea, +.helpdesk-ticket-form select, +.helpdesk-ticket-form .select2-container--default .select2-selection--single, +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple, +.helpdesk-ticket-form .select2-container--default .select2-selection__rendered, +.helpdesk-ticket-form .select2-container--default .select2-selection__choice { + background: #09090b !important; + background-color: #09090b !important; + color: #f4f4f5 !important; + border-color: #3f3f46 !important; + caret-color: #f4f4f5 !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:disabled, +.helpdesk-ticket-form textarea:disabled, +.helpdesk-ticket-form select:disabled, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--single, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--multiple, +.helpdesk-ticket-form [disabled], +.helpdesk-ticket-form [aria-disabled="true"] { + background: #09090b !important; + background-color: #09090b !important; + color: #a1a1aa !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:-webkit-autofill, +.helpdesk-ticket-form input:-webkit-autofill:hover, +.helpdesk-ticket-form input:-webkit-autofill:focus, +.helpdesk-ticket-form textarea:-webkit-autofill, +.helpdesk-ticket-form textarea:-webkit-autofill:hover, +.helpdesk-ticket-form textarea:-webkit-autofill:focus, +.helpdesk-ticket-form select:-webkit-autofill, +.helpdesk-ticket-form select:-webkit-autofill:hover, +.helpdesk-ticket-form select:-webkit-autofill:focus { + -webkit-text-fill-color: #f4f4f5 !important; + box-shadow: 0 0 0 1000px #09090b inset !important; + transition: background-color 9999s ease-in-out 0s; } -/* Status/accent helpers */ -.hd-accent { - color: var(--hd-primary-600); -} - -.dark .hd-accent { - color: var(--hd-primary-400); -} - -.hd-accent-bg { - background: var(--hd-primary-600); - color: #fff; -} - -.hd-accent-soft { - background: var(--hd-primary-50); - color: var(--hd-primary-800); - border-color: var(--hd-primary-200); -} - -.dark .hd-accent-soft { - background: color-mix(in srgb, var(--hd-primary-900) 55%, transparent); - color: var(--hd-primary-200); - border-color: var(--hd-primary-800); -} - -/* - * Flux sidebar active state. - * Flux currently exposes current state using aria-current on the rendered link. - */ -.hd-sidebar a[aria-current="page"] { - background: var(--hd-primary-600) !important; +.hd-helpdesk-surface .hd-btn, +.hd-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: .5rem; + border-radius: .85rem; + padding: .62rem 1.05rem; + font-size: .875rem; + line-height: 1.25rem; + font-weight: 800; color: #fff !important; + text-decoration: none !important; + border: 1px solid rgba(255,255,255,.14); + box-shadow: 0 12px 28px rgba(0,0,0,.22); + transition: background-color .15s ease, transform .15s ease, box-shadow .15s ease; } -.hd-sidebar a[aria-current="page"] svg { +.hd-helpdesk-surface .hd-btn:hover, +.hd-btn:hover { + transform: translateY(-1px); + box-shadow: 0 16px 34px rgba(0,0,0,.30); +} + +.hd-btn-sm { + border-radius: .65rem; + padding: .42rem .78rem; + font-size: .8125rem; +} + +.hd-btn-blue { background: #2563eb !important; } +.hd-btn-blue:hover { background: #1d4ed8 !important; } + +.hd-btn-green { background: #16a34a !important; } +.hd-btn-green:hover { background: #15803d !important; } + +.hd-btn-amber { background: #f59e0b !important; } +.hd-btn-amber:hover { background: #d97706 !important; } + +.hd-btn-red { background: #dc2626 !important; } +.hd-btn-red:hover { background: #b91c1c !important; } + +.hd-btn-violet { background: #7c3aed !important; } +.hd-btn-violet:hover { background: #6d28d9 !important; } + +.hd-helpdesk-surface button[type="submit"], +.hd-helpdesk-surface button[data-flux-button][type="submit"] { + background: #16a34a !important; color: #fff !important; + border-color: rgba(255,255,255,.14) !important; } -.hd-sidebar a:not([aria-current="page"]):hover { - background: var(--hd-primary-50); - color: var(--hd-primary-800); +.hd-helpdesk-surface button[wire\:click^="reset"], +.hd-helpdesk-surface button[wire\:target^="reset"] { + background: #f59e0b !important; + color: #fff !important; + border-color: rgba(255,255,255,.14) !important; } -.dark .hd-sidebar a:not([aria-current="page"]):hover { - background: color-mix(in srgb, var(--hd-primary-900) 30%, transparent); - color: var(--hd-primary-200); +.hd-helpdesk-surface button[wire\:click^="edit"], +.hd-helpdesk-surface button[wire\:target^="edit"] { + background: #2563eb !important; + color: #fff !important; + border-color: rgba(255,255,255,.14) !important; +} + +.hd-helpdesk-surface button[wire\:click^="delete"], +.hd-helpdesk-surface button[wire\:target^="delete"] { + background: #dc2626 !important; + color: #fff !important; + border-color: rgba(255,255,255,.14) !important; +} + +.hd-select { + width: 100%; + min-height: 3.35rem; + border-radius: 1rem; + border: 1px solid #3f3f46 !important; + background: #09090b !important; + color: #f4f4f5 !important; + padding: .78rem 3rem .78rem 1rem; + font-weight: 800; + outline: none; + box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 12px 26px rgba(0,0,0,.24); +} + +.hd-select:focus { + border-color: #60a5fa !important; + box-shadow: + 0 0 0 3px rgba(96,165,250,.38), + inset 0 1px 0 rgba(255,255,255,.05); +} + +.helpdesk-required-star { + color: #ef4444 !important; + font-weight: 800; +} + +.helpdesk-ticket-form, +.helpdesk-ticket-form * { + -webkit-tap-highlight-color: transparent; +} + +.helpdesk-ticket-form input, +.helpdesk-ticket-form textarea, +.helpdesk-ticket-form select, +.helpdesk-ticket-form .select2-container--default .select2-selection--single, +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple, +.helpdesk-ticket-form .select2-container--default .select2-selection__rendered, +.helpdesk-ticket-form .select2-container--default .select2-selection__choice { + background: #09090b !important; + color: #f4f4f5 !important; + border-color: #3f3f46 !important; + caret-color: #f4f4f5 !important; + opacity: 1 !important; +} + +.helpdesk-ticket-form input:disabled, +.helpdesk-ticket-form textarea:disabled, +.helpdesk-ticket-form select:disabled, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--single, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--multiple { + background: #09090b !important; + color: #a1a1aa !important; + opacity: 1 !important; +} + +.helpdesk-ticket-form input:-webkit-autofill, +.helpdesk-ticket-form input:-webkit-autofill:hover, +.helpdesk-ticket-form input:-webkit-autofill:focus, +.helpdesk-ticket-form textarea:-webkit-autofill, +.helpdesk-ticket-form textarea:-webkit-autofill:hover, +.helpdesk-ticket-form textarea:-webkit-autofill:focus, +.helpdesk-ticket-form select:-webkit-autofill, +.helpdesk-ticket-form select:-webkit-autofill:hover, +.helpdesk-ticket-form select:-webkit-autofill:focus { + -webkit-text-fill-color: #f4f4f5 !important; + box-shadow: 0 0 0 1000px #09090b inset !important; + transition: background-color 9999s ease-in-out 0s; +} + +.select2-container--default .select2-selection--single { + position: relative; +} + +.select2-container--default .select2-selection--single .select2-selection__clear { + position: absolute !important; + top: 50% !important; + right: 2.25rem !important; + transform: translateY(-50%); + color: #f87171 !important; + font-weight: 800 !important; + z-index: 5; +} + +/* Select2 base */ +.helpdesk-ticket-form .select2-container { + width: 100% !important; +} + +.helpdesk-ticket-form .select2-container--default .select2-selection--single, +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple { + min-height: 3.35rem; + border-radius: 1rem; + border: 1px solid #d4d4d8 !important; + background: #ffffff !important; + color: #18181b !important; + box-shadow: 0 10px 22px rgba(24, 24, 27, .08); +} + +.helpdesk-ticket-form .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #18181b !important; + line-height: 3.25rem; + padding-left: 1rem; + padding-right: 2.75rem; + font-weight: 700; +} + +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple { + align-items: center; + padding: .4rem .65rem; +} + +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple .select2-selection__choice { + border: 1px solid #2563eb !important; + border-radius: 9999px !important; + background: #dbeafe !important; + color: #1e3a8a !important; + font-weight: 700; + padding: .2rem .55rem; +} + +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: #dc2626 !important; + margin-right: .35rem; +} + +.select2-dropdown { + border: 1px solid #d4d4d8 !important; + border-radius: .9rem !important; + background: #ffffff !important; + color: #18181b !important; + overflow: hidden; + box-shadow: 0 18px 42px rgba(24, 24, 27, .18); +} + +.select2-search__field { + border: 1px solid #d4d4d8 !important; + border-radius: .7rem !important; + background: #ffffff !important; + color: #18181b !important; +} + +.select2-container--default .select2-results__option { + color: #18181b !important; +} + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background: #2563eb !important; + color: #ffffff !important; +} + +.select2-container--default .select2-results__option[aria-selected="true"] { + background: #e0f2fe !important; + color: #075985 !important; +} + +/* Dark mode */ +.dark .helpdesk-ticket-form .select2-container--default .select2-selection--single, +.dark .helpdesk-ticket-form .select2-container--default .select2-selection--multiple { + border-color: #3f3f46 !important; + background: #09090b !important; + color: #f4f4f5 !important; + box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 12px 26px rgba(0,0,0,.24); +} + +.dark .helpdesk-ticket-form .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #f4f4f5 !important; +} + +.dark .helpdesk-ticket-form .select2-container--default .select2-selection--multiple .select2-selection__choice { + border-color: #60a5fa !important; + background: #1d4ed8 !important; + color: #ffffff !important; +} + +.dark .select2-dropdown { + border-color: #3f3f46 !important; + background: #18181b !important; + color: #f4f4f5 !important; + box-shadow: 0 18px 42px rgba(0,0,0,.55); +} + +.dark .select2-search__field { + border-color: #3f3f46 !important; + background: #09090b !important; + color: #f4f4f5 !important; +} + +.dark .select2-container--default .select2-results__option { + color: #f4f4f5 !important; +} + +.dark .select2-container--default .select2-results__option--highlighted[aria-selected] { + background: #2563eb !important; + color: #ffffff !important; +} + +.dark .select2-container--default .select2-results__option[aria-selected="true"] { + background: #27272a !important; + color: #ffffff !important; +} + +.select2-container--default .select2-results__option { + background: rgb(9 9 11); + color: rgb(244 244 245); +} + +.select2-container--default .select2-results__option--highlighted[aria-selected], +.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable { + background: rgb(37 99 235) !important; + color: rgb(255 255 255) !important; +} + +.select2-container--default .select2-results__option[aria-selected="true"], +.select2-container--default .select2-results__option--selected { + background: rgb(30 64 175) !important; + color: rgb(255 255 255) !important; +} + +.select2-dropdown { + border-color: rgb(63 63 70) !important; + background: rgb(9 9 11) !important; +} + +.select2-container--default .select2-selection--single { + border: 1px solid rgb(63 63 70) !important; + background: rgb(9 9 11) !important; +} + +.select2-container--default .select2-selection--single .select2-selection__rendered { + color: rgb(244 244 245) !important; +} + +.select2-container--default .select2-selection--single .select2-selection__placeholder { + color: rgb(113 113 122) !important; +} + +.select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: rgb(161 161 170) transparent transparent transparent !important; +} + +.select2-container--default.select2-container--open .select2-selection--single { + border-color: rgb(59 130 246) !important; + box-shadow: 0 0 0 2px rgb(59 130 246 / 0.35); +} + +.select2-container--default .select2-selection--multiple { + border: 1px solid rgb(63 63 70) !important; + background: rgb(9 9 11) !important; +} + +.select2-container--default .select2-selection--multiple .select2-selection__choice { + border: 1px solid rgb(59 130 246 / 0.45) !important; + background: rgb(30 64 175 / 0.35) !important; + color: rgb(219 234 254) !important; +} + +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: rgb(191 219 254) !important; +} + +.select2-container--default .select2-selection--single, +.select2-container--default .select2-selection--multiple { + border-radius: 0.75rem !important; +} + +.select2-dropdown { + overflow: hidden; + border-radius: 0.75rem !important; +} + +.select2-container--open .select2-dropdown--below { + margin-top: 0.35rem; + border-radius: 0.75rem !important; +} + +.select2-container--open .select2-dropdown--above { + margin-bottom: 0.35rem; + border-radius: 0.75rem !important; +} + +.select2-container--default .select2-selection--single { + position: relative; + padding-right: 3.5rem; +} + +.select2-container--default .select2-selection--single .select2-selection__rendered { + padding-right: 3.5rem; +} + +.select2-container--default .select2-selection--single .select2-selection__clear { + position: absolute; + right: 2rem; + top: 50%; + z-index: 3; + margin: 0; + transform: translateY(-50%); + color: rgb(161 161 170); + font-size: 1rem; + line-height: 1; +} + +.select2-container--default .select2-selection--single .select2-selection__clear:hover { + color: rgb(248 113 113); +} + +.select2-container--default .select2-selection--single .select2-selection__arrow { + right: 0.75rem; +} + +.select2-container--default .select2-selection--single { + position: relative !important; +} + +.select2-container--default .select2-selection--single .select2-selection__rendered { + padding-left: 0.75rem !important; + padding-right: 4.25rem !important; +} + +.select2-container--default .select2-selection--single .select2-selection__clear { + position: absolute !important; + right: 2.35rem !important; + top: 50% !important; + float: none !important; + margin: 0 !important; + transform: translateY(-50%) !important; +} + +.select2-container--default .select2-selection--single .select2-selection__clear span { + color: rgb(161 161 170) !important; + font-size: 1.1rem !important; + line-height: 1 !important; +} + +.select2-container--default .select2-selection--single .select2-selection__arrow { + right: 0.75rem !important; +} + +.select2-container--default .select2-selection--single { + display: flex !important; + align-items: center !important; + position: relative !important; +} + +.select2-container--default .select2-selection--single .select2-selection__rendered { + flex: 1 1 auto !important; + width: 100% !important; + padding-right: 4.5rem !important; +} + +.select2-container--default .select2-selection--single .select2-selection__clear { + position: absolute !important; + right: 2.25rem !important; + top: 50% !important; + z-index: 20 !important; + display: inline-flex !important; + align-items: center !important; + justify-content: center !important; + width: 1.25rem !important; + height: 1.25rem !important; + float: none !important; + margin: 0 !important; + padding: 0 !important; + transform: translateY(-50%) !important; + color: rgb(161 161 170) !important; + cursor: pointer !important; +} + +.select2-container--default .select2-selection--single .select2-selection__clear:hover { + color: rgb(248 113 113) !important; +} + +.select2-container--default .select2-selection--single .select2-selection__arrow { + position: absolute !important; + right: 0.75rem !important; + top: 50% !important; + transform: translateY(-50%) !important; +} + +/* Helpdesk Flatpickr date picker */ +.flatpickr-calendar { + border: 1px solid rgb(63 63 70); + background: rgb(24 24 27); + color: rgb(244 244 245); + box-shadow: 0 20px 45px rgb(0 0 0 / 0.35); +} + +.flatpickr-calendar.arrowTop::before, +.flatpickr-calendar.arrowTop::after, +.flatpickr-calendar.arrowBottom::before, +.flatpickr-calendar.arrowBottom::after { + border-bottom-color: rgb(24 24 27); + border-top-color: rgb(24 24 27); +} + +.flatpickr-months, +.flatpickr-months .flatpickr-month, +.flatpickr-current-month .flatpickr-monthDropdown-months, +.flatpickr-current-month input.cur-year { + background: rgb(24 24 27); + color: rgb(244 244 245); +} + +.flatpickr-weekday, +span.flatpickr-weekday { + color: rgb(161 161 170); +} + +.flatpickr-day { + color: rgb(228 228 231); +} + +.flatpickr-day:hover, +.flatpickr-day:focus { + border-color: rgb(59 130 246); + background: rgb(39 39 42); + color: rgb(255 255 255); +} + +.flatpickr-day.selected, +.flatpickr-day.startRange, +.flatpickr-day.endRange { + border-color: rgb(37 99 235); + background: rgb(37 99 235); + color: rgb(255 255 255); +} + +.flatpickr-day.today { + border-color: rgb(34 197 94); +} + +.flatpickr-day.flatpickr-disabled, +.flatpickr-day.prevMonthDay, +.flatpickr-day.nextMonthDay { + color: rgb(113 113 122); +} +.hd-helpdesk-surface .hd-btn, +.hd-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: .5rem; + border-radius: .85rem; + padding: .62rem 1.05rem; + font-size: .875rem; + line-height: 1.25rem; + font-weight: 800; + font-size: .95rem; + color: #ffffff !important; + text-decoration: none !important; + border: 1px solid rgba(255,255,255,.14); + box-shadow: 0 12px 28px rgba(0,0,0,.22); + transition: background-color .15s ease, transform .15s ease, box-shadow .15s ease; +} +.hd-helpdesk-surface .hd-btn:hover, +.hd-btn:hover { + transform: translateY(-1px); + box-shadow: 0 16px 34px rgba(0,0,0,.30); +} +.hd-helpdesk-surface .hd-btn-sm, +.hd-btn-sm { + border-radius: .65rem; + padding: .42rem .78rem; + font-size: .8125rem; +} +.hd-helpdesk-surface .hd-btn-blue, +.hd-btn-blue { background: #2563eb !important; } +.hd-helpdesk-surface .hd-btn-blue:hover, +.hd-btn-blue:hover { background: #1d4ed8 !important; } +.hd-helpdesk-surface .hd-btn-green, +.hd-btn-green { background: #16a34a !important; } +.hd-helpdesk-surface .hd-btn-green:hover, +.hd-btn-green:hover { background: #15803d !important; } +.hd-helpdesk-surface .hd-btn-amber, +.hd-btn-amber { background: #f59e0b !important; } +.hd-helpdesk-surface .hd-btn-amber:hover, +.hd-btn-amber:hover { background: #d97706 !important; } +.hd-helpdesk-surface .hd-btn-red, +.hd-btn-red { background: #dc2626 !important; } +.hd-helpdesk-surface .hd-btn-red:hover, +.hd-btn-red:hover { background: #b91c1c !important; } +.hd-helpdesk-surface .hd-btn-violet, +.hd-btn-violet { background: #7c3aed !important; } +.hd-helpdesk-surface .hd-btn-violet:hover, +.hd-btn-violet:hover { background: #6d28d9 !important; } + +.hd-helpdesk-surface button[type="submit"], +.hd-helpdesk-surface button[data-flux-button][type="submit"] { + background: #16a34a !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="reset"], +.hd-helpdesk-surface button[wire\:target^="reset"] { + background: #f59e0b !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="edit"], +.hd-helpdesk-surface button[wire\:target^="edit"] { + background: #2563eb !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="delete"], +.hd-helpdesk-surface button[wire\:target^="delete"] { + background: #dc2626 !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} + +.hd-select-wrap { + position: relative; + width: 100%; + max-width: 18rem; +} +.hd-select-wrap::after { + position: absolute; + top: 50%; + right: 1rem; + width: .55rem; + height: .55rem; + content: ""; + pointer-events: none; + border-right: 2px solid #93c5fd; + border-bottom: 2px solid #93c5fd; + transform: translateY(-65%) rotate(45deg); +} +.hd-select { + width: 100%; + min-height: 2.75rem; + appearance: none; + -webkit-appearance: none; + border-radius: .9rem; + border: 1px solid rgba(96, 165, 250, .38) !important; + background: linear-gradient(135deg, #030712 0%, #111827 54%, #0f172a 100%) !important; + color: #f8fafc !important; + padding: .62rem 2.45rem .62rem .9rem; + font-weight: 800; + outline: none; + box-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 14px 30px rgba(2,6,23,.38); +} +.hd-select option { + background: #020617 !important; + color: #f8fafc !important; +} +.hd-select:focus { + border-color: #60a5fa !important; + box-shadow: 0 0 0 3px rgba(96,165,250,.38), inset 0 1px 0 rgba(255,255,255,.08), 0 14px 30px rgba(2,6,23,.38); +} +.hd-ticket-board-select-wrap { + position: relative; + max-width: 12.5rem; +} +.hd-ticket-board-select-wrap::after { + position: absolute; + top: 50%; + right: .7rem; + width: .45rem; + height: .45rem; + content: ""; + pointer-events: none; + border-right: 2px solid #86efac; + border-bottom: 2px solid #86efac; + transform: translateY(-65%) rotate(45deg); +} +.hd-ticket-board-select { + width: 100%; + min-height: 2.35rem; + appearance: none; + -webkit-appearance: none; + border-radius: .85rem; + border: 1px solid rgba(34,197,94,.35) !important; + background: linear-gradient(135deg, #052e16 0%, #064e3b 100%) !important; + color: #ecfdf5 !important; + padding: .48rem 2rem .48rem .75rem; + font-size: .75rem; + font-weight: 800; + outline: none; + box-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 10px 22px rgba(0,0,0,.26); +} +.hd-ticket-board-select option { + background: #052e16 !important; + color: #ecfdf5 !important; +} +.hd-ticket-board-select:focus { + border-color: #86efac !important; + box-shadow: 0 0 0 3px rgba(34,197,94,.28), inset 0 1px 0 rgba(255,255,255,.08); +} + +.helpdesk-ticket-form, +.helpdesk-ticket-form * { + -webkit-tap-highlight-color: transparent; +} +.helpdesk-ticket-form input, +.helpdesk-ticket-form textarea, +.helpdesk-ticket-form select, +.helpdesk-ticket-form .select2-container--default .select2-selection--single, +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple, +.helpdesk-ticket-form .select2-container--default .select2-selection__rendered, +.helpdesk-ticket-form .select2-container--default .select2-selection__choice { + background: #09090b !important; + background-color: #09090b !important; + color: #f4f4f5 !important; + border-color: #3f3f46 !important; + caret-color: #f4f4f5 !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:disabled, +.helpdesk-ticket-form textarea:disabled, +.helpdesk-ticket-form select:disabled, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--single, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--multiple, +.helpdesk-ticket-form [disabled], +.helpdesk-ticket-form [aria-disabled="true"] { + background: #09090b !important; + background-color: #09090b !important; + color: #a1a1aa !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:-webkit-autofill, +.helpdesk-ticket-form input:-webkit-autofill:hover, +.helpdesk-ticket-form input:-webkit-autofill:focus, +.helpdesk-ticket-form textarea:-webkit-autofill, +.helpdesk-ticket-form textarea:-webkit-autofill:hover, +.helpdesk-ticket-form textarea:-webkit-autofill:focus, +.helpdesk-ticket-form select:-webkit-autofill, +.helpdesk-ticket-form select:-webkit-autofill:hover, +.helpdesk-ticket-form select:-webkit-autofill:focus { + -webkit-text-fill-color: #f4f4f5 !important; + box-shadow: 0 0 0 1000px #09090b inset !important; + transition: background-color 9999s ease-in-out 0s; +} + +.hd-helpdesk-surface .hd-btn, +.hd-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: .5rem; + border-radius: .85rem; + padding: .62rem 1.05rem; + font-size: .875rem; + line-height: 1.25rem; + font-weight: 800; + color: #ffffff !important; + text-decoration: none !important; + border: 1px solid rgba(255,255,255,.14); + box-shadow: 0 12px 28px rgba(0,0,0,.22); + transition: background-color .15s ease, transform .15s ease, box-shadow .15s ease; +} +.hd-helpdesk-surface .hd-btn:hover, +.hd-btn:hover { + transform: translateY(-1px); + box-shadow: 0 16px 34px rgba(0,0,0,.30); +} +.hd-helpdesk-surface .hd-btn-sm, +.hd-btn-sm { + border-radius: .65rem; + padding: .42rem .78rem; + font-size: .8125rem; +} +.hd-helpdesk-surface .hd-btn-blue, +.hd-btn-blue { background: #2563eb !important; } +.hd-helpdesk-surface .hd-btn-blue:hover, +.hd-btn-blue:hover { background: #1d4ed8 !important; } +.hd-helpdesk-surface .hd-btn-green, +.hd-btn-green { background: #16a34a !important; } +.hd-helpdesk-surface .hd-btn-green:hover, +.hd-btn-green:hover { background: #15803d !important; } +.hd-helpdesk-surface .hd-btn-amber, +.hd-btn-amber { background: #f59e0b !important; } +.hd-helpdesk-surface .hd-btn-amber:hover, +.hd-btn-amber:hover { background: #d97706 !important; } +.hd-helpdesk-surface .hd-btn-red, +.hd-btn-red { background: #dc2626 !important; } +.hd-helpdesk-surface .hd-btn-red:hover, +.hd-btn-red:hover { background: #b91c1c !important; } +.hd-helpdesk-surface .hd-btn-violet, +.hd-btn-violet { background: #7c3aed !important; } +.hd-helpdesk-surface .hd-btn-violet:hover, +.hd-btn-violet:hover { background: #6d28d9 !important; } + +.hd-helpdesk-surface button[type="submit"], +.hd-helpdesk-surface button[data-flux-button][type="submit"] { + background: #16a34a !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="reset"], +.hd-helpdesk-surface button[wire\:target^="reset"] { + background: #f59e0b !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="edit"], +.hd-helpdesk-surface button[wire\:target^="edit"] { + background: #2563eb !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} +.hd-helpdesk-surface button[wire\:click^="delete"], +.hd-helpdesk-surface button[wire\:target^="delete"] { + background: #dc2626 !important; + color: #ffffff !important; + border-color: rgba(255,255,255,.14) !important; +} + +.hd-select { + width: 100%; + min-height: 3.35rem; + border-radius: 1rem; + border: 1px solid #3f3f46 !important; + background: #09090b !important; + color: #f4f4f5 !important; + padding: .78rem 3rem .78rem 1rem; + font-weight: 800; + outline: none; + box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 12px 26px rgba(0,0,0,.24); +} +.hd-select:focus { + border-color: #60a5fa !important; + box-shadow: 0 0 0 3px rgba(96,165,250,.38), inset 0 1px 0 rgba(255,255,255,.05); +} + +.helpdesk-ticket-form, +.helpdesk-ticket-form * { + -webkit-tap-highlight-color: transparent; +} +.helpdesk-ticket-form input, +.helpdesk-ticket-form textarea, +.helpdesk-ticket-form select, +.helpdesk-ticket-form .select2-container--default .select2-selection--single, +.helpdesk-ticket-form .select2-container--default .select2-selection--multiple, +.helpdesk-ticket-form .select2-container--default .select2-selection__rendered, +.helpdesk-ticket-form .select2-container--default .select2-selection__choice { + background: #09090b !important; + background-color: #09090b !important; + color: #f4f4f5 !important; + border-color: #3f3f46 !important; + caret-color: #f4f4f5 !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:disabled, +.helpdesk-ticket-form textarea:disabled, +.helpdesk-ticket-form select:disabled, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--single, +.helpdesk-ticket-form .select2-container--disabled .select2-selection--multiple, +.helpdesk-ticket-form [disabled], +.helpdesk-ticket-form [aria-disabled="true"] { + background: #09090b !important; + background-color: #09090b !important; + color: #a1a1aa !important; + opacity: 1 !important; +} +.helpdesk-ticket-form input:-webkit-autofill, +.helpdesk-ticket-form input:-webkit-autofill:hover, +.helpdesk-ticket-form input:-webkit-autofill:focus, +.helpdesk-ticket-form textarea:-webkit-autofill, +.helpdesk-ticket-form textarea:-webkit-autofill:hover, +.helpdesk-ticket-form textarea:-webkit-autofill:focus, +.helpdesk-ticket-form select:-webkit-autofill, +.helpdesk-ticket-form select:-webkit-autofill:hover, +.helpdesk-ticket-form select:-webkit-autofill:focus { + -webkit-text-fill-color: #f4f4f5 !important; + box-shadow: 0 0 0 1000px #09090b inset !important; + transition: background-color 9999s ease-in-out 0s; } diff --git a/resources/themes/backend/views/layouts/app/sidebar.blade.php b/resources/themes/backend/views/layouts/app/sidebar.blade.php index 2d4e78a..33424a2 100644 --- a/resources/themes/backend/views/layouts/app/sidebar.blade.php +++ b/resources/themes/backend/views/layouts/app/sidebar.blade.php @@ -1,184 +1,223 @@ - - @include('partials.head') - + + @include('partials.head') + - - - - + + @php + /* + * Match the Core WMS support navigation strategy: + * detect routes rather than hiding navigation behind role checks. + */ + $helpdeskEnabled = Route::has('helpdesk.index') || Route::has('helpdesk.tickets.index'); - - + $helpdeskSettingsRoute = Route::has('helpdesk.settings') + ? 'helpdesk.settings' + : (Route::has('helpdesk.settings.index') + ? 'helpdesk.settings.index' + : null); - - - - {{ __('Dashboard') }} - - + $helpdeskActive = request()->routeIs('helpdesk.*'); + @endphp - - - {{ __('Tickets') }} - - - - {{ __('Kanban') }} - - - - {{ __('Support') }} - - - @if (auth()->user()->isHelpdeskAdmin()) - + + - {{ __('Settings') }} - - @endif - - + /> - + + - - - - - - - - - - - - -
-
- - -
- - {{ auth()->user()->name }} - - - - {{ auth()->user()->email }} - -
-
-
-
- - - - - - {{ __('Support') }} - - - @if (auth()->user()->isHelpdeskAdmin()) - + + - {{ __('Helpdesk Settings') }} - + {{ __('Dashboard') }} + + + + @if ($helpdeskEnabled) +
+ {{-- Core WMS uses Support as the selected parent group. --}} + @if (Route::has('helpdesk.index')) + + {{ __('Support') }} + + @else +
+ {{ __('Support') }} +
+ @endif + +
+ @if (Route::has('helpdesk.tickets.index')) + + {{ __('Tickets') }} + + @endif + + @if (Route::has('helpdesk.kanban')) + + {{ __('Kanban') }} + + @endif + + @if ($helpdeskSettingsRoute) + + {{ __('Settings') }} + + @endif +
+
@endif + - - {{ __('Profile Settings') }} - -
+ - +
-
-
+ -{{ $slot }} + + -@persist('toast') - - - -@endpersist + + +
+
+ -@fluxScripts - +
+ + {{ auth()->user()->name }} + + + + {{ auth()->user()->email }} + +
+
+
+
+ + + + + @if (Route::has('helpdesk.index')) + + {{ __('Support') }} + + @endif + + @if ($helpdeskSettingsRoute) + + {{ __('Helpdesk Settings') }} + + @endif + + @if (Route::has('profile.edit')) + + {{ __('Profile') }} + + @endif + + + + +
+ @csrf + + + {{ __('Log out') }} + +
+
+
+ + + {{ $slot }} + + @persist('toast') + + + + @endpersist + + @fluxScripts + diff --git a/resources/themes/backend/views/modules/helpdesk/livewire/kanban-board.blade.php b/resources/themes/backend/views/modules/helpdesk/livewire/kanban-board.blade.php index 6bffddd..d0ffb14 100644 --- a/resources/themes/backend/views/modules/helpdesk/livewire/kanban-board.blade.php +++ b/resources/themes/backend/views/modules/helpdesk/livewire/kanban-board.blade.php @@ -1,172 +1,347 @@ -
-
-
- {{ __('Helpdesk Kanban') }} - - {{ __('Move tickets through the workflow for the selected board.') }} - -
- -
- @if ($boards->isNotEmpty()) -
- - @foreach ($boards as $boardOption) - - @endforeach - +
+
+
+
+
+

Helpdesk workflow

+

Kanban board

+

Drag tickets between board columns. Boards and + columns are configured in Helpdesk Settings.

- @endif - - {{ __('Ticket list') }} - + +
- - @if (session('success')) -
- {{ session('success') }} -
- @endif - - @if ($board === null) -
- {{ __('No Kanban board configured') }} - - {{ __('Create a board in Helpdesk settings before using Kanban.') }} - - - - {{ __('Open settings') }} - + @if ($boards->isEmpty()) +
+ No Kanban boards exist yet. Open Helpdesk Settings and create a board with at least one status column.
@else -
- @foreach ($statuses as $status) - @php - $statusTickets = collect($ticketsByStatus[$status->id] ?? []); - @endphp +
+
+

Active board: {{ $board?->name ?? 'None' }}

+

+ {{ $board?->description ?: 'Use settings to configure which statuses appear as draggable columns.' }} +

+ @if ($board?->owner) +

Owner: + {{ $board->owner->name }}

+ @endif +
-
+ - - - @foreach ($statuses as $targetStatus) - @if ($targetStatus->id !== $status->id) - - @endif - @endforeach - -
- @endcan - - @empty -
- {{ __('No tickets') }} -
- @endforelse -
- - @endforeach + @foreach ($boards as $availableBoard) + + @endforeach + +
+ + @if ($statuses->isEmpty()) +
+ This board is being initialised with the default workflow statuses. Refresh the page if the columns do + not appear immediately. +
+ @else +
+ @foreach ($statuses as $status) + @php($tickets = $ticketsByStatus[$status->id] ?? collect()) + +
+
+
+
+

+ {{ $status->name }}

+

{{ $tickets->count() }} + tickets

+
+ +
+
+ +
+ @forelse ($tickets as $ticket) +
+
+
+
+ {{ $ticket->reference }}
+

+ {{ $ticket->subject }}

+
+ + @if ($ticket->priority) + + {{ $ticket->priority->name }} + + @endif +
+ +
+
{{ $ticket->owner?->name ?? 'Unknown' }}
+
{{ $ticket->agent?->name ?? 'Unassigned' }} +
+ @if ($ticket->project) +
+ {{ $ticket->project->title }}
+ @endif + @if ($ticket->team) +
{{ $ticket->team->name }}
+ @endif + @if ($ticket->product) +
{{ $ticket->product->name }}
+ @endif +
+ + +
+ @csrf + + +
+ +
+
+ @if ($ticket->tags->isNotEmpty()) +
+ @foreach ($ticket->tags as $tag) + {{ $tag->name }} + @endforeach +
+ @endif + + @if ($ticket->checklistItems->isNotEmpty()) + @php($done = $ticket->checklistItems->where('is_completed', true)->count()) +
Checklist + {{ $done }}/{{ $ticket->checklistItems->count() }}
+ @endif + + @if ($ticket->sla_first_response_breached || $ticket->sla_resolution_breached) +
+ SLA breach
+ @endif + +
+ Open + @can('update', $ticket) + Edit + @endcan +
+
+ @empty +
+ Drop tickets here for {{ $status->name }}. +
+ @endforelse +
+
+ @endforeach +
+ @endif @endif + + @script + + @endscript