intial ticket fix partial delete fix

This commit is contained in:
Mark Gregory
2026-06-18 15:08:02 +01:00
parent 7cd8feec83
commit 8912d28b7b
5 changed files with 113 additions and 48 deletions
+58 -28
View File
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Modules\Helpdesk\Livewire;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
@@ -24,6 +25,7 @@ use Modules\Helpdesk\Models\Status;
use Modules\Helpdesk\Models\Tag;
use Modules\Helpdesk\Models\Team;
use Modules\Helpdesk\Models\WorkflowTemplate;
use Throwable;
final class SettingsManager extends Component
{
@@ -119,6 +121,16 @@ final class SettingsManager extends Component
return in_array($section, $allowed, true) ? $section : 'statuses';
}
/**
* Switch settings panels without relying on a full browser navigation.
*/
public function showSection(string $section): void
{
$this->section = $this->validSection($section);
$this->resetValidation();
}
public function saveStatus(): void
{
$data = $this->validate([
@@ -139,6 +151,7 @@ final class SettingsManager extends Component
Status::query()->updateOrCreate(['id' => $this->statusForm['id']], $data);
$this->resetStatusForm();
$this->section = 'statuses';
session()->flash('success', 'Status saved.');
}
@@ -150,8 +163,7 @@ final class SettingsManager extends Component
public function deleteStatus(int $id): void
{
Status::query()->findOrFail($id)->delete();
session()->flash('success', 'Status deleted.');
$this->deleteRecord(Status::class, $id, 'Status', 'statuses');
}
public function resetStatusForm(): void
@@ -177,6 +189,7 @@ final class SettingsManager extends Component
}
Priority::query()->updateOrCreate(['id' => $this->priorityForm['id']], $data);
$this->resetPriorityForm();
$this->section = 'priorities';
session()->flash('success', 'Priority saved.');
}
@@ -188,8 +201,7 @@ final class SettingsManager extends Component
public function deletePriority(int $id): void
{
Priority::query()->findOrFail($id)->delete();
session()->flash('success', 'Priority deleted.');
$this->deleteRecord(Priority::class, $id, 'Priority', 'priorities');
}
public function resetPriorityForm(): void
@@ -221,6 +233,7 @@ final class SettingsManager extends Component
}
Category::query()->updateOrCreate(['id' => $this->categoryForm['id']], $data);
$this->resetCategoryForm();
$this->section = 'categories';
session()->flash('success', 'Category saved.');
}
@@ -232,8 +245,7 @@ final class SettingsManager extends Component
public function deleteCategory(int $id): void
{
Category::query()->findOrFail($id)->delete();
session()->flash('success', 'Category deleted.');
$this->deleteRecord(Category::class, $id, 'Category', 'categories');
}
public function resetCategoryForm(): void
@@ -265,6 +277,7 @@ final class SettingsManager extends Component
}
Team::query()->updateOrCreate(['id' => $this->teamForm['id']], $data);
$this->resetTeamForm();
$this->section = 'teams';
session()->flash('success', 'Team saved.');
}
@@ -276,8 +289,7 @@ final class SettingsManager extends Component
public function deleteTeam(int $id): void
{
Team::query()->findOrFail($id)->delete();
session()->flash('success', 'Team deleted.');
$this->deleteRecord(Team::class, $id, 'Team', 'teams');
}
public function resetTeamForm(): void
@@ -310,6 +322,7 @@ final class SettingsManager extends Component
}
Project::query()->updateOrCreate(['id' => $this->projectForm['id']], $data);
$this->resetProjectForm();
$this->section = 'projects';
session()->flash('success', 'Project saved.');
}
@@ -321,8 +334,7 @@ final class SettingsManager extends Component
public function deleteProject(int $id): void
{
Project::query()->findOrFail($id)->delete();
session()->flash('success', 'Project deleted.');
$this->deleteRecord(Project::class, $id, 'Project', 'projects');
}
public function resetProjectForm(): void
@@ -388,8 +400,7 @@ final class SettingsManager extends Component
public function deleteBoard(int $id): void
{
KanbanBoard::query()->findOrFail($id)->delete();
session()->flash('success', 'Kanban board deleted.');
$this->deleteRecord(KanbanBoard::class, $id, 'Kanban board', 'boards');
}
public function resetBoardForm(): void
@@ -415,6 +426,7 @@ final class SettingsManager extends Component
GitRepository::query()->updateOrCreate(['id' => $this->repositoryForm['id']], $data);
$this->resetRepositoryForm();
$this->section = 'git';
session()->flash('success', 'Git repository saved.');
}
@@ -426,8 +438,7 @@ final class SettingsManager extends Component
public function deleteRepository(int $id): void
{
GitRepository::query()->findOrFail($id)->delete();
session()->flash('success', 'Git repository deleted.');
$this->deleteRecord(GitRepository::class, $id, 'Git repository', 'git');
}
public function resetRepositoryForm(): void
@@ -453,6 +464,7 @@ final class SettingsManager extends Component
WorkflowTemplate::query()->updateOrCreate(['id' => $this->workflowForm['id']], $data);
$this->resetWorkflowTemplateForm();
$this->section = 'workflow';
session()->flash('success', 'Workflow message saved.');
}
@@ -464,8 +476,7 @@ final class SettingsManager extends Component
public function deleteWorkflowTemplate(int $id): void
{
WorkflowTemplate::query()->findOrFail($id)->delete();
session()->flash('success', 'Workflow message deleted.');
$this->deleteRecord(WorkflowTemplate::class, $id, 'Workflow message', 'workflow');
}
public function resetWorkflowTemplateForm(): void
@@ -492,6 +503,7 @@ final class SettingsManager extends Component
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
CannedResponse::query()->updateOrCreate(['id' => $this->cannedForm['id']], $data);
$this->resetCannedResponseForm();
$this->section = 'canned';
session()->flash('success', 'Canned response saved.');
}
@@ -503,8 +515,7 @@ final class SettingsManager extends Component
public function deleteCannedResponse(int $id): void
{
CannedResponse::query()->findOrFail($id)->delete();
session()->flash('success', 'Canned response deleted.');
$this->deleteRecord(CannedResponse::class, $id, 'Canned response', 'canned');
}
public function resetCannedResponseForm(): void
@@ -534,6 +545,7 @@ final class SettingsManager extends Component
}
SlaPolicy::query()->updateOrCreate(['id' => $this->slaForm['id']], $data);
$this->resetSlaPolicyForm();
$this->section = 'sla';
session()->flash('success', 'SLA policy saved.');
}
@@ -545,8 +557,7 @@ final class SettingsManager extends Component
public function deleteSlaPolicy(int $id): void
{
SlaPolicy::query()->findOrFail($id)->delete();
session()->flash('success', 'SLA policy deleted.');
$this->deleteRecord(SlaPolicy::class, $id, 'SLA policy', 'sla');
}
public function resetSlaPolicyForm(): void
@@ -578,6 +589,7 @@ final class SettingsManager extends Component
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
AutomationRule::query()->updateOrCreate(['id' => $this->automationForm['id']], $data);
$this->resetAutomationRuleForm();
$this->section = 'automation';
session()->flash('success', 'Automation rule saved.');
}
@@ -589,8 +601,7 @@ final class SettingsManager extends Component
public function deleteAutomationRule(int $id): void
{
AutomationRule::query()->findOrFail($id)->delete();
session()->flash('success', 'Automation rule deleted.');
$this->deleteRecord(AutomationRule::class, $id, 'Automation rule', 'automation');
}
public function resetAutomationRuleForm(): void
@@ -615,6 +626,7 @@ final class SettingsManager extends Component
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
Product::query()->updateOrCreate(['id' => $this->productForm['id']], $data);
$this->resetProductForm();
$this->section = 'products';
session()->flash('success', 'Product/service saved.');
}
@@ -626,8 +638,7 @@ final class SettingsManager extends Component
public function deleteProduct(int $id): void
{
Product::query()->findOrFail($id)->delete();
session()->flash('success', 'Product/service deleted.');
$this->deleteRecord(Product::class, $id, 'Product/service', 'products');
}
public function resetProductForm(): void
@@ -648,6 +659,7 @@ final class SettingsManager extends Component
$data['slug'] = $this->slug($data['slug'] ?: $data['name']);
Tag::query()->updateOrCreate(['id' => $this->tagForm['id']], $data);
$this->resetTagForm();
$this->section = 'tags';
session()->flash('success', 'Tag saved.');
}
@@ -659,8 +671,7 @@ final class SettingsManager extends Component
public function deleteTag(int $id): void
{
Tag::query()->findOrFail($id)->delete();
session()->flash('success', 'Tag deleted.');
$this->deleteRecord(Tag::class, $id, 'Tag', 'tags');
}
public function resetTagForm(): void
@@ -687,6 +698,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();
ChecklistTemplate::query()->updateOrCreate(['id' => $this->checklistTemplateForm['id']], $data);
$this->resetChecklistTemplateForm();
$this->section = 'checklists';
session()->flash('success', 'Checklist template saved.');
}
@@ -701,8 +713,7 @@ final class SettingsManager extends Component
public function deleteChecklistTemplate(int $id): void
{
ChecklistTemplate::query()->findOrFail($id)->delete();
session()->flash('success', 'Checklist template deleted.');
$this->deleteRecord(ChecklistTemplate::class, $id, 'Checklist template', 'checklists');
}
public function resetChecklistTemplateForm(): void
@@ -736,6 +747,7 @@ final class SettingsManager extends Component
->update(['is_default_helpdesk_company' => true]);
}
$this->section = 'defaults';
session()->flash('success', 'Default Helpdesk company saved.');
}
@@ -822,6 +834,24 @@ final class SettingsManager extends Component
->get();
}
/**
* Delete a settings record without letting foreign-key protection crash the UI.
*
* @param class-string<Model> $modelClass
*/
private function deleteRecord(string $modelClass, int $id, string $label, string $section): void
{
$this->section = $section;
try {
$modelClass::query()->findOrFail($id)->delete();
session()->flash('success', $label.' deleted.');
} catch (Throwable) {
session()->flash('error', $label.' could not be deleted because it is still used by tickets or related Helpdesk records.');
}
}
/**
* Convert browser select empty strings into null before Livewire validation.
*