structure updates
This commit is contained in:
@@ -12,6 +12,7 @@ use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use Modules\Helpdesk\Models\AutomationRule;
|
||||
use Modules\Helpdesk\Models\CannedResponse;
|
||||
use Modules\Helpdesk\Models\Category;
|
||||
@@ -30,10 +31,26 @@ use Modules\Helpdesk\Support\Color;
|
||||
|
||||
final class SettingsManager extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public string $section = 'statuses';
|
||||
|
||||
public bool $teamModalOpen = false;
|
||||
|
||||
public bool $statusModalOpen = false;
|
||||
public bool $priorityModalOpen = false;
|
||||
public bool $categoryModalOpen = false;
|
||||
public bool $projectModalOpen = false;
|
||||
public bool $boardModalOpen = false;
|
||||
public bool $repositoryModalOpen = false;
|
||||
public bool $workflowModalOpen = false;
|
||||
public bool $cannedModalOpen = false;
|
||||
public bool $slaModalOpen = false;
|
||||
public bool $automationModalOpen = false;
|
||||
public bool $checklistModalOpen = false;
|
||||
public bool $tagModalOpen = false;
|
||||
public bool $productModalOpen = false;
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
public array $statusForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'gray', 'sort_order' => 0, 'is_closed' => false, 'is_default' => false];
|
||||
|
||||
@@ -141,6 +158,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$this->persistSettingModel(Status::class, $this->statusForm['id'], $data);
|
||||
$this->resetStatusForm();
|
||||
$this->statusModalOpen = false;
|
||||
session()->flash('success', 'Status saved.');
|
||||
}
|
||||
|
||||
@@ -149,6 +167,7 @@ final class SettingsManager extends Component
|
||||
$this->statusForm = Status::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color', 'sort_order', 'is_closed', 'is_default']);
|
||||
$this->statusForm['color'] = Color::normalise($this->statusForm['color'] ?? 'gray');
|
||||
$this->section = 'statuses';
|
||||
$this->statusModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteStatus(int $id): void
|
||||
@@ -157,6 +176,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Status deleted.');
|
||||
}
|
||||
|
||||
public function openCreateStatusModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetStatusForm();
|
||||
$this->section = 'statuses';
|
||||
$this->statusModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeStatusModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetStatusForm();
|
||||
$this->statusModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetStatusForm(): void
|
||||
{
|
||||
$this->statusForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'gray', 'sort_order' => 0, 'is_closed' => false, 'is_default' => false];
|
||||
@@ -180,6 +214,7 @@ final class SettingsManager extends Component
|
||||
}
|
||||
$this->persistSettingModel(Priority::class, $this->priorityForm['id'], $data);
|
||||
$this->resetPriorityForm();
|
||||
$this->priorityModalOpen = false;
|
||||
session()->flash('success', 'Priority saved.');
|
||||
}
|
||||
|
||||
@@ -188,6 +223,7 @@ final class SettingsManager extends Component
|
||||
$this->priorityForm = Priority::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color', 'sort_order', 'is_default']);
|
||||
$this->priorityForm['color'] = Color::normalise($this->priorityForm['color'] ?? 'gray');
|
||||
$this->section = 'priorities';
|
||||
$this->priorityModalOpen = true;
|
||||
}
|
||||
|
||||
public function deletePriority(int $id): void
|
||||
@@ -196,6 +232,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Priority deleted.');
|
||||
}
|
||||
|
||||
public function openCreatePriorityModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetPriorityForm();
|
||||
$this->section = 'priorities';
|
||||
$this->priorityModalOpen = true;
|
||||
}
|
||||
|
||||
public function closePriorityModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetPriorityForm();
|
||||
$this->priorityModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetPriorityForm(): void
|
||||
{
|
||||
$this->priorityForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'gray', 'sort_order' => 0, 'is_default' => false];
|
||||
@@ -221,6 +272,7 @@ final class SettingsManager extends Component
|
||||
}
|
||||
$this->persistSettingModel(Category::class, $this->categoryForm['id'], $data);
|
||||
$this->resetCategoryForm();
|
||||
$this->categoryModalOpen = false;
|
||||
session()->flash('success', 'Category saved.');
|
||||
}
|
||||
|
||||
@@ -229,6 +281,7 @@ final class SettingsManager extends Component
|
||||
$this->categoryForm = Category::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color', 'description', 'is_default']);
|
||||
$this->categoryForm['color'] = Color::normalise($this->categoryForm['color'] ?? 'blue');
|
||||
$this->section = 'categories';
|
||||
$this->categoryModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteCategory(int $id): void
|
||||
@@ -237,6 +290,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Category deleted.');
|
||||
}
|
||||
|
||||
public function openCreateCategoryModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetCategoryForm();
|
||||
$this->section = 'categories';
|
||||
$this->categoryModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeCategoryModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetCategoryForm();
|
||||
$this->categoryModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetCategoryForm(): void
|
||||
{
|
||||
$this->categoryForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'blue', 'description' => '', 'is_default' => false];
|
||||
@@ -401,6 +469,7 @@ final class SettingsManager extends Component
|
||||
}
|
||||
$this->persistSettingModel(Project::class, $this->projectForm['id'], $data);
|
||||
$this->resetProjectForm();
|
||||
$this->projectModalOpen = false;
|
||||
session()->flash('success', 'Project saved.');
|
||||
}
|
||||
|
||||
@@ -409,6 +478,7 @@ final class SettingsManager extends Component
|
||||
$this->projectForm = Project::query()->findOrFail($id)->only(['id', 'team_id', 'title', 'slug', 'color', 'description', 'is_default', 'archived_at']);
|
||||
$this->projectForm['color'] = Color::normalise($this->projectForm['color'] ?? 'blue');
|
||||
$this->section = 'projects';
|
||||
$this->projectModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteProject(int $id): void
|
||||
@@ -417,6 +487,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Project deleted.');
|
||||
}
|
||||
|
||||
public function openCreateProjectModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetProjectForm();
|
||||
$this->section = 'projects';
|
||||
$this->projectModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeProjectModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetProjectForm();
|
||||
$this->projectModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetProjectForm(): void
|
||||
{
|
||||
$this->projectForm = ['id' => null, 'team_id' => null, 'title' => '', 'slug' => '', 'color' => 'blue', 'description' => '', 'is_default' => false, 'archived_at' => null];
|
||||
@@ -456,6 +541,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$board->statuses()->sync($sync);
|
||||
$this->resetBoardForm();
|
||||
$this->boardModalOpen = false;
|
||||
$this->section = 'boards';
|
||||
session()->flash('success', 'Kanban board saved.');
|
||||
}
|
||||
@@ -476,6 +562,7 @@ final class SettingsManager extends Component
|
||||
];
|
||||
|
||||
$this->section = 'boards';
|
||||
$this->boardModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteBoard(int $id): void
|
||||
@@ -484,6 +571,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Kanban board deleted.');
|
||||
}
|
||||
|
||||
public function openCreateBoardModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetBoardForm();
|
||||
$this->section = 'boards';
|
||||
$this->boardModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeBoardModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetBoardForm();
|
||||
$this->boardModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetBoardForm(): void
|
||||
{
|
||||
$this->boardForm = ['id' => null, 'name' => '', 'slug' => '', 'description' => '', 'owner_id' => null, 'is_default' => false, 'sort_order' => 0, 'status_ids' => []];
|
||||
@@ -506,6 +608,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$this->persistSettingModel(GitRepository::class, $this->repositoryForm['id'], $data);
|
||||
$this->resetRepositoryForm();
|
||||
$this->repositoryModalOpen = false;
|
||||
session()->flash('success', 'Git repository saved.');
|
||||
}
|
||||
|
||||
@@ -513,6 +616,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->repositoryForm = GitRepository::query()->findOrFail($id)->only(['id', 'project_id', 'name', 'provider', 'remote_url', 'default_branch', 'webhook_secret']);
|
||||
$this->section = 'git';
|
||||
$this->repositoryModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteRepository(int $id): void
|
||||
@@ -521,6 +625,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Git repository deleted.');
|
||||
}
|
||||
|
||||
public function openCreateRepositoryModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetRepositoryForm();
|
||||
$this->section = 'git';
|
||||
$this->repositoryModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeRepositoryModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetRepositoryForm();
|
||||
$this->repositoryModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetRepositoryForm(): void
|
||||
{
|
||||
$this->repositoryForm = ['id' => null, 'project_id' => null, 'name' => '', 'provider' => 'git', 'remote_url' => '', 'default_branch' => 'main', 'webhook_secret' => ''];
|
||||
@@ -544,6 +663,7 @@ final class SettingsManager extends Component
|
||||
|
||||
$this->persistSettingModel(WorkflowTemplate::class, $this->workflowForm['id'], $data);
|
||||
$this->resetWorkflowTemplateForm();
|
||||
$this->workflowModalOpen = false;
|
||||
session()->flash('success', 'Workflow message saved.');
|
||||
}
|
||||
|
||||
@@ -551,6 +671,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->workflowForm = WorkflowTemplate::query()->findOrFail($id)->only(['id', 'name', 'event', 'subject', 'html_body', 'text_body', 'to_role', 'cc', 'bcc', 'is_active']);
|
||||
$this->section = 'workflow';
|
||||
$this->workflowModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteWorkflowTemplate(int $id): void
|
||||
@@ -559,6 +680,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Workflow message deleted.');
|
||||
}
|
||||
|
||||
public function openCreateWorkflowTemplateModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetWorkflowTemplateForm();
|
||||
$this->section = 'workflow';
|
||||
$this->workflowModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeWorkflowTemplateModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetWorkflowTemplateForm();
|
||||
$this->workflowModalOpen = false;
|
||||
}
|
||||
|
||||
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];
|
||||
@@ -582,6 +718,7 @@ final class SettingsManager extends Component
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(CannedResponse::class, $this->cannedForm['id'], $data);
|
||||
$this->resetCannedResponseForm();
|
||||
$this->cannedModalOpen = false;
|
||||
session()->flash('success', 'Canned response saved.');
|
||||
}
|
||||
|
||||
@@ -589,6 +726,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->cannedForm = CannedResponse::query()->findOrFail($id)->only(['id', 'category_id', 'team_id', 'name', 'slug', 'visibility', 'subject', 'body', 'is_active', 'sort_order']);
|
||||
$this->section = 'canned';
|
||||
$this->cannedModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteCannedResponse(int $id): void
|
||||
@@ -597,6 +735,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Canned response deleted.');
|
||||
}
|
||||
|
||||
public function openCreateCannedResponseModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetCannedResponseForm();
|
||||
$this->section = 'canned';
|
||||
$this->cannedModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeCannedResponseModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetCannedResponseForm();
|
||||
$this->cannedModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetCannedResponseForm(): void
|
||||
{
|
||||
$this->cannedForm = ['id' => null, 'category_id' => null, 'team_id' => null, 'name' => '', 'slug' => '', 'visibility' => 'agents', 'subject' => '', 'body' => '', 'is_active' => true, 'sort_order' => 0];
|
||||
@@ -623,6 +776,7 @@ final class SettingsManager extends Component
|
||||
}
|
||||
$this->persistSettingModel(SlaPolicy::class, $this->slaForm['id'], $data);
|
||||
$this->resetSlaPolicyForm();
|
||||
$this->slaModalOpen = false;
|
||||
session()->flash('success', 'SLA policy saved.');
|
||||
}
|
||||
|
||||
@@ -630,6 +784,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->slaForm = SlaPolicy::query()->findOrFail($id)->only(['id', 'priority_id', 'category_id', 'name', 'slug', 'first_response_minutes', 'resolution_minutes', 'business_hours_only', 'is_default', 'is_active']);
|
||||
$this->section = 'sla';
|
||||
$this->slaModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteSlaPolicy(int $id): void
|
||||
@@ -638,6 +793,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'SLA policy deleted.');
|
||||
}
|
||||
|
||||
public function openCreateSlaPolicyModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetSlaPolicyForm();
|
||||
$this->section = 'sla';
|
||||
$this->slaModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeSlaPolicyModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetSlaPolicyForm();
|
||||
$this->slaModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetSlaPolicyForm(): void
|
||||
{
|
||||
$this->slaForm = ['id' => null, 'priority_id' => null, 'category_id' => null, 'name' => '', 'slug' => '', 'first_response_minutes' => 240, 'resolution_minutes' => 2880, 'business_hours_only' => false, 'is_default' => false, 'is_active' => true];
|
||||
@@ -666,6 +836,7 @@ final class SettingsManager extends Component
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(AutomationRule::class, $this->automationForm['id'], $data);
|
||||
$this->resetAutomationRuleForm();
|
||||
$this->automationModalOpen = false;
|
||||
session()->flash('success', 'Automation rule saved.');
|
||||
}
|
||||
|
||||
@@ -673,6 +844,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->automationForm = AutomationRule::query()->findOrFail($id)->only(['id', 'name', 'slug', 'match_sender', 'match_subject', 'match_mailbox', 'match_category_id', 'set_priority_id', 'set_category_id', 'set_team_id', 'set_project_id', 'set_status_id', 'set_agent_id', 'is_active', 'sort_order']);
|
||||
$this->section = 'automation';
|
||||
$this->automationModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteAutomationRule(int $id): void
|
||||
@@ -681,6 +853,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Automation rule deleted.');
|
||||
}
|
||||
|
||||
public function openCreateAutomationRuleModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetAutomationRuleForm();
|
||||
$this->section = 'automation';
|
||||
$this->automationModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeAutomationRuleModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetAutomationRuleForm();
|
||||
$this->automationModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetAutomationRuleForm(): void
|
||||
{
|
||||
$this->automationForm = ['id' => null, 'name' => '', 'slug' => '', 'match_sender' => '', 'match_subject' => '', 'match_mailbox' => '', 'match_category_id' => null, 'set_priority_id' => null, 'set_category_id' => null, 'set_team_id' => null, 'set_project_id' => null, 'set_status_id' => null, 'set_agent_id' => null, 'is_active' => true, 'sort_order' => 0];
|
||||
@@ -702,6 +889,7 @@ final class SettingsManager extends Component
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(Product::class, $this->productForm['id'], $data);
|
||||
$this->resetProductForm();
|
||||
$this->productModalOpen = false;
|
||||
session()->flash('success', 'Product/service saved.');
|
||||
}
|
||||
|
||||
@@ -709,6 +897,7 @@ final class SettingsManager extends Component
|
||||
{
|
||||
$this->productForm = Product::query()->findOrFail($id)->only(['id', 'name', 'slug', 'type', 'version', 'release_channel', 'description', 'is_active']);
|
||||
$this->section = 'products';
|
||||
$this->productModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteProduct(int $id): void
|
||||
@@ -717,6 +906,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Product/service deleted.');
|
||||
}
|
||||
|
||||
public function openCreateProductModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetProductForm();
|
||||
$this->section = 'products';
|
||||
$this->productModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeProductModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetProductForm();
|
||||
$this->productModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetProductForm(): void
|
||||
{
|
||||
$this->productForm = ['id' => null, 'name' => '', 'slug' => '', 'type' => 'service', 'version' => '', 'release_channel' => '', 'description' => '', 'is_active' => true];
|
||||
@@ -734,6 +938,7 @@ final class SettingsManager extends Component
|
||||
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
|
||||
$this->persistSettingModel(Tag::class, $this->tagForm['id'], $data);
|
||||
$this->resetTagForm();
|
||||
$this->tagModalOpen = false;
|
||||
session()->flash('success', 'Tag saved.');
|
||||
}
|
||||
|
||||
@@ -742,6 +947,7 @@ final class SettingsManager extends Component
|
||||
$this->tagForm = Tag::query()->findOrFail($id)->only(['id', 'name', 'slug', 'color']);
|
||||
$this->tagForm['color'] = Color::normalise($this->tagForm['color'] ?? 'gray');
|
||||
$this->section = 'tags';
|
||||
$this->tagModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteTag(int $id): void
|
||||
@@ -750,6 +956,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Tag deleted.');
|
||||
}
|
||||
|
||||
public function openCreateTagModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetTagForm();
|
||||
$this->section = 'tags';
|
||||
$this->tagModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeTagModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetTagForm();
|
||||
$this->tagModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetTagForm(): void
|
||||
{
|
||||
$this->tagForm = ['id' => null, 'name' => '', 'slug' => '', 'color' => 'gray'];
|
||||
@@ -773,6 +994,7 @@ final class SettingsManager extends Component
|
||||
$data['items'] = collect(preg_split('/\r\n|\r|\n/', $itemsText) ?: [])->map(fn ($line): string => trim($line))->filter()->values()->all();
|
||||
$this->persistSettingModel(ChecklistTemplate::class, $this->checklistTemplateForm['id'], $data);
|
||||
$this->resetChecklistTemplateForm();
|
||||
$this->checklistModalOpen = false;
|
||||
session()->flash('success', 'Checklist template saved.');
|
||||
}
|
||||
|
||||
@@ -783,6 +1005,7 @@ final class SettingsManager extends Component
|
||||
'items_text' => collect($template->items ?? [])->map(fn ($item): string => is_array($item) ? (string) ($item['title'] ?? '') : (string) $item)->implode("\n"),
|
||||
];
|
||||
$this->section = 'checklists';
|
||||
$this->checklistModalOpen = true;
|
||||
}
|
||||
|
||||
public function deleteChecklistTemplate(int $id): void
|
||||
@@ -791,6 +1014,21 @@ final class SettingsManager extends Component
|
||||
session()->flash('success', 'Checklist template deleted.');
|
||||
}
|
||||
|
||||
public function openCreateChecklistTemplateModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetChecklistTemplateForm();
|
||||
$this->section = 'checklists';
|
||||
$this->checklistModalOpen = true;
|
||||
}
|
||||
|
||||
public function closeChecklistTemplateModal(): void
|
||||
{
|
||||
$this->resetValidation();
|
||||
$this->resetChecklistTemplateForm();
|
||||
$this->checklistModalOpen = false;
|
||||
}
|
||||
|
||||
public function resetChecklistTemplateForm(): void
|
||||
{
|
||||
$this->checklistTemplateForm = ['id' => null, 'category_id' => null, 'project_id' => null, 'name' => '', 'slug' => '', 'items_text' => '', 'is_active' => true];
|
||||
@@ -810,15 +1048,45 @@ final class SettingsManager extends Component
|
||||
'boardOwners' => User::query()->where(static function ($query): void {
|
||||
$query->where('helpdesk_agent', true)->orWhere('helpdesk_admin', true);
|
||||
})->orderBy('name')->get(['id', 'name', 'email']),
|
||||
'boards' => KanbanBoard::query()->with(['statuses', 'owner:id,name,email'])->withCount('tickets')->orderBy('sort_order')->orderBy('name')->get(),
|
||||
'repositories' => GitRepository::query()->with(['project'])->withCount(['commits', 'webhookLogs'])->orderBy('name')->get(),
|
||||
'workflowTemplates' => WorkflowTemplate::query()->orderBy('event')->orderBy('name')->get(),
|
||||
'cannedResponses' => CannedResponse::query()->with(['category', 'team'])->orderBy('sort_order')->orderBy('name')->get(),
|
||||
'slaPolicies' => SlaPolicy::query()->with(['priority', 'category'])->orderByDesc('is_default')->orderBy('name')->get(),
|
||||
'automationRules' => AutomationRule::query()->orderBy('sort_order')->orderBy('name')->get(),
|
||||
'products' => Product::query()->withCount('tickets')->orderBy('name')->get(),
|
||||
'tags' => Tag::query()->orderBy('name')->get(),
|
||||
'checklistTemplates' => ChecklistTemplate::query()->orderBy('name')->get(),
|
||||
'boards' => KanbanBoard::query()
|
||||
->with(['statuses', 'owner:id,name,email'])
|
||||
->withCount('tickets')
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'boardsPage'),
|
||||
'repositories' => GitRepository::query()
|
||||
->with(['project'])
|
||||
->withCount(['commits', 'webhookLogs'])
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'gitPage'),
|
||||
'workflowTemplates' => WorkflowTemplate::query()
|
||||
->orderBy('event')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'workflowPage'),
|
||||
'cannedResponses' => CannedResponse::query()
|
||||
->with(['category', 'team'])
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'cannedPage'),
|
||||
'slaPolicies' => SlaPolicy::query()
|
||||
->with(['priority', 'category'])
|
||||
->orderByDesc('is_default')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'slaPage'),
|
||||
'automationRules' => AutomationRule::query()
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'rulesPage'),
|
||||
'products' => Product::query()
|
||||
->withCount('tickets')
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'productsPage'),
|
||||
'tags' => Tag::query()
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'tagsPage'),
|
||||
'checklistTemplates' => ChecklistTemplate::query()
|
||||
->orderBy('name')
|
||||
->paginate(10, ['*'], 'checksPage'),
|
||||
'colourOptions' => Color::options(),
|
||||
])->layout('layouts.app');
|
||||
}
|
||||
@@ -830,7 +1098,7 @@ final class SettingsManager extends Component
|
||||
->when($this->hasDefaultColumn('helpdesk_statuses'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
->paginate(10, ['*'], 'statusesPage');
|
||||
}
|
||||
|
||||
private function orderedPriorities(): mixed
|
||||
@@ -840,7 +1108,7 @@ final class SettingsManager extends Component
|
||||
->when($this->hasDefaultColumn('helpdesk_priorities'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
->paginate(10, ['*'], 'prioritiesPage');
|
||||
}
|
||||
|
||||
private function orderedCategories(): mixed
|
||||
@@ -849,7 +1117,7 @@ final class SettingsManager extends Component
|
||||
->withCount('tickets')
|
||||
->when($this->hasDefaultColumn('helpdesk_categories'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('name')
|
||||
->get();
|
||||
->paginate(10, ['*'], 'categoriesPage');
|
||||
}
|
||||
|
||||
private function orderedTeams(): mixed
|
||||
@@ -859,7 +1127,7 @@ final class SettingsManager extends Component
|
||||
->withCount(['projects', 'tickets', 'users'])
|
||||
->when($this->hasDefaultColumn('helpdesk_teams'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('name')
|
||||
->get();
|
||||
->paginate(10, ['*'], 'teamsPage');
|
||||
}
|
||||
|
||||
private function orderedProjects(): mixed
|
||||
@@ -869,7 +1137,7 @@ final class SettingsManager extends Component
|
||||
->withCount('tickets')
|
||||
->when($this->hasDefaultColumn('helpdesk_projects'), fn ($query) => $query->orderByDesc('is_default'))
|
||||
->orderBy('title')
|
||||
->get();
|
||||
->paginate(10, ['*'], 'projectsPage');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -982,3 +982,38 @@ span.flatpickr-weekday {
|
||||
box-shadow: 0 0 0 1000px #09090b inset !important;
|
||||
transition: background-color 9999s ease-in-out 0s;
|
||||
}
|
||||
|
||||
|
||||
/* Helpdesk settings modal presentation */
|
||||
.hd-settings-modal {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.hd-settings-modal form {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.hd-settings-modal form > * {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hd-settings-modal input:not([type="checkbox"]):not([type="radio"]):not([type="color"]),
|
||||
.hd-settings-modal select,
|
||||
.hd-settings-modal textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hd-settings-modal textarea {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.hd-settings-modal label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.hd-settings-modal {
|
||||
padding-inline: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Tests\Feature;
|
||||
|
||||
use Modules\Helpdesk\Livewire\SettingsManager;
|
||||
use ReflectionClass;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class SettingsModalStructureTest extends TestCase
|
||||
{
|
||||
public function test_each_settings_editor_exposes_a_modal_state_property(): void
|
||||
{
|
||||
$reflection = new ReflectionClass(SettingsManager::class);
|
||||
|
||||
foreach ([
|
||||
'statusModalOpen', 'priorityModalOpen', 'categoryModalOpen',
|
||||
'projectModalOpen', 'boardModalOpen', 'repositoryModalOpen',
|
||||
'workflowModalOpen', 'cannedModalOpen', 'slaModalOpen',
|
||||
'automationModalOpen', 'checklistModalOpen', 'tagModalOpen',
|
||||
'productModalOpen',
|
||||
] as $property) {
|
||||
self::assertTrue($reflection->hasProperty($property), $property);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user