*/ public array $statusForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'zinc', 'sort_order' => 0, 'is_closed' => false]; /** @var array */ public array $priorityForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'zinc', 'sort_order' => 0]; /** @var array */ public array $categoryForm = ['id' => null, 'company_id' => null, 'name' => '', 'slug' => '', 'color' => 'blue', 'description' => '']; /** @var array */ public array $teamForm = ['id' => null, 'company_id' => null, 'name' => '', 'slug' => '', 'color' => 'indigo', 'description' => '', 'archived_at' => null]; /** @var array */ public array $projectForm = ['id' => null, 'company_id' => null, 'team_id' => null, 'title' => '', 'slug' => '', 'color' => 'blue', 'description' => '', 'archived_at' => null]; /** @var array */ public array $boardForm = ['id' => null, 'name' => '', 'slug' => '', 'description' => '', 'is_default' => false, 'sort_order' => 0, 'status_ids' => []]; /** @var array */ public array $repositoryForm = ['id' => null, 'company_id' => null, 'project_id' => null, 'name' => '', 'provider' => 'git', 'remote_url' => '', 'default_branch' => 'main', 'webhook_secret' => '']; /** @var array */ public array $workflowForm = ['id' => null, 'name' => '', 'event' => 'ticket.created', 'subject' => '', 'html_body' => '', 'text_body' => '', 'to_role' => 'requester', 'cc' => '', 'bcc' => '', 'is_active' => true]; public function saveStatus(): void { $data = $this->validate([ 'statusForm.name' => ['required', 'string', 'max:80'], 'statusForm.slug' => ['nullable', 'string', 'max:100'], 'statusForm.color' => ['required', 'string', 'max:30'], 'statusForm.sort_order' => ['required', 'integer', 'min:0'], 'statusForm.is_closed' => ['boolean'], ])['statusForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); Status::query()->updateOrCreate(['id' => $this->statusForm['id']], $data); $this->resetStatusForm(); session()->flash('success', 'Status saved.'); } public function editStatus(int $id): void { $this->statusForm = Status::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color', 'sort_order', 'is_closed']); $this->section = 'statuses'; } public function deleteStatus(int $id): void { Status::query()->findOrFail($id)->delete(); session()->flash('success', 'Status deleted.'); } public function resetStatusForm(): void { $this->statusForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'zinc', 'sort_order' => 0, 'is_closed' => false]; } public function savePriority(): void { $data = $this->validate([ 'priorityForm.name' => ['required', 'string', 'max:80'], 'priorityForm.slug' => ['nullable', 'string', 'max:100'], 'priorityForm.color' => ['required', 'string', 'max:30'], 'priorityForm.sort_order' => ['required', 'integer', 'min:0'], ])['priorityForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); Priority::query()->updateOrCreate(['id' => $this->priorityForm['id']], $data); $this->resetPriorityForm(); session()->flash('success', 'Priority saved.'); } public function editPriority(int $id): void { $this->priorityForm = Priority::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color', 'sort_order']); $this->section = 'priorities'; } public function deletePriority(int $id): void { Priority::query()->findOrFail($id)->delete(); session()->flash('success', 'Priority deleted.'); } public function resetPriorityForm(): void { $this->priorityForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'zinc', 'sort_order' => 0]; } public function saveCategory(): void { $data = $this->validate([ 'categoryForm.company_id' => ['nullable', 'integer'], 'categoryForm.name' => ['required', 'string', 'max:120'], 'categoryForm.slug' => ['nullable', 'string', 'max:140'], 'categoryForm.color' => ['required', 'string', 'max:30'], 'categoryForm.description' => ['nullable', 'string'], ])['categoryForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); Category::query()->updateOrCreate(['id' => $this->categoryForm['id']], $data); $this->resetCategoryForm(); session()->flash('success', 'Category saved.'); } public function editCategory(int $id): void { $this->categoryForm = Category::query()->findOrFail($id)->only(['id', 'company_id', 'name', 'slug', 'color', 'description']); $this->section = 'categories'; } public function deleteCategory(int $id): void { Category::query()->findOrFail($id)->delete(); session()->flash('success', 'Category deleted.'); } public function resetCategoryForm(): void { $this->categoryForm = ['id' => null, 'company_id' => null, 'name' => '', 'slug' => '', 'color' => 'blue', 'description' => '']; } public function saveTeam(): void { $data = $this->validate([ 'teamForm.company_id' => ['nullable', 'integer'], 'teamForm.name' => ['required', 'string', 'max:120'], 'teamForm.slug' => ['nullable', 'string', 'max:140'], 'teamForm.color' => ['required', 'string', 'max:30'], 'teamForm.description' => ['nullable', 'string'], ])['teamForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['name']); Team::query()->updateOrCreate(['id' => $this->teamForm['id']], $data); $this->resetTeamForm(); session()->flash('success', 'Team saved.'); } public function editTeam(int $id): void { $this->teamForm = Team::query()->findOrFail($id)->only(['id', 'company_id', 'name', 'slug', 'color', 'description', 'archived_at']); $this->section = 'teams'; } public function deleteTeam(int $id): void { Team::query()->findOrFail($id)->delete(); session()->flash('success', 'Team deleted.'); } public function resetTeamForm(): void { $this->teamForm = ['id' => null, 'company_id' => null, 'name' => '', 'slug' => '', 'color' => 'indigo', 'description' => '', 'archived_at' => null]; } public function saveProject(): void { $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.color' => ['required', 'string', 'max:30'], 'projectForm.description' => ['nullable', 'string'], ])['projectForm']; $data['slug'] = $this->slug($data['slug'] ?: $data['title']); Project::query()->updateOrCreate(['id' => $this->projectForm['id']], $data); $this->resetProjectForm(); session()->flash('success', 'Project saved.'); } public function editProject(int $id): void { $this->projectForm = Project::query()->findOrFail($id)->only(['id', 'company_id', 'team_id', 'title', 'slug', 'color', 'description', 'archived_at']); $this->section = 'projects'; } public function deleteProject(int $id): void { Project::query()->findOrFail($id)->delete(); session()->flash('success', 'Project deleted.'); } public function resetProjectForm(): void { $this->projectForm = ['id' => null, 'company_id' => null, 'team_id' => null, 'title' => '', 'slug' => '', 'color' => 'blue', 'description' => '', 'archived_at' => null]; } public function saveBoard(): void { $data = $this->validate([ 'boardForm.name' => ['required', 'string', 'max:160'], 'boardForm.slug' => ['nullable', 'string', 'max:180'], 'boardForm.description' => ['nullable', 'string'], 'boardForm.is_default' => ['boolean'], 'boardForm.sort_order' => ['required', 'integer', 'min:0'], 'boardForm.status_ids' => ['array'], 'boardForm.status_ids.*' => ['integer', 'exists:helpdesk_statuses,id'], ])['boardForm']; $statusIds = collect($data['status_ids'] ?? [])->map(static fn ($id): int => (int) $id)->filter()->values(); unset($data['status_ids']); $data['slug'] = $this->slug($data['slug'] ?: $data['name']); if ((bool) ($data['is_default'] ?? false)) { KanbanBoard::query()->whereKeyNot($this->boardForm['id'])->update(['is_default' => false]); } $board = KanbanBoard::query()->updateOrCreate(['id' => $this->boardForm['id']], $data); $sync = []; foreach ($statusIds as $index => $statusId) { $sync[$statusId] = ['sort_order' => ($index + 1) * 10]; } $board->statuses()->sync($sync); $this->resetBoardForm(); $this->section = 'boards'; session()->flash('success', 'Kanban board saved.'); } public function editBoard(int $id): void { $board = KanbanBoard::query()->with('statuses')->findOrFail($id); $this->boardForm = [ 'id' => $board->id, 'name' => $board->name, 'slug' => $board->slug, 'description' => $board->description, 'is_default' => $board->is_default, 'sort_order' => $board->sort_order, 'status_ids' => $board->statuses->pluck('id')->map(static fn ($id): int => (int) $id)->all(), ]; $this->section = 'boards'; } public function deleteBoard(int $id): void { KanbanBoard::query()->findOrFail($id)->delete(); session()->flash('success', 'Kanban board deleted.'); } public function resetBoardForm(): void { $this->boardForm = ['id' => null, 'name' => '', 'slug' => '', 'description' => '', 'is_default' => false, 'sort_order' => 0, 'status_ids' => []]; } public function saveRepository(): void { $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']; GitRepository::query()->updateOrCreate(['id' => $this->repositoryForm['id']], $data); $this->resetRepositoryForm(); session()->flash('success', 'Git repository saved.'); } public function editRepository(int $id): void { $this->repositoryForm = GitRepository::query()->findOrFail($id)->only(['id', 'company_id', 'project_id', 'name', 'provider', 'remote_url', 'default_branch', 'webhook_secret']); $this->section = 'git'; } public function deleteRepository(int $id): void { GitRepository::query()->findOrFail($id)->delete(); session()->flash('success', 'Git repository deleted.'); } public function resetRepositoryForm(): void { $this->repositoryForm = ['id' => null, 'company_id' => null, 'project_id' => null, 'name' => '', 'provider' => 'git', 'remote_url' => '', 'default_branch' => 'main', 'webhook_secret' => '']; } public function saveWorkflowTemplate(): void { $data = $this->validate([ 'workflowForm.name' => ['required', 'string', 'max:160'], 'workflowForm.event' => ['required', 'string', 'max:80'], 'workflowForm.subject' => ['required', 'string', '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.is_active' => ['boolean'], ])['workflowForm']; WorkflowTemplate::query()->updateOrCreate(['id' => $this->workflowForm['id']], $data); $this->resetWorkflowTemplateForm(); session()->flash('success', 'Workflow message saved.'); } public function editWorkflowTemplate(int $id): void { $this->workflowForm = WorkflowTemplate::query()->findOrFail($id)->only(['id', 'name', 'event', 'subject', 'html_body', 'text_body', 'to_role', 'cc', 'bcc', 'is_active']); $this->section = 'workflow'; } public function deleteWorkflowTemplate(int $id): void { WorkflowTemplate::query()->findOrFail($id)->delete(); session()->flash('success', 'Workflow message deleted.'); } public function resetWorkflowTemplateForm(): void { $this->workflowForm = ['id' => null, 'name' => '', 'event' => 'ticket.created', 'subject' => '', 'html_body' => '', 'text_body' => '', 'to_role' => 'requester', 'cc' => '', 'bcc' => '', 'is_active' => true]; } public function render(): View { return view('helpdesk::livewire.settings-manager', [ 'companies' => $this->companies(), 'statuses' => Status::query()->withCount('tickets')->orderBy('sort_order')->orderBy('name')->get(), 'priorities' => Priority::query()->withCount('tickets')->orderBy('sort_order')->orderBy('name')->get(), 'categories' => Category::query()->withCount('tickets')->orderBy('name')->get(), 'teams' => Team::query()->withCount(['projects', 'tickets'])->orderBy('name')->get(), 'projects' => Project::query()->with(['team'])->withCount('tickets')->orderBy('title')->get(), 'boards' => KanbanBoard::query()->with('statuses')->orderBy('sort_order')->orderBy('name')->get(), 'repositories' => GitRepository::query()->with(['project'])->withCount('commits')->orderBy('name')->get(), 'workflowTemplates' => WorkflowTemplate::query()->orderBy('event')->orderBy('name')->get(), ])->layout('layouts.app'); } /** @return array */ private function companies(): array { if (! Schema::hasTable('companies')) { return []; } return DB::table('companies')->select(['id', 'name'])->orderBy('name')->get()->all(); } private function slug(string $value): string { return Str::slug($value); } }