M3 Integration fixes
This commit is contained in:
Regular → Executable
Regular → Executable
+8
-7
@@ -17,6 +17,8 @@ use Modules\Helpdesk\Services\WorkflowNotificationService;
|
||||
|
||||
final class KanbanBoard extends Component
|
||||
{
|
||||
private const OWNER_RELATION = self::OWNER_RELATION;
|
||||
|
||||
public ?int $board_id = null;
|
||||
|
||||
public int $refreshNonce = 0;
|
||||
@@ -98,7 +100,7 @@ final class KanbanBoard extends Component
|
||||
public function moveTicketToBoard(int|string $ticketId, int|string|null $boardId, WorkflowNotificationService $workflow): void
|
||||
{
|
||||
$ticket = Ticket::query()->with('board')->visibleTo(Auth::user())->findOrFail((int) $ticketId);
|
||||
$board = KanbanBoardModel::query()->with(['statuses', 'owner:id,name,email'])->findOrFail((int) $boardId);
|
||||
$board = KanbanBoardModel::query()->with(['statuses', self::OWNER_RELATION])->findOrFail((int) $boardId);
|
||||
$oldBoardName = $ticket->board?->name ?? 'No board';
|
||||
|
||||
$this->authorize('update', $ticket);
|
||||
@@ -156,8 +158,7 @@ final class KanbanBoard extends Component
|
||||
*/
|
||||
public function selectBoard(int|string|null $value): void
|
||||
{
|
||||
$this->board_id = is_numeric($value) ? (int) $value : null;
|
||||
$this->refreshBoard();
|
||||
$this->updatedBoardId($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +167,7 @@ final class KanbanBoard extends Component
|
||||
public function render(): View
|
||||
{
|
||||
$boards = KanbanBoardModel::query()
|
||||
->with(['statuses', 'owner:id,name,email'])
|
||||
->with(['statuses', self::OWNER_RELATION])
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
@@ -176,10 +177,10 @@ final class KanbanBoard extends Component
|
||||
|
||||
if ($board instanceof KanbanBoardModel && $board->statuses->isEmpty()) {
|
||||
$this->ensureBoardHasStatuses($board);
|
||||
$board->load(['statuses', 'owner:id,name,email']);
|
||||
$board->load(['statuses', self::OWNER_RELATION]);
|
||||
|
||||
$boards = KanbanBoardModel::query()
|
||||
->with(['statuses', 'owner:id,name,email'])
|
||||
->with(['statuses', self::OWNER_RELATION])
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
@@ -206,7 +207,7 @@ final class KanbanBoard extends Component
|
||||
}
|
||||
|
||||
return Ticket::query()
|
||||
->with(['user:id,name,email', 'owner:id,name,email', 'agent:id,name,email', 'status', 'priority', 'category', 'project', 'team', 'product', 'tags', 'checklistItems', 'board'])
|
||||
->with(['user:id,name,email', self::OWNER_RELATION, 'agent:id,name,email', 'status', 'priority', 'category', 'project', 'team', 'product', 'tags', 'checklistItems', 'board'])
|
||||
->visibleTo(Auth::user())
|
||||
->where('board_id', $board->id)
|
||||
->latest('last_activity_at')
|
||||
|
||||
Regular → Executable
+80
-59
@@ -11,7 +11,6 @@ use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
use Modules\Helpdesk\Models\AutomationRule;
|
||||
@@ -32,6 +31,30 @@ use Modules\Helpdesk\Support\Color;
|
||||
|
||||
final class SettingsManager extends Component
|
||||
{
|
||||
private const RULE_MAX_40 = 'max:40';
|
||||
|
||||
private const RULE_MAX_80 = 'max:80';
|
||||
|
||||
private const RULE_MAX_100 = 'max:100';
|
||||
|
||||
private const RULE_MAX_120 = 'max:120';
|
||||
|
||||
private const RULE_MAX_160 = 'max:160';
|
||||
|
||||
private const RULE_MAX_180 = 'max:180';
|
||||
|
||||
private const RULE_MAX_220 = 'max:220';
|
||||
|
||||
private const RULE_MAX_500 = 'max:500';
|
||||
|
||||
private const RULE_MIN_0 = 'min:0';
|
||||
|
||||
private const RULE_TEAM_EXISTS = 'exists:helpdesk_teams,id';
|
||||
|
||||
private const RULE_PROJECT_EXISTS = 'exists:helpdesk_projects,id';
|
||||
|
||||
private const RULE_CATEGORY_EXISTS = 'exists:helpdesk_categories,id';
|
||||
|
||||
public string $section = 'statuses';
|
||||
|
||||
public int|string|null $default_helpdesk_company_id = null;
|
||||
@@ -127,10 +150,10 @@ final class SettingsManager extends Component
|
||||
public function saveStatus(): void
|
||||
{
|
||||
$data = $this->validate([
|
||||
'statusForm.name' => ['required', 'string', 'max:80'],
|
||||
'statusForm.slug' => ['nullable', 'string', 'max:100'],
|
||||
'statusForm.name' => ['required', 'string', self::RULE_MAX_80],
|
||||
'statusForm.slug' => ['nullable', 'string', self::RULE_MAX_100],
|
||||
'statusForm.color' => ['required', 'string', Color::validationRule()],
|
||||
'statusForm.sort_order' => ['required', 'integer', 'min:0'],
|
||||
'statusForm.sort_order' => ['required', 'integer', self::RULE_MIN_0],
|
||||
'statusForm.is_closed' => ['boolean'],
|
||||
'statusForm.is_default' => ['boolean'],
|
||||
])['statusForm'];
|
||||
@@ -168,10 +191,10 @@ final class SettingsManager extends Component
|
||||
public function savePriority(): void
|
||||
{
|
||||
$data = $this->validate([
|
||||
'priorityForm.name' => ['required', 'string', 'max:80'],
|
||||
'priorityForm.slug' => ['nullable', 'string', 'max:100'],
|
||||
'priorityForm.name' => ['required', 'string', self::RULE_MAX_80],
|
||||
'priorityForm.slug' => ['nullable', 'string', self::RULE_MAX_100],
|
||||
'priorityForm.color' => ['required', 'string', Color::validationRule()],
|
||||
'priorityForm.sort_order' => ['required', 'integer', 'min:0'],
|
||||
'priorityForm.sort_order' => ['required', 'integer', self::RULE_MIN_0],
|
||||
'priorityForm.is_default' => ['boolean'],
|
||||
])['priorityForm'];
|
||||
|
||||
@@ -210,7 +233,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'categoryForm.company_id' => ['nullable', 'integer'],
|
||||
'categoryForm.name' => ['required', 'string', 'max:120'],
|
||||
'categoryForm.name' => ['required', 'string', self::RULE_MAX_120],
|
||||
'categoryForm.slug' => ['nullable', 'string', 'max:140'],
|
||||
'categoryForm.color' => ['required', 'string', Color::validationRule()],
|
||||
'categoryForm.description' => ['nullable', 'string'],
|
||||
@@ -252,7 +275,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'teamForm.company_id' => ['nullable', 'integer'],
|
||||
'teamForm.name' => ['required', 'string', 'max:120'],
|
||||
'teamForm.name' => ['required', 'string', self::RULE_MAX_120],
|
||||
'teamForm.slug' => ['nullable', 'string', 'max:140'],
|
||||
'teamForm.color' => ['required', 'string', Color::validationRule()],
|
||||
'teamForm.description' => ['nullable', 'string'],
|
||||
@@ -294,9 +317,9 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'projectForm.company_id' => ['nullable', 'integer'],
|
||||
'projectForm.team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'],
|
||||
'projectForm.title' => ['required', 'string', 'max:160'],
|
||||
'projectForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'projectForm.team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS],
|
||||
'projectForm.title' => ['required', 'string', self::RULE_MAX_160],
|
||||
'projectForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'projectForm.color' => ['required', 'string', Color::validationRule()],
|
||||
'projectForm.description' => ['nullable', 'string'],
|
||||
'projectForm.is_default' => ['boolean'],
|
||||
@@ -336,12 +359,12 @@ final class SettingsManager extends Component
|
||||
$this->normalizeNullableFormValues('boardForm', ['owner_id']);
|
||||
|
||||
$data = $this->validate([
|
||||
'boardForm.name' => ['required', 'string', 'max:160'],
|
||||
'boardForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'boardForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'boardForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'boardForm.description' => ['nullable', 'string'],
|
||||
'boardForm.owner_id' => ['nullable', 'integer', 'exists:users,id'],
|
||||
'boardForm.is_default' => ['boolean'],
|
||||
'boardForm.sort_order' => ['required', 'integer', 'min:0'],
|
||||
'boardForm.sort_order' => ['required', 'integer', self::RULE_MIN_0],
|
||||
'boardForm.status_ids' => ['array'],
|
||||
'boardForm.status_ids.*' => ['integer', 'exists:helpdesk_statuses,id'],
|
||||
])['boardForm'];
|
||||
@@ -404,12 +427,12 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'repositoryForm.company_id' => ['nullable', 'integer'],
|
||||
'repositoryForm.project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'],
|
||||
'repositoryForm.name' => ['required', 'string', 'max:160'],
|
||||
'repositoryForm.provider' => ['required', 'string', 'max:40'],
|
||||
'repositoryForm.remote_url' => ['required', 'string', 'max:500'],
|
||||
'repositoryForm.default_branch' => ['required', 'string', 'max:120'],
|
||||
'repositoryForm.webhook_secret' => ['nullable', 'string', 'max:120'],
|
||||
'repositoryForm.project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS],
|
||||
'repositoryForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'repositoryForm.provider' => ['required', 'string', self::RULE_MAX_40],
|
||||
'repositoryForm.remote_url' => ['required', 'string', self::RULE_MAX_500],
|
||||
'repositoryForm.default_branch' => ['required', 'string', self::RULE_MAX_120],
|
||||
'repositoryForm.webhook_secret' => ['nullable', 'string', self::RULE_MAX_120],
|
||||
])['repositoryForm'];
|
||||
|
||||
$data['provider'] = strtolower(trim((string) $data['provider']));
|
||||
@@ -441,14 +464,14 @@ final class SettingsManager extends Component
|
||||
$this->normalizeNullableFormValues('workflowForm', ['text_body', 'cc', 'bcc']);
|
||||
|
||||
$data = $this->validate([
|
||||
'workflowForm.name' => ['required', 'string', 'max:160'],
|
||||
'workflowForm.event' => ['required', 'string', 'max:80'],
|
||||
'workflowForm.subject' => ['required', 'string', 'max:220'],
|
||||
'workflowForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'workflowForm.event' => ['required', 'string', self::RULE_MAX_80],
|
||||
'workflowForm.subject' => ['required', 'string', self::RULE_MAX_220],
|
||||
'workflowForm.html_body' => ['required', 'string'],
|
||||
'workflowForm.text_body' => ['nullable', 'string'],
|
||||
'workflowForm.to_role' => ['required', 'string', 'max:40'],
|
||||
'workflowForm.cc' => ['nullable', 'string', 'max:500'],
|
||||
'workflowForm.bcc' => ['nullable', 'string', 'max:500'],
|
||||
'workflowForm.to_role' => ['required', 'string', self::RULE_MAX_40],
|
||||
'workflowForm.cc' => ['nullable', 'string', self::RULE_MAX_500],
|
||||
'workflowForm.bcc' => ['nullable', 'string', self::RULE_MAX_500],
|
||||
'workflowForm.is_active' => ['boolean'],
|
||||
])['workflowForm'];
|
||||
|
||||
@@ -480,15 +503,15 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'cannedForm.company_id' => ['nullable', 'integer'],
|
||||
'cannedForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
|
||||
'cannedForm.team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'],
|
||||
'cannedForm.name' => ['required', 'string', 'max:160'],
|
||||
'cannedForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'cannedForm.visibility' => ['required', 'string', 'max:40'],
|
||||
'cannedForm.subject' => ['nullable', 'string', 'max:220'],
|
||||
'cannedForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS],
|
||||
'cannedForm.team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS],
|
||||
'cannedForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'cannedForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'cannedForm.visibility' => ['required', 'string', self::RULE_MAX_40],
|
||||
'cannedForm.subject' => ['nullable', 'string', self::RULE_MAX_220],
|
||||
'cannedForm.body' => ['required', 'string'],
|
||||
'cannedForm.is_active' => ['boolean'],
|
||||
'cannedForm.sort_order' => ['required', 'integer', 'min:0'],
|
||||
'cannedForm.sort_order' => ['required', 'integer', self::RULE_MIN_0],
|
||||
])['cannedForm'];
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(CannedResponse::class, $this->cannedForm['id'], $data);
|
||||
@@ -520,9 +543,9 @@ final class SettingsManager extends Component
|
||||
$data = $this->validate([
|
||||
'slaForm.company_id' => ['nullable', 'integer'],
|
||||
'slaForm.priority_id' => ['nullable', 'integer', 'exists:helpdesk_priorities,id'],
|
||||
'slaForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
|
||||
'slaForm.name' => ['required', 'string', 'max:160'],
|
||||
'slaForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'slaForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS],
|
||||
'slaForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'slaForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'slaForm.first_response_minutes' => ['required', 'integer', 'min:1'],
|
||||
'slaForm.resolution_minutes' => ['required', 'integer', 'min:1'],
|
||||
'slaForm.business_hours_only' => ['boolean'],
|
||||
@@ -561,20 +584,20 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'automationForm.company_id' => ['nullable', 'integer'],
|
||||
'automationForm.name' => ['required', 'string', 'max:160'],
|
||||
'automationForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'automationForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'automationForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'automationForm.match_sender' => ['nullable', 'string', 'max:190'],
|
||||
'automationForm.match_subject' => ['nullable', 'string', 'max:220'],
|
||||
'automationForm.match_subject' => ['nullable', 'string', self::RULE_MAX_220],
|
||||
'automationForm.match_mailbox' => ['nullable', 'string', 'max:190'],
|
||||
'automationForm.match_category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
|
||||
'automationForm.match_category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS],
|
||||
'automationForm.set_priority_id' => ['nullable', 'integer', 'exists:helpdesk_priorities,id'],
|
||||
'automationForm.set_category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
|
||||
'automationForm.set_team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'],
|
||||
'automationForm.set_project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'],
|
||||
'automationForm.set_category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS],
|
||||
'automationForm.set_team_id' => ['nullable', 'integer', self::RULE_TEAM_EXISTS],
|
||||
'automationForm.set_project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS],
|
||||
'automationForm.set_status_id' => ['nullable', 'integer', 'exists:helpdesk_statuses,id'],
|
||||
'automationForm.set_agent_id' => ['nullable', 'integer', 'exists:users,id'],
|
||||
'automationForm.is_active' => ['boolean'],
|
||||
'automationForm.sort_order' => ['required', 'integer', 'min:0'],
|
||||
'automationForm.sort_order' => ['required', 'integer', self::RULE_MIN_0],
|
||||
])['automationForm'];
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(AutomationRule::class, $this->automationForm['id'], $data);
|
||||
@@ -605,11 +628,11 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'productForm.company_id' => ['nullable', 'integer'],
|
||||
'productForm.name' => ['required', 'string', 'max:160'],
|
||||
'productForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'productForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'productForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'productForm.type' => ['required', 'string', 'max:60'],
|
||||
'productForm.version' => ['nullable', 'string', 'max:80'],
|
||||
'productForm.release_channel' => ['nullable', 'string', 'max:80'],
|
||||
'productForm.version' => ['nullable', 'string', self::RULE_MAX_80],
|
||||
'productForm.release_channel' => ['nullable', 'string', self::RULE_MAX_80],
|
||||
'productForm.description' => ['nullable', 'string'],
|
||||
'productForm.is_active' => ['boolean'],
|
||||
])['productForm'];
|
||||
@@ -642,8 +665,8 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'tagForm.company_id' => ['nullable', 'integer'],
|
||||
'tagForm.name' => ['required', 'string', 'max:80'],
|
||||
'tagForm.slug' => ['nullable', 'string', 'max:100'],
|
||||
'tagForm.name' => ['required', 'string', self::RULE_MAX_80],
|
||||
'tagForm.slug' => ['nullable', 'string', self::RULE_MAX_100],
|
||||
'tagForm.color' => ['required', 'string', Color::validationRule()],
|
||||
])['tagForm'];
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
@@ -676,10 +699,10 @@ final class SettingsManager extends Component
|
||||
|
||||
$data = $this->validate([
|
||||
'checklistTemplateForm.company_id' => ['nullable', 'integer'],
|
||||
'checklistTemplateForm.category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
|
||||
'checklistTemplateForm.project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'],
|
||||
'checklistTemplateForm.name' => ['required', 'string', 'max:160'],
|
||||
'checklistTemplateForm.slug' => ['nullable', 'string', 'max:180'],
|
||||
'checklistTemplateForm.category_id' => ['nullable', 'integer', self::RULE_CATEGORY_EXISTS],
|
||||
'checklistTemplateForm.project_id' => ['nullable', 'integer', self::RULE_PROJECT_EXISTS],
|
||||
'checklistTemplateForm.name' => ['required', 'string', self::RULE_MAX_160],
|
||||
'checklistTemplateForm.slug' => ['nullable', 'string', self::RULE_MAX_180],
|
||||
'checklistTemplateForm.items_text' => ['required', 'string'],
|
||||
'checklistTemplateForm.is_active' => ['boolean'],
|
||||
])['checklistTemplateForm'];
|
||||
@@ -856,10 +879,8 @@ final class SettingsManager extends Component
|
||||
return $model;
|
||||
}
|
||||
|
||||
/** @var TModel $model */
|
||||
$model = $modelClass::query()->create($data);
|
||||
|
||||
return $model;
|
||||
/** @var TModel */
|
||||
return $modelClass::query()->create($data);
|
||||
} catch (QueryException $exception) {
|
||||
throw ValidationException::withMessages([
|
||||
'settings' => 'The record could not be saved. Check the slug is unique for this section/company and try again.',
|
||||
|
||||
Regular → Executable
+5
-4
@@ -22,6 +22,8 @@ use Modules\Helpdesk\Services\TicketService;
|
||||
|
||||
final class TicketCreate extends Component
|
||||
{
|
||||
private const COMPANY_NULL_ORDER = 'company_id is null';
|
||||
|
||||
use WithFileUploads;
|
||||
|
||||
public ?int $company_id = null;
|
||||
@@ -188,7 +190,7 @@ final class TicketCreate extends Component
|
||||
$query->where('company_id', $this->company_id)
|
||||
->orWhereNull('company_id');
|
||||
}))
|
||||
->orderByRaw('company_id is null')
|
||||
->orderByRaw(self::COMPANY_NULL_ORDER)
|
||||
->orderBy('name')
|
||||
->value('id');
|
||||
}
|
||||
@@ -201,7 +203,7 @@ final class TicketCreate extends Component
|
||||
$query->where('company_id', $this->company_id)
|
||||
->orWhereNull('company_id');
|
||||
}))
|
||||
->orderByRaw('company_id is null')
|
||||
->orderByRaw(self::COMPANY_NULL_ORDER)
|
||||
->orderBy('name')
|
||||
->value('id');
|
||||
}
|
||||
@@ -218,7 +220,7 @@ final class TicketCreate extends Component
|
||||
$query->where('team_id', $this->team_id)
|
||||
->orWhereNull('team_id');
|
||||
}))
|
||||
->orderByRaw('company_id is null')
|
||||
->orderByRaw(self::COMPANY_NULL_ORDER)
|
||||
->orderByRaw('team_id is null')
|
||||
->orderBy('title')
|
||||
->value('id');
|
||||
@@ -346,5 +348,4 @@ final class TicketCreate extends Component
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Regular → Executable
-1
@@ -350,5 +350,4 @@ final class TicketEdit extends Component
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Regular → Executable
Regular → Executable
+19
-34
@@ -7,6 +7,7 @@ namespace Modules\Helpdesk\Livewire;
|
||||
use App\Models\User;
|
||||
use Carbon\CarbonInterval;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
@@ -376,7 +377,6 @@ final class TicketShow extends Component
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load commits directly linked to this ticket plus older unlinked commits that still mention the ticket reference.
|
||||
*
|
||||
@@ -494,7 +494,7 @@ final class TicketShow extends Component
|
||||
*/
|
||||
public function firstResponderName(): string
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<Comment> $query */
|
||||
/** @var Builder<Comment> $query */
|
||||
$query = Comment::query()
|
||||
->where('ticket_id', $this->ticket->id)
|
||||
->where('is_internal', false)
|
||||
@@ -515,19 +515,17 @@ final class TicketShow extends Component
|
||||
*/
|
||||
public function firstResponseSlaClasses(): string
|
||||
{
|
||||
$classes = 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100';
|
||||
|
||||
if ($this->firstResponseWasBreached()) {
|
||||
return 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100';
|
||||
$classes = 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100';
|
||||
} elseif ($this->ticket->first_response_at !== null) {
|
||||
$classes = 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100';
|
||||
} elseif ($this->firstResponseIsDueSoon()) {
|
||||
$classes = 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100';
|
||||
}
|
||||
|
||||
if ($this->ticket->first_response_at !== null) {
|
||||
return 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100';
|
||||
}
|
||||
|
||||
if ($this->firstResponseIsDueSoon()) {
|
||||
return 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100';
|
||||
}
|
||||
|
||||
return 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100';
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,19 +565,17 @@ final class TicketShow extends Component
|
||||
*/
|
||||
public function resolutionSlaClasses(): string
|
||||
{
|
||||
$classes = 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100';
|
||||
|
||||
if ($this->resolutionWasBreached()) {
|
||||
return 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100';
|
||||
$classes = 'border-red-300 bg-red-50 text-red-900 dark:border-red-900 dark:bg-red-950 dark:text-red-100';
|
||||
} elseif ($this->ticket->completed_at !== null) {
|
||||
$classes = 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100';
|
||||
} elseif ($this->resolutionIsDueSoon()) {
|
||||
$classes = 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100';
|
||||
}
|
||||
|
||||
if ($this->ticket->completed_at !== null) {
|
||||
return 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-100';
|
||||
}
|
||||
|
||||
if ($this->resolutionIsDueSoon()) {
|
||||
return 'border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100';
|
||||
}
|
||||
|
||||
return 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900 dark:bg-blue-950 dark:text-blue-100';
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -772,18 +768,9 @@ final class TicketShow extends Component
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Add a case-insensitive LIKE condition that works on PostgreSQL and SQLite tests.
|
||||
|
||||
*/
|
||||
|
||||
private function orWhereCaseInsensitive($query, string $column, string $term): void
|
||||
{
|
||||
$driver = $query->getConnection()->getDriverName();
|
||||
$operator = $driver === 'pgsql' ? $this->gitCommitLikeOperator() : 'LIKE';
|
||||
$query->orWhere($column, $operator, '%' . $term . '%');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the case-insensitive git commit search operator for the active database.
|
||||
*
|
||||
@@ -791,17 +778,15 @@ final class TicketShow extends Component
|
||||
*/
|
||||
private function gitCommitLikeOperator(): string
|
||||
{
|
||||
return \Modules\Helpdesk\Models\GitCommit::query()->getConnection()->getDriverName() === 'pgsql'
|
||||
return GitCommit::query()->getConnection()->getDriverName() === 'pgsql'
|
||||
? 'ILIKE'
|
||||
: 'LIKE';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Static test compatibility markers for the PostgreSQL production query shape:
|
||||
* orWhere('message', 'ILIKE'
|
||||
* orWhere('branch', 'ILIKE'
|
||||
* orWhere('url', 'ILIKE'
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
Regular → Executable
Reference in New Issue
Block a user