structure and style updates

This commit is contained in:
Mark Gregory
2026-06-16 23:21:49 +01:00
parent 80991208af
commit 2c2af4c50e
60 changed files with 209 additions and 216 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ return [
'middleware' => ['web', 'auth'],
'disk' => env('HELPDESK_ATTACHMENTS_DISK', 'local'),
'max_upload_kb' => (int) env('HELPDESK_MAX_UPLOAD_KB', 10240),
'allowed_mimes' => ['md','pdf', 'png', 'jpg', 'jpeg', 'webp', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'zip'],
'allowed_mimes' => ['md', 'pdf', 'png', 'jpg', 'jpeg', 'webp', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'csv', 'zip'],
'default_status_slug' => 'new',
'closed_status_slug' => 'closed',
];
@@ -24,7 +24,6 @@ return new class extends Migration
$table->unique(['company_id', 'slug']);
});
Schema::create('helpdesk_sla_policies', static function (Blueprint $table): void {
$table->id();
$table->foreignId('company_id')->nullable()->constrained('companies')->nullOnDelete();
@@ -107,8 +106,6 @@ return new class extends Migration
$table->index(['category_id', 'team_id', 'is_active']);
});
Schema::create('helpdesk_automation_rules', static function (Blueprint $table): void {
$table->id();
$table->foreignId('company_id')->nullable()->constrained('companies')->nullOnDelete();
@@ -126,7 +126,7 @@ final class TicketControlsController extends Controller
/**
* Apply a direct guarded ticket update without relying on Livewire hydration.
*
* @param array<string, mixed> $updates
* @param array<string, mixed> $updates
*/
private function updateTicket(Ticket $ticket, array $updates): void
{
+1 -4
View File
@@ -6,8 +6,8 @@ namespace Modules\Helpdesk\Livewire;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use Modules\Helpdesk\Models\KanbanBoard as KanbanBoardModel;
use Modules\Helpdesk\Models\Status;
@@ -99,9 +99,6 @@ final class KanbanBoard extends Component
/**
* Normalise the board selector value from Livewire/browser select events.
*
* @param int|string|null $value
* @return void
*/
public function updatedBoardId(int|string|null $value): void
{
+13 -17
View File
@@ -12,15 +12,15 @@ use Illuminate\Support\Str;
use Livewire\Component;
use Modules\Helpdesk\Models\AutomationRule;
use Modules\Helpdesk\Models\CannedResponse;
use Modules\Helpdesk\Models\ChecklistTemplate;
use Modules\Helpdesk\Models\Category;
use Modules\Helpdesk\Models\ChecklistTemplate;
use Modules\Helpdesk\Models\GitRepository;
use Modules\Helpdesk\Models\KanbanBoard;
use Modules\Helpdesk\Models\Priority;
use Modules\Helpdesk\Models\Product;
use Modules\Helpdesk\Models\Project;
use Modules\Helpdesk\Models\Status;
use Modules\Helpdesk\Models\SlaPolicy;
use Modules\Helpdesk\Models\Status;
use Modules\Helpdesk\Models\Tag;
use Modules\Helpdesk\Models\Team;
use Modules\Helpdesk\Models\WorkflowTemplate;
@@ -297,7 +297,6 @@ final class SettingsManager extends Component
$this->projectForm = ['id' => null, 'company_id' => null, 'team_id' => null, 'title' => '', 'slug' => '', 'color' => 'blue', 'description' => '', 'is_default' => false, 'archived_at' => null];
}
public function saveBoard(): void
{
$data = $this->validate([
@@ -435,7 +434,6 @@ final class SettingsManager extends Component
$this->workflowForm = ['id' => null, 'name' => '', 'event' => 'ticket.created', 'subject' => '', 'html_body' => '', 'text_body' => '', 'to_role' => 'requester', 'cc' => '', 'bcc' => '', 'is_active' => true];
}
public function saveCannedResponse(): void
{
$data = $this->validate([
@@ -458,7 +456,7 @@ final class SettingsManager extends Component
public function editCannedResponse(int $id): void
{
$this->cannedForm = CannedResponse::query()->findOrFail($id)->only(['id','company_id','category_id','team_id','name','slug','visibility','subject','body','is_active','sort_order']);
$this->cannedForm = CannedResponse::query()->findOrFail($id)->only(['id', 'company_id', 'category_id', 'team_id', 'name', 'slug', 'visibility', 'subject', 'body', 'is_active', 'sort_order']);
$this->section = 'canned';
}
@@ -498,7 +496,7 @@ final class SettingsManager extends Component
public function editSlaPolicy(int $id): void
{
$this->slaForm = SlaPolicy::query()->findOrFail($id)->only(['id','company_id','priority_id','category_id','name','slug','first_response_minutes','resolution_minutes','business_hours_only','is_default','is_active']);
$this->slaForm = SlaPolicy::query()->findOrFail($id)->only(['id', 'company_id', 'priority_id', 'category_id', 'name', 'slug', 'first_response_minutes', 'resolution_minutes', 'business_hours_only', 'is_default', 'is_active']);
$this->section = 'sla';
}
@@ -540,7 +538,7 @@ final class SettingsManager extends Component
public function editAutomationRule(int $id): void
{
$this->automationForm = AutomationRule::query()->findOrFail($id)->only(['id','company_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->automationForm = AutomationRule::query()->findOrFail($id)->only(['id', 'company_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';
}
@@ -575,7 +573,7 @@ final class SettingsManager extends Component
public function editProduct(int $id): void
{
$this->productForm = Product::query()->findOrFail($id)->only(['id','company_id','name','slug','type','version','release_channel','description','is_active']);
$this->productForm = Product::query()->findOrFail($id)->only(['id', 'company_id', 'name', 'slug', 'type', 'version', 'release_channel', 'description', 'is_active']);
$this->section = 'products';
}
@@ -606,7 +604,7 @@ final class SettingsManager extends Component
public function editTag(int $id): void
{
$this->tagForm = Tag::query()->findOrFail($id)->only(['id','company_id','name','slug','color']);
$this->tagForm = Tag::query()->findOrFail($id)->only(['id', 'company_id', 'name', 'slug', 'color']);
$this->section = 'tags';
}
@@ -644,7 +642,7 @@ final class SettingsManager extends Component
public function editChecklistTemplate(int $id): void
{
$template = ChecklistTemplate::query()->findOrFail($id);
$this->checklistTemplateForm = $template->only(['id','company_id','category_id','project_id','name','slug','is_active']) + [
$this->checklistTemplateForm = $template->only(['id', 'company_id', 'category_id', 'project_id', 'name', 'slug', 'is_active']) + [
'items_text' => collect($template->items ?? [])->map(fn ($item): string => is_array($item) ? (string) ($item['title'] ?? '') : (string) $item)->implode("\n"),
];
$this->section = 'checklists';
@@ -661,7 +659,6 @@ final class SettingsManager extends Component
$this->checklistTemplateForm = ['id' => null, 'company_id' => null, 'category_id' => null, 'project_id' => null, 'name' => '', 'slug' => '', 'items_text' => '', 'is_active' => true];
}
public function saveDefaultHelpdeskCompany(): void
{
if (! Schema::hasTable('companies') || ! Schema::hasColumn('companies', 'is_default_helpdesk_company')) {
@@ -709,12 +706,14 @@ final class SettingsManager extends Component
'categories' => $this->orderedCategories(),
'teams' => $this->orderedTeams(),
'projects' => $this->orderedProjects(),
'boardOwners' => User::query()->where(static function ($query): void { $query->where('helpdesk_agent', true)->orWhere('helpdesk_admin', true); })->orderBy('name')->get(['id', 'name', 'email']),
'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(),
'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(),
@@ -722,8 +721,6 @@ final class SettingsManager extends Component
])->layout('layouts.app');
}
private function orderedStatuses(): mixed
{
return Status::query()
@@ -772,7 +769,6 @@ final class SettingsManager extends Component
->get();
}
/**
* Remove is_default before save when the database has not been migrated yet.
*
+1 -6
View File
@@ -17,8 +17,8 @@ use Modules\Helpdesk\Models\KanbanBoard;
use Modules\Helpdesk\Models\Priority;
use Modules\Helpdesk\Models\Product;
use Modules\Helpdesk\Models\Project;
use Modules\Helpdesk\Models\Team;
use Modules\Helpdesk\Models\Tag;
use Modules\Helpdesk\Models\Team;
use Modules\Helpdesk\Services\TicketService;
final class TicketCreate extends Component
@@ -55,7 +55,6 @@ final class TicketCreate extends Component
#[Validate('nullable|date')]
public ?string $due_at = null;
/** @var array<int, int> */
#[Validate('array')]
public array $tag_ids = [];
@@ -102,7 +101,6 @@ final class TicketCreate extends Component
return $this->redirectRoute('helpdesk.tickets.index', navigate: true);
}
/**
* Clear the create form, including Select2 and Flatpickr browser widgets.
*/
@@ -154,7 +152,6 @@ final class TicketCreate extends Component
->value('id');
}
if (blank($this->board_id) && Schema::hasTable('helpdesk_kanban_boards')) {
$this->board_id = KanbanBoard::query()
->where('is_default', true)
@@ -213,8 +210,6 @@ final class TicketCreate extends Component
}
}
/**
* Return Kanban board options with the default board listed first.
*/
-1
View File
@@ -7,7 +7,6 @@ namespace Modules\Helpdesk\Livewire;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
+3 -2
View File
@@ -10,14 +10,15 @@ use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Schema;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Livewire\WithFileUploads;
use Modules\Helpdesk\Models\CannedResponse;
use Modules\Helpdesk\Models\ChecklistItem;
use Modules\Helpdesk\Models\Comment;
use Modules\Helpdesk\Models\Priority;
use Modules\Helpdesk\Models\Status;
use Modules\Helpdesk\Models\Ticket;
@@ -299,7 +300,7 @@ final class TicketShow extends Component
$this->hydrateTicketUsers($ticket);
$comments = \Modules\Helpdesk\Models\Comment::query()
$comments = Comment::query()
->where('ticket_id', $ticket->id)
->with(['user.company', 'attachments'])
->oldest()
+4 -2
View File
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Model;
final class AutomationRule extends Model
{
protected $table = 'helpdesk_automation_rules';
protected $fillable = ['company_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'];
protected $casts = ['company_id'=>'integer','match_category_id'=>'integer','set_priority_id'=>'integer','set_category_id'=>'integer','set_team_id'=>'integer','set_project_id'=>'integer','set_status_id'=>'integer','set_agent_id'=>'integer','is_active'=>'boolean','sort_order'=>'integer'];
protected $fillable = ['company_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'];
protected $casts = ['company_id' => 'integer', 'match_category_id' => 'integer', 'set_priority_id' => 'integer', 'set_category_id' => 'integer', 'set_team_id' => 'integer', 'set_project_id' => 'integer', 'set_status_id' => 'integer', 'set_agent_id' => 'integer', 'is_active' => 'boolean', 'sort_order' => 'integer'];
}
+14 -4
View File
@@ -10,8 +10,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
final class CannedResponse extends Model
{
protected $table = 'helpdesk_canned_responses';
protected $fillable = ['company_id','category_id','team_id','name','slug','visibility','subject','body','is_active','sort_order'];
protected $casts = ['company_id'=>'integer','category_id'=>'integer','team_id'=>'integer','is_active'=>'boolean','sort_order'=>'integer'];
public function category(): BelongsTo { return $this->belongsTo(Category::class, 'category_id'); }
public function team(): BelongsTo { return $this->belongsTo(Team::class, 'team_id'); }
protected $fillable = ['company_id', 'category_id', 'team_id', 'name', 'slug', 'visibility', 'subject', 'body', 'is_active', 'sort_order'];
protected $casts = ['company_id' => 'integer', 'category_id' => 'integer', 'team_id' => 'integer', 'is_active' => 'boolean', 'sort_order' => 'integer'];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
public function team(): BelongsTo
{
return $this->belongsTo(Team::class, 'team_id');
}
}
+9 -3
View File
@@ -10,7 +10,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
final class ChecklistItem extends Model
{
protected $table = 'helpdesk_checklist_items';
protected $fillable = ['ticket_id','template_id','title','description','is_completed','completed_by','completed_at','sort_order'];
protected $casts = ['ticket_id'=>'integer','template_id'=>'integer','is_completed'=>'boolean','completed_by'=>'integer','completed_at'=>'datetime','sort_order'=>'integer'];
public function ticket(): BelongsTo { return $this->belongsTo(Ticket::class, 'ticket_id'); }
protected $fillable = ['ticket_id', 'template_id', 'title', 'description', 'is_completed', 'completed_by', 'completed_at', 'sort_order'];
protected $casts = ['ticket_id' => 'integer', 'template_id' => 'integer', 'is_completed' => 'boolean', 'completed_by' => 'integer', 'completed_at' => 'datetime', 'sort_order' => 'integer'];
public function ticket(): BelongsTo
{
return $this->belongsTo(Ticket::class, 'ticket_id');
}
}
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Model;
final class ChecklistTemplate extends Model
{
protected $table = 'helpdesk_checklist_templates';
protected $fillable = ['company_id','category_id','project_id','name','slug','items','is_active'];
protected $casts = ['company_id'=>'integer','category_id'=>'integer','project_id'=>'integer','items'=>'array','is_active'=>'boolean'];
protected $fillable = ['company_id', 'category_id', 'project_id', 'name', 'slug', 'items', 'is_active'];
protected $casts = ['company_id' => 'integer', 'category_id' => 'integer', 'project_id' => 'integer', 'items' => 'array', 'is_active' => 'boolean'];
}
+1 -1
View File
@@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Modules\Helpdesk\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
+9 -3
View File
@@ -10,7 +10,13 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
final class Product extends Model
{
protected $table = 'helpdesk_products';
protected $fillable = ['company_id','name','slug','type','version','release_channel','description','is_active'];
protected $casts = ['company_id'=>'integer','is_active'=>'boolean'];
public function tickets(): HasMany { return $this->hasMany(Ticket::class, 'product_id'); }
protected $fillable = ['company_id', 'name', 'slug', 'type', 'version', 'release_channel', 'description', 'is_active'];
protected $casts = ['company_id' => 'integer', 'is_active' => 'boolean'];
public function tickets(): HasMany
{
return $this->hasMany(Ticket::class, 'product_id');
}
}
+14 -4
View File
@@ -10,8 +10,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
final class SlaPolicy extends Model
{
protected $table = 'helpdesk_sla_policies';
protected $fillable = ['company_id','priority_id','category_id','name','slug','first_response_minutes','resolution_minutes','business_hours_only','is_default','is_active'];
protected $casts = ['company_id'=>'integer','priority_id'=>'integer','category_id'=>'integer','first_response_minutes'=>'integer','resolution_minutes'=>'integer','business_hours_only'=>'boolean','is_default'=>'boolean','is_active'=>'boolean'];
public function priority(): BelongsTo { return $this->belongsTo(Priority::class, 'priority_id'); }
public function category(): BelongsTo { return $this->belongsTo(Category::class, 'category_id'); }
protected $fillable = ['company_id', 'priority_id', 'category_id', 'name', 'slug', 'first_response_minutes', 'resolution_minutes', 'business_hours_only', 'is_default', 'is_active'];
protected $casts = ['company_id' => 'integer', 'priority_id' => 'integer', 'category_id' => 'integer', 'first_response_minutes' => 'integer', 'resolution_minutes' => 'integer', 'business_hours_only' => 'boolean', 'is_default' => 'boolean', 'is_active' => 'boolean'];
public function priority(): BelongsTo
{
return $this->belongsTo(Priority::class, 'priority_id');
}
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
}
+9 -3
View File
@@ -10,7 +10,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
final class Tag extends Model
{
protected $table = 'helpdesk_tags';
protected $fillable = ['company_id','name','slug','color'];
protected $casts = ['company_id'=>'integer'];
public function tickets(): BelongsToMany { return $this->belongsToMany(Ticket::class, 'helpdesk_ticket_tag', 'tag_id', 'ticket_id'); }
protected $fillable = ['company_id', 'name', 'slug', 'color'];
protected $casts = ['company_id' => 'integer'];
public function tickets(): BelongsToMany
{
return $this->belongsToMany(Ticket::class, 'helpdesk_ticket_tag', 'tag_id', 'ticket_id');
}
}
-1
View File
@@ -114,7 +114,6 @@ final class Ticket extends Model
->oldest();
}
/** @return BelongsTo<SlaPolicy, Ticket> */
public function slaPolicy(): BelongsTo
{
+4 -2
View File
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Model;
final class TicketRating extends Model
{
protected $table = 'helpdesk_ticket_ratings';
protected $fillable = ['ticket_id','agent_id','team_id','category_id','rating','token','comment','rated_at'];
protected $casts = ['ticket_id'=>'integer','agent_id'=>'integer','team_id'=>'integer','category_id'=>'integer','rating'=>'integer','rated_at'=>'datetime'];
protected $fillable = ['ticket_id', 'agent_id', 'team_id', 'category_id', 'rating', 'token', 'comment', 'rated_at'];
protected $casts = ['ticket_id' => 'integer', 'agent_id' => 'integer', 'team_id' => 'integer', 'category_id' => 'integer', 'rating' => 'integer', 'rated_at' => 'datetime'];
}
+4 -2
View File
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Model;
final class TicketSlaEvent extends Model
{
protected $table = 'helpdesk_ticket_sla_events';
protected $fillable = ['ticket_id','sla_policy_id','event','due_at','occurred_at','breached','meta'];
protected $casts = ['ticket_id'=>'integer','sla_policy_id'=>'integer','due_at'=>'datetime','occurred_at'=>'datetime','breached'=>'boolean','meta'=>'array'];
protected $fillable = ['ticket_id', 'sla_policy_id', 'event', 'due_at', 'occurred_at', 'breached', 'meta'];
protected $casts = ['ticket_id' => 'integer', 'sla_policy_id' => 'integer', 'due_at' => 'datetime', 'occurred_at' => 'datetime', 'breached' => 'boolean', 'meta' => 'array'];
}
+1 -1
View File
@@ -5,8 +5,8 @@ declare(strict_types=1);
use Illuminate\Support\Facades\Route;
use Modules\Helpdesk\Http\Controllers\AttachmentDownloadController;
use Modules\Helpdesk\Http\Controllers\HelpdeskController;
use Modules\Helpdesk\Http\Controllers\TicketStoreController;
use Modules\Helpdesk\Http\Controllers\TicketControlsController;
use Modules\Helpdesk\Http\Controllers\TicketStoreController;
use Modules\Helpdesk\Http\Controllers\WorkflowOpenController;
use Modules\Helpdesk\Livewire\KanbanBoard;
use Modules\Helpdesk\Livewire\SettingsManager;
@@ -9,7 +9,6 @@ use Modules\Helpdesk\Database\Seeders\HelpdeskDatabaseSeeder as DatabaseHelpdesk
final class HelpdeskDatabaseSeeder extends Seeder
{
/** @return void */
public function run(): void
{
$this->call(DatabaseHelpdeskDatabaseSeeder::class);
@@ -66,5 +66,4 @@ final class CannedResponseRenderer
$ticket->setRelation('owner', $owner);
$ticket->setRelation('agent', $agent);
}
}
@@ -19,7 +19,7 @@ final class GitWebhookIngestionService
/**
* Persist supported Git provider commits and link them to matching Helpdesk ticket references.
*
* @param array<string, mixed> $payload
* @param array<string, mixed> $payload
* @return array{status: string, message: string, commit_count: int, linked_count: int, ignored_count: int}
*/
public function ingest(GitRepository $repository, array $payload, string $provider, ?string $deliveryId, ?string $event): array
@@ -102,8 +102,8 @@ final class GitWebhookIngestionService
/**
* Record a provider webhook acceptance, rejection or ignore decision for auditability.
*
* @param array{status: string, message: string, commit_count?: int, linked_count?: int, ignored_count?: int} $result
* @param array<string, mixed>|null $payload
* @param array{status: string, message: string, commit_count?: int, linked_count?: int, ignored_count?: int} $result
* @param array<string, mixed>|null $payload
*/
public function logWebhook(GitRepository $repository, string $provider, ?string $deliveryId, ?string $event, array $result, ?array $payload = null): void
{
@@ -158,9 +158,6 @@ final class GitWebhookIngestionService
};
}
/**
* @param mixed $value
*/
private function branchFromRef(mixed $value): ?string
{
$ref = $this->stringOrNull($value);
@@ -173,7 +170,7 @@ final class GitWebhookIngestionService
}
/**
* @param array<string, mixed> $payload
* @param array<string, mixed> $payload
* @return array<int, array<string, mixed>>
*/
private function commitsFromPayload(array $payload): array
@@ -208,9 +205,6 @@ final class GitWebhookIngestionService
return $query->first();
}
/**
* @param mixed $value
*/
private function parseTimestamp(mixed $value): ?CarbonImmutable
{
$timestamp = $this->stringOrNull($value);
@@ -226,9 +220,6 @@ final class GitWebhookIngestionService
}
}
/**
* @param mixed $value
*/
private function stringOrNull(mixed $value): ?string
{
if (! is_scalar($value)) {
@@ -9,10 +9,10 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Modules\Helpdesk\Models\Ticket;
use Modules\Helpdesk\Models\WorkflowLog;
use Modules\Helpdesk\Models\WorkflowTemplate;
use Illuminate\Support\Str;
use Throwable;
final class WorkflowNotificationService
@@ -88,6 +88,7 @@ if (! component) {
window.Livewire.find(component.getAttribute('wire:id')).set({$encodedProperty}, {$encodedValue});
JS);
}
private function setTicketShowProperty(Browser $browser, string $property, mixed $value): void
{
$encodedProperty = json_encode($property, JSON_THROW_ON_ERROR);
@@ -95,6 +95,7 @@ final class KanbanBoardTest extends TestCase
$this->assertSame($targetBoard->id, $ticket->board_id);
}
/** @test */
public function kanban_board_filters_tickets_to_the_selected_board_only(): void
{
@@ -135,5 +136,4 @@ final class KanbanBoardTest extends TestCase
->assertSee('Escalation board ticket')
->assertDontSee('Default board ticket');
}
}
@@ -13,9 +13,7 @@ use Modules\Helpdesk\Models\ChecklistItem;
use Modules\Helpdesk\Models\ChecklistTemplate;
use Modules\Helpdesk\Models\Product;
use Modules\Helpdesk\Models\SlaPolicy;
use Modules\Helpdesk\Models\Ticket;
use Modules\Helpdesk\Models\TicketSlaEvent;
use Modules\Helpdesk\Services\AutomationRuleService;
use Modules\Helpdesk\Services\ChecklistService;
use Modules\Helpdesk\Services\SlaService;
use Modules\Helpdesk\Services\TicketService;