added support for legacy tickets
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
return [
|
return [
|
||||||
'route_prefix' => env('HELPDESK_ROUTE_PREFIX', 'admin/helpdesk'),
|
'route_prefix' => env('HELPDESK_ROUTE_PREFIX', 'admin/helpdesk'),
|
||||||
'middleware' => ['web', 'auth'],
|
'middleware' => ['web', 'auth'],
|
||||||
|
'legacy_connection' => env('HELPDESK_LEGACY_DB_CONNECTION', config('database.default')),
|
||||||
'disk' => env('HELPDESK_ATTACHMENTS_DISK', 'local'),
|
'disk' => env('HELPDESK_ATTACHMENTS_DISK', 'local'),
|
||||||
'max_upload_kb' => (int) env('HELPDESK_MAX_UPLOAD_KB', 10240),
|
'max_upload_kb' => (int) env('HELPDESK_MAX_UPLOAD_KB', 10240),
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Helpdesk\Console;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Modules\Helpdesk\Models\LegacyCategory;
|
||||||
|
use Modules\Helpdesk\Models\LegacyComment;
|
||||||
|
use Modules\Helpdesk\Models\LegacyTicket;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
final class ImportLegacyHelpdeskCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'helpdesk:import-legacy {--connection= : Laravel database connection containing the old tickets tables} {--fresh : Clear previously imported legacy records first}';
|
||||||
|
protected $description = 'Import the old Helpdesk tickets and categories into the read-only Legacy System';
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$connectionName = (string) ($this->option('connection') ?: config('helpdesk.legacy_connection', config('database.default')));
|
||||||
|
$source = DB::connection($connectionName);
|
||||||
|
$schema = Schema::connection($connectionName);
|
||||||
|
|
||||||
|
foreach (['tickets', 'tickets_categories'] as $table) {
|
||||||
|
if (! $schema->hasTable($table)) {
|
||||||
|
$this->error("Source table {$table} was not found on connection [{$connectionName}].");
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('fresh')) {
|
||||||
|
LegacyComment::query()->delete();
|
||||||
|
LegacyTicket::query()->delete();
|
||||||
|
LegacyCategory::query()->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->importCategories($source);
|
||||||
|
$this->importTickets($source, $schema);
|
||||||
|
$this->importComments($source, $schema);
|
||||||
|
$this->refreshCategoryCounts();
|
||||||
|
|
||||||
|
$this->info(sprintf('Legacy import complete: %d tickets, %d categories, %d comments.', LegacyTicket::count(), LegacyCategory::count(), LegacyComment::count()));
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function importCategories(ConnectionInterface $source): void
|
||||||
|
{
|
||||||
|
$source->table('tickets_categories')->orderBy('id')->chunk(500, function ($rows): void {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
LegacyCategory::updateOrCreate(['legacy_id' => $row->id], ['name' => (string) $row->name, 'color' => $row->color ?? null]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function importTickets(ConnectionInterface $source, $schema): void
|
||||||
|
{
|
||||||
|
$columns = collect($schema->getColumnListing('tickets'));
|
||||||
|
$lookups = [
|
||||||
|
'category' => $this->lookup($source, $schema, 'tickets_categories'),
|
||||||
|
'status' => $this->lookup($source, $schema, 'tickets_statuses'),
|
||||||
|
'priority' => $this->lookup($source, $schema, 'tickets_priorities'),
|
||||||
|
'project' => $this->lookup($source, $schema, 'projects'),
|
||||||
|
'user' => $this->lookup($source, $schema, 'users'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$source->table('tickets')->orderBy('id')->chunk(250, function ($rows) use ($columns, $lookups): void {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$data = (array) $row;
|
||||||
|
LegacyTicket::updateOrCreate(['legacy_id' => $row->id], [
|
||||||
|
'reference' => $data['reference'] ?? null,
|
||||||
|
'subject' => (string) ($data['subject'] ?? 'Legacy ticket #'.$row->id),
|
||||||
|
'content' => $data['content'] ?? null,
|
||||||
|
'html_content' => $data['htmlcontent'] ?? null,
|
||||||
|
'legacy_category_id' => $data['category_id'] ?? null,
|
||||||
|
'category_name' => $lookups['category'][$data['category_id'] ?? 0] ?? null,
|
||||||
|
'status_name' => $lookups['status'][$data['status_id'] ?? 0] ?? null,
|
||||||
|
'priority_name' => $lookups['priority'][$data['priority_id'] ?? 0] ?? null,
|
||||||
|
'requester_name' => $lookups['user'][$data['user_id'] ?? 0] ?? null,
|
||||||
|
'agent_name' => $lookups['user'][$data['agent_id'] ?? 0] ?? null,
|
||||||
|
'project_name' => $lookups['project'][$data['project_id'] ?? 0] ?? null,
|
||||||
|
'legacy_created_at' => $data['created_at'] ?? null,
|
||||||
|
'legacy_updated_at' => $data['updated_at'] ?? null,
|
||||||
|
'completed_at' => $data['completed_at'] ?? null,
|
||||||
|
'archived_at' => $data['archived_at'] ?? null,
|
||||||
|
'legacy_data' => $data,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function importComments(ConnectionInterface $source, $schema): void
|
||||||
|
{
|
||||||
|
if (! $schema->hasTable('tickets_comments')) return;
|
||||||
|
$users = $this->lookup($source, $schema, 'users');
|
||||||
|
$source->table('tickets_comments')->orderBy('id')->chunk(500, function ($rows) use ($users): void {
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$data = (array) $row;
|
||||||
|
LegacyComment::updateOrCreate(['legacy_id' => $row->id], [
|
||||||
|
'legacy_ticket_id' => $data['ticket_id'],
|
||||||
|
'author_name' => $users[$data['user_id'] ?? 0] ?? null,
|
||||||
|
'content' => $data['content'] ?? null,
|
||||||
|
'html_content' => $data['htmlcontent'] ?? null,
|
||||||
|
'legacy_created_at' => $data['created_at'] ?? null,
|
||||||
|
'legacy_updated_at' => $data['updated_at'] ?? null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function lookup(ConnectionInterface $source, $schema, string $table): array
|
||||||
|
{
|
||||||
|
if (! $schema->hasTable($table)) return [];
|
||||||
|
$columns = $schema->getColumnListing($table);
|
||||||
|
$nameColumn = in_array('name', $columns, true) ? 'name' : (in_array('username', $columns, true) ? 'username' : null);
|
||||||
|
if ($nameColumn === null) return [];
|
||||||
|
try { return $source->table($table)->pluck($nameColumn, 'id')->map(fn ($v) => (string) $v)->all(); } catch (Throwable) { return []; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private function refreshCategoryCounts(): void
|
||||||
|
{
|
||||||
|
LegacyCategory::query()->each(function (LegacyCategory $category): void {
|
||||||
|
$category->update(['ticket_count' => LegacyTicket::query()->where('legacy_category_id', $category->legacy_id)->count()]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('helpdesk_legacy_categories', function (Blueprint $table): void {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('legacy_id')->unique();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('color', 32)->nullable();
|
||||||
|
$table->unsignedInteger('ticket_count')->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('helpdesk_legacy_tickets', function (Blueprint $table): void {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('legacy_id')->unique();
|
||||||
|
$table->string('reference')->nullable()->index();
|
||||||
|
$table->string('subject');
|
||||||
|
$table->longText('content')->nullable();
|
||||||
|
$table->longText('html_content')->nullable();
|
||||||
|
$table->unsignedBigInteger('legacy_category_id')->nullable()->index();
|
||||||
|
$table->string('category_name')->nullable();
|
||||||
|
$table->string('status_name')->nullable();
|
||||||
|
$table->string('priority_name')->nullable();
|
||||||
|
$table->string('requester_name')->nullable();
|
||||||
|
$table->string('agent_name')->nullable();
|
||||||
|
$table->string('project_name')->nullable();
|
||||||
|
$table->timestamp('legacy_created_at')->nullable()->index();
|
||||||
|
$table->timestamp('legacy_updated_at')->nullable();
|
||||||
|
$table->timestamp('completed_at')->nullable();
|
||||||
|
$table->timestamp('archived_at')->nullable();
|
||||||
|
$table->json('legacy_data')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('helpdesk_legacy_comments', function (Blueprint $table): void {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('legacy_id')->unique();
|
||||||
|
$table->unsignedBigInteger('legacy_ticket_id')->index();
|
||||||
|
$table->string('author_name')->nullable();
|
||||||
|
$table->longText('content')->nullable();
|
||||||
|
$table->longText('html_content')->nullable();
|
||||||
|
$table->timestamp('legacy_created_at')->nullable();
|
||||||
|
$table->timestamp('legacy_updated_at')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('helpdesk_legacy_comments');
|
||||||
|
Schema::dropIfExists('helpdesk_legacy_tickets');
|
||||||
|
Schema::dropIfExists('helpdesk_legacy_categories');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Helpdesk\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Modules\Helpdesk\Models\LegacyCategory;
|
||||||
|
use Modules\Helpdesk\Models\LegacyTicket;
|
||||||
|
|
||||||
|
final class LegacySystemController
|
||||||
|
{
|
||||||
|
public function tickets(Request $request): View
|
||||||
|
{
|
||||||
|
$search = trim((string) $request->query('search', ''));
|
||||||
|
$category = $request->integer('category');
|
||||||
|
|
||||||
|
$tickets = LegacyTicket::query()
|
||||||
|
->when($search !== '', fn ($query) => $query->where(function ($q) use ($search): void {
|
||||||
|
$q->where('reference', 'like', "%{$search}%")
|
||||||
|
->orWhere('subject', 'like', "%{$search}%")
|
||||||
|
->orWhere('requester_name', 'like', "%{$search}%");
|
||||||
|
}))
|
||||||
|
->when($category > 0, fn ($query) => $query->where('legacy_category_id', $category))
|
||||||
|
->orderByDesc('legacy_created_at')
|
||||||
|
->orderByDesc('legacy_id')
|
||||||
|
->paginate(30)
|
||||||
|
->withQueryString();
|
||||||
|
|
||||||
|
return view('helpdesk::legacy.tickets', [
|
||||||
|
'tickets' => $tickets,
|
||||||
|
'categories' => LegacyCategory::query()->orderBy('name')->get(),
|
||||||
|
'search' => $search,
|
||||||
|
'selectedCategory' => $category,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(LegacyTicket $ticket): View
|
||||||
|
{
|
||||||
|
$ticket->load('comments');
|
||||||
|
return view('helpdesk::legacy.show', compact('ticket'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function categories(): View
|
||||||
|
{
|
||||||
|
return view('helpdesk::legacy.categories', [
|
||||||
|
'categories' => LegacyCategory::query()->orderBy('name')->paginate(50),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Helpdesk\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
final class LegacyCategory extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'helpdesk_legacy_categories';
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Helpdesk\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
final class LegacyComment extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'helpdesk_legacy_comments';
|
||||||
|
protected $guarded = [];
|
||||||
|
protected $casts = ['legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime'];
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Helpdesk\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
|
final class LegacyTicket extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'helpdesk_legacy_tickets';
|
||||||
|
protected $guarded = [];
|
||||||
|
protected $casts = ['legacy_data' => 'array', 'legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime', 'completed_at' => 'datetime', 'archived_at' => 'datetime'];
|
||||||
|
|
||||||
|
public function comments(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(LegacyComment::class, 'legacy_ticket_id', 'legacy_id')->orderBy('legacy_created_at');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<x-layouts::app :title="__('Legacy Categories')">
|
||||||
|
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||||
|
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white"><p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System</p><h1 class="mt-2 text-3xl font-semibold tracking-tight">Legacy Categories</h1><p class="mt-2 text-sm text-blue-100/90">Categories retained from the previous Helpdesk.</p></div></div>
|
||||||
|
<div class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><table class="w-full text-left text-sm"><thead class="border-b border-zinc-200 bg-zinc-50 text-xs uppercase text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/60"><tr><th class="px-5 py-3">Category</th><th class="px-5 py-3">Legacy ID</th><th class="px-5 py-3 text-right">Tickets</th></tr></thead><tbody class="divide-y divide-zinc-200 dark:divide-zinc-800">@forelse($categories as $category)<tr><td class="px-5 py-4"><a class="font-semibold text-blue-600 hover:underline" href="{{ route('helpdesk.legacy.tickets', ['category' => $category->legacy_id]) }}" wire:navigate>{{ $category->name }}</a></td><td class="px-5 py-4 text-zinc-500">{{ $category->legacy_id }}</td><td class="px-5 py-4 text-right">{{ $category->ticket_count }}</td></tr>@empty<tr><td colspan="3" class="px-5 py-10 text-center text-zinc-500">No legacy categories have been imported.</td></tr>@endforelse</tbody></table>@if($categories->hasPages())<div class="border-t border-zinc-200 p-4 dark:border-zinc-700">{{ $categories->links() }}</div>@endif</div>
|
||||||
|
</div>
|
||||||
|
</x-layouts::app>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<x-layouts::app :title="$ticket->reference ?: 'Legacy Ticket #'.$ticket->legacy_id">
|
||||||
|
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||||
|
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white"><div class="flex items-start justify-between gap-4"><div><p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System · Read only</p><h1 class="mt-2 text-3xl font-semibold tracking-tight">{{ $ticket->subject }}</h1><p class="mt-2 text-sm text-blue-100/90">{{ $ticket->reference ?: 'Legacy ticket #'.$ticket->legacy_id }}</p></div><a href="{{ route('helpdesk.legacy.tickets') }}" wire:navigate class="hd-btn hd-btn-blue"><i class="fa-solid fa-arrow-left"></i><span>Legacy Tickets</span></a></div></div></div>
|
||||||
|
<div class="grid gap-6 xl:grid-cols-[1fr_320px]"><div class="space-y-6"><section class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 text-lg font-semibold">Original request</h2><div class="prose max-w-none dark:prose-invert">{!! $ticket->html_content ?: nl2br(e($ticket->content ?: 'No content recorded.')) !!}</div></section>@if($ticket->comments->isNotEmpty())<section class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 text-lg font-semibold">Comments</h2><div class="space-y-4">@foreach($ticket->comments as $comment)<article class="rounded-xl border border-zinc-200 p-4 dark:border-zinc-700"><div class="mb-2 flex justify-between text-xs text-zinc-500"><strong>{{ $comment->author_name ?: 'Legacy user' }}</strong><span>{{ $comment->legacy_created_at?->format('d M Y H:i') }}</span></div><div class="prose max-w-none text-sm dark:prose-invert">{!! $comment->html_content ?: nl2br(e($comment->content ?: '')) !!}</div></article>@endforeach</div></section>@endif</div><aside><div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 font-semibold">Legacy details</h2><dl class="space-y-3 text-sm">@foreach(['Category'=>$ticket->category_name,'Status'=>$ticket->status_name,'Priority'=>$ticket->priority_name,'Requester'=>$ticket->requester_name,'Agent'=>$ticket->agent_name,'Project'=>$ticket->project_name] as $label=>$value)<div><dt class="text-xs uppercase tracking-wide text-zinc-500">{{ $label }}</dt><dd class="mt-1 font-medium">{{ $value ?: '—' }}</dd></div>@endforeach<div><dt class="text-xs uppercase tracking-wide text-zinc-500">Created</dt><dd class="mt-1 font-medium">{{ $ticket->legacy_created_at?->format('d M Y H:i') ?: '—' }}</dd></div></dl></div></aside></div>
|
||||||
|
</div>
|
||||||
|
</x-layouts::app>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<x-layouts::app :title="__('Legacy Tickets')">
|
||||||
|
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||||
|
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||||
|
<div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white">
|
||||||
|
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System</p>
|
||||||
|
<h1 class="mt-2 text-3xl font-semibold tracking-tight">Legacy Tickets</h1>
|
||||||
|
<p class="mt-2 text-sm text-blue-100/90">Historical tickets from the previous Helpdesk. These records are read-only.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||||
|
<form class="grid gap-3 md:grid-cols-[1fr_260px_auto]" method="GET">
|
||||||
|
<input class="hd-ticket-search" type="search" name="search" value="{{ $search }}" placeholder="Search reference, subject or requester">
|
||||||
|
<select class="hd-select" name="category"><option value="">All legacy categories</option>@foreach($categories as $category)<option value="{{ $category->legacy_id }}" @selected($selectedCategory === $category->legacy_id)>{{ $category->name }}</option>@endforeach</select>
|
||||||
|
<button class="hd-btn hd-btn-blue" type="submit"><i class="fa-solid fa-magnifying-glass"></i><span>Search</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||||
|
<div class="overflow-x-auto"><table class="w-full text-left text-sm"><thead class="border-b border-zinc-200 bg-zinc-50 text-xs uppercase text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/60"><tr><th class="px-5 py-3">Reference</th><th class="px-5 py-3">Subject</th><th class="px-5 py-3">Category</th><th class="px-5 py-3">Status</th><th class="px-5 py-3">Requester</th><th class="px-5 py-3">Created</th></tr></thead><tbody class="divide-y divide-zinc-200 dark:divide-zinc-800">@forelse($tickets as $ticket)
|
||||||
|
<tr class="transition-colors dark:hover:bg-zinc-800/30">
|
||||||
|
<td class="px-5 py-4"><a class="font-semibold text-blue-600 hover:underline" href="{{ route('helpdesk.legacy.tickets.show', $ticket) }}" wire:navigate>{{ $ticket->reference ?: '#'.$ticket->legacy_id }}</a></td><td class="px-5 py-4 font-medium">{{ $ticket->subject }}</td><td class="px-5 py-4">{{ $ticket->category_name ?: '—' }}</td><td class="px-5 py-4">{{ $ticket->status_name ?: '—' }}</td><td class="px-5 py-4">{{ $ticket->requester_name ?: '—' }}</td><td class="px-5 py-4 text-zinc-500">{{ $ticket->legacy_created_at?->format('d M Y H:i') ?: '—' }}</td></tr>@empty<tr><td class="px-5 py-10 text-center text-zinc-500" colspan="6">No legacy tickets have been imported.</td></tr>@endforelse</tbody></table></div>
|
||||||
|
@if($tickets->hasPages())
|
||||||
|
<div class="flex items-center justify-between border-t border-zinc-800 px-5 py-4">
|
||||||
|
|
||||||
|
{{-- Previous --}}
|
||||||
|
@if($tickets->onFirstPage())
|
||||||
|
<span
|
||||||
|
class="inline-flex cursor-not-allowed items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-600"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-chevron-left mr-2 text-xs"></i>
|
||||||
|
Previous
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
<a
|
||||||
|
href="{{ $tickets->previousPageUrl() }}"
|
||||||
|
class="inline-flex items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-300 transition hover:border-zinc-600 hover:bg-zinc-800 hover:text-white"
|
||||||
|
wire:navigate
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-chevron-left mr-2 text-xs"></i>
|
||||||
|
Previous
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Page information --}}
|
||||||
|
<div class="text-sm text-zinc-500">
|
||||||
|
Page
|
||||||
|
<span class="font-semibold text-zinc-300">
|
||||||
|
{{ $tickets->currentPage() }}
|
||||||
|
</span>
|
||||||
|
of
|
||||||
|
<span class="font-semibold text-zinc-300">
|
||||||
|
{{ $tickets->lastPage() }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Next --}}
|
||||||
|
@if($tickets->hasMorePages())
|
||||||
|
<a
|
||||||
|
href="{{ $tickets->nextPageUrl() }}"
|
||||||
|
class="inline-flex items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-300 transition hover:border-zinc-600 hover:bg-zinc-800 hover:text-white"
|
||||||
|
wire:navigate
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
<i class="fa-solid fa-chevron-right ml-2 text-xs"></i>
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<span
|
||||||
|
class="inline-flex cursor-not-allowed items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-600"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
<i class="fa-solid fa-chevron-right ml-2 text-xs"></i>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-layouts::app>
|
||||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Modules\Helpdesk\Http\Controllers\AttachmentDownloadController;
|
use Modules\Helpdesk\Http\Controllers\AttachmentDownloadController;
|
||||||
use Modules\Helpdesk\Http\Controllers\HelpdeskController;
|
use Modules\Helpdesk\Http\Controllers\HelpdeskController;
|
||||||
|
use Modules\Helpdesk\Http\Controllers\LegacySystemController;
|
||||||
use Modules\Helpdesk\Http\Controllers\TicketAttachmentStoreController;
|
use Modules\Helpdesk\Http\Controllers\TicketAttachmentStoreController;
|
||||||
use Modules\Helpdesk\Http\Controllers\TicketBoardController;
|
use Modules\Helpdesk\Http\Controllers\TicketBoardController;
|
||||||
use Modules\Helpdesk\Http\Controllers\TicketCommentDeleteController;
|
use Modules\Helpdesk\Http\Controllers\TicketCommentDeleteController;
|
||||||
@@ -28,6 +29,10 @@ Route::get('/', HelpdeskController::class)->name('index');
|
|||||||
Route::get('/settings', SettingsManager::class)->name('settings');
|
Route::get('/settings', SettingsManager::class)->name('settings');
|
||||||
Route::get('/kanban', KanbanBoard::class)->name('kanban');
|
Route::get('/kanban', KanbanBoard::class)->name('kanban');
|
||||||
|
|
||||||
|
Route::get('/legacy/tickets', [LegacySystemController::class, 'tickets'])->name('legacy.tickets');
|
||||||
|
Route::get('/legacy/tickets/{ticket}', [LegacySystemController::class, 'show'])->name('legacy.tickets.show');
|
||||||
|
Route::get('/legacy/categories', [LegacySystemController::class, 'categories'])->name('legacy.categories');
|
||||||
|
|
||||||
Route::get('/tickets', TicketIndex::class)->name('tickets.index');
|
Route::get('/tickets', TicketIndex::class)->name('tickets.index');
|
||||||
Route::get('/tickets/archived', ArchivedTicketIndex::class)->name('tickets.archived');
|
Route::get('/tickets/archived', ArchivedTicketIndex::class)->name('tickets.archived');
|
||||||
Route::post('/tickets', TicketStoreController::class)->name('tickets.store');
|
Route::post('/tickets', TicketStoreController::class)->name('tickets.store');
|
||||||
|
|||||||
+14
-1
@@ -83,7 +83,20 @@ return [
|
|||||||
Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||||
]) : [],
|
]) : [],
|
||||||
],
|
],
|
||||||
|
'helpdesk_legacy' => [
|
||||||
|
'driver' => 'mysql',
|
||||||
|
'host' => env('LEGACY_DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('LEGACY_DB_PORT', '3306'),
|
||||||
|
'database' => env('LEGACY_DB_DATABASE'),
|
||||||
|
'username' => env('LEGACY_DB_USERNAME'),
|
||||||
|
'password' => env('LEGACY_DB_PASSWORD'),
|
||||||
|
'unix_socket' => env('LEGACY_DB_SOCKET', ''),
|
||||||
|
'charset' => 'utf8mb4',
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'prefix' => '',
|
||||||
|
'strict' => true,
|
||||||
|
'engine' => null,
|
||||||
|
],
|
||||||
'pgsql' => [
|
'pgsql' => [
|
||||||
'driver' => 'pgsql',
|
'driver' => 'pgsql',
|
||||||
'url' => env('DB_URL'),
|
'url' => env('DB_URL'),
|
||||||
|
|||||||
@@ -2476,3 +2476,23 @@ html:not(.dark) .hd-appearance-choice.is-active { background: #fff; color: #1118
|
|||||||
.hd-account-settings-form { max-width: none; }
|
.hd-account-settings-form { max-width: none; }
|
||||||
.hd-ios12 .hd-settings-section-card { width: calc(50% - 8px) !important; min-width: 0 !important; }
|
.hd-ios12 .hd-settings-section-card { width: calc(50% - 8px) !important; min-width: 0 !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Legacy ticket table hover */
|
||||||
|
.legacy-tickets-table tbody tr {
|
||||||
|
transition: background-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legacy-tickets-table tbody tr:hover,
|
||||||
|
.legacy-tickets-table tbody tr:hover > td {
|
||||||
|
background-color: rgba(255, 255, 255, 0.035) !important;
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legacy-tickets-table tbody tr:hover td,
|
||||||
|
.legacy-tickets-table tbody tr:hover td:not(:first-child) {
|
||||||
|
color: var(--hd-text-primary, #e5e7eb) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legacy-tickets-table tbody tr:hover a {
|
||||||
|
color: #3b82f6 !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -143,6 +143,12 @@
|
|||||||
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4h18v16H3V4zm2 2v12h6V6H5zm8 0v12h6V6h-6z"/></svg><span>Kanban</span></a>@endif
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4h18v16H3V4zm2 2v12h6V6H5zm8 0v12h6V6h-6z"/></svg><span>Kanban</span></a>@endif
|
||||||
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.7 2h2.6l.6 2.3c.5.2 1 .5 1.5.9l2.3-.7 1.3 2.3-1.7 1.6c.1.5.2 1.1.2 1.6s-.1 1.1-.2 1.6l1.7 1.6-1.3 2.3-2.3-.7c-.5.4-1 .7-1.5.9l-.6 2.3h-2.6l-.6-2.3c-.5-.2-1-.5-1.5-.9l-2.3.7L5 13.2l1.7-1.6A6 6 0 0 1 6.5 10c0-.5.1-1.1.2-1.6L5 6.8l1.3-2.3 2.3.7c.5-.4 1-.7 1.5-.9L10.7 2zM12 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/></svg><span>Settings</span></a>@endif
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.7 2h2.6l.6 2.3c.5.2 1 .5 1.5.9l2.3-.7 1.3 2.3-1.7 1.6c.1.5.2 1.1.2 1.6s-.1 1.1-.2 1.6l1.7 1.6-1.3 2.3-2.3-.7c-.5.4-1 .7-1.5.9l-.6 2.3h-2.6l-.6-2.3c-.5-.2-1-.5-1.5-.9l-2.3.7L5 13.2l1.7-1.6A6 6 0 0 1 6.5 10c0-.5.1-1.1.2-1.6L5 6.8l1.3-2.3 2.3.7c.5-.4 1-.7 1.5-.9L10.7 2zM12 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/></svg><span>Settings</span></a>@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if(Route::has('helpdesk.legacy.tickets'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Legacy System</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.tickets*') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.tickets') }}" wire:navigate><i class="fa-solid fa-clock-rotate-left" aria-hidden="true"></i><span>Legacy Tickets</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.categories') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.categories') }}" wire:navigate><i class="fa-solid fa-folder-tree" aria-hidden="true"></i><span>Legacy Categories</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 2h8l4 4v16H6V2zm7 1.8V7h3.2L13 3.8zM9 11v1.5h6V11H9zm0 3.5V16h6v-1.5H9z"/></svg><span>Documents</span></a>
|
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 2h8l4 4v16H6V2zm7 1.8V7h3.2L13 3.8zM9 11v1.5h6V11H9zm0 3.5V16h6v-1.5H9z"/></svg><span>Documents</span></a>
|
||||||
|
|||||||
@@ -143,6 +143,12 @@
|
|||||||
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4h18v16H3V4zm2 2v12h6V6H5zm8 0v12h6V6h-6z"/></svg><span>Kanban</span></a>@endif
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 4h18v16H3V4zm2 2v12h6V6H5zm8 0v12h6V6h-6z"/></svg><span>Kanban</span></a>@endif
|
||||||
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.7 2h2.6l.6 2.3c.5.2 1 .5 1.5.9l2.3-.7 1.3 2.3-1.7 1.6c.1.5.2 1.1.2 1.6s-.1 1.1-.2 1.6l1.7 1.6-1.3 2.3-2.3-.7c-.5.4-1 .7-1.5.9l-.6 2.3h-2.6l-.6-2.3c-.5-.2-1-.5-1.5-.9l-2.3.7L5 13.2l1.7-1.6A6 6 0 0 1 6.5 10c0-.5.1-1.1.2-1.6L5 6.8l1.3-2.3 2.3.7c.5-.4 1-.7 1.5-.9L10.7 2zM12 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/></svg><span>Settings</span></a>@endif
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.7 2h2.6l.6 2.3c.5.2 1 .5 1.5.9l2.3-.7 1.3 2.3-1.7 1.6c.1.5.2 1.1.2 1.6s-.1 1.1-.2 1.6l1.7 1.6-1.3 2.3-2.3-.7c-.5.4-1 .7-1.5.9l-.6 2.3h-2.6l-.6-2.3c-.5-.2-1-.5-1.5-.9l-2.3.7L5 13.2l1.7-1.6A6 6 0 0 1 6.5 10c0-.5.1-1.1.2-1.6L5 6.8l1.3-2.3 2.3.7c.5-.4 1-.7 1.5-.9L10.7 2zM12 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/></svg><span>Settings</span></a>@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if(Route::has('helpdesk.legacy.tickets'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Legacy System</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.tickets*') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.tickets') }}" wire:navigate><i class="fa-solid fa-clock-rotate-left" aria-hidden="true"></i><span>Legacy Tickets</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.categories') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.categories') }}" wire:navigate><i class="fa-solid fa-folder-tree" aria-hidden="true"></i><span>Legacy Categories</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 2h8l4 4v16H6V2zm7 1.8V7h3.2L13 3.8zM9 11v1.5h6V11H9zm0 3.5V16h6v-1.5H9z"/></svg><span>Documents</span></a>
|
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><svg class="hd-svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 2h8l4 4v16H6V2zm7 1.8V7h3.2L13 3.8zM9 11v1.5h6V11H9zm0 3.5V16h6v-1.5H9z"/></svg><span>Documents</span></a>
|
||||||
|
|||||||
@@ -143,6 +143,12 @@
|
|||||||
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><i class="fa-solid fa-table-columns" aria-hidden="true"></i><span>Kanban</span></a>@endif
|
@if(Route::has('helpdesk.kanban'))<a class="hd-nav-link hd-nav-link--kanban {{ request()->routeIs('helpdesk.kanban') ? 'is-active' : '' }}" href="{{ route('helpdesk.kanban') }}" wire:navigate><i class="fa-solid fa-table-columns" aria-hidden="true"></i><span>Kanban</span></a>@endif
|
||||||
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><i class="fa-solid fa-gear" aria-hidden="true"></i><span>Settings</span></a>@endif
|
@if(Route::has('helpdesk.settings'))<a class="hd-nav-link hd-nav-link--settings {{ request()->routeIs('helpdesk.settings*') ? 'is-active' : '' }}" href="{{ route('helpdesk.settings') }}" wire:navigate><i class="fa-solid fa-gear" aria-hidden="true"></i><span>Settings</span></a>@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if(Route::has('helpdesk.legacy.tickets'))
|
||||||
|
<div class="hd-nav-section"><div class="hd-nav-heading">Legacy System</div>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.tickets*') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.tickets') }}" wire:navigate><i class="fa-solid fa-clock-rotate-left" aria-hidden="true"></i><span>Legacy Tickets</span></a>
|
||||||
|
<a class="hd-nav-link {{ request()->routeIs('helpdesk.legacy.categories') ? 'is-active' : '' }}" style="--hd-nav-accent:#64748b;--hd-nav-accent-rgb:100,116,139" href="{{ route('helpdesk.legacy.categories') }}" wire:navigate><i class="fa-solid fa-folder-tree" aria-hidden="true"></i><span>Legacy Categories</span></a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
@if(Route::has('documentation.index') || Route::has('documentation.documents.index'))
|
||||||
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
<div class="hd-nav-section"><div class="hd-nav-heading">Documentation</div>
|
||||||
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><i class="fa-solid fa-file-lines" aria-hidden="true"></i><span>Documents</span></a>
|
<a class="hd-nav-link hd-nav-link--documents {{ request()->routeIs('documentation.documents.*') || request()->routeIs('documentation.index') ? 'is-active' : '' }}" href="{{ Route::has('documentation.documents.index') ? route('documentation.documents.index') : route('documentation.index') }}" wire:navigate><i class="fa-solid fa-file-lines" aria-hidden="true"></i><span>Documents</span></a>
|
||||||
|
|||||||
@@ -370,3 +370,11 @@ promiseReactionJob@[native code] {"url":"https://helpdesk.vm/dashboard","user_ag
|
|||||||
[2026-09-28 08:46:40] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:46:39.947Z"}
|
[2026-09-28 08:46:40] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:46:39.947Z"}
|
||||||
[2026-09-28 08:48:45] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:48:45.326Z"}
|
[2026-09-28 08:48:45] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:48:45.326Z"}
|
||||||
[2026-09-28 08:50:56] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:50:56.465Z"}
|
[2026-09-28 08:50:56] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T08:50:56.465Z"}
|
||||||
|
[2026-09-28 09:25:11] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/dashboard","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:25:11.035Z"}
|
||||||
|
[2026-09-28 09:25:23] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:25:22.956Z"}
|
||||||
|
[2026-09-28 09:38:32] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:38:32.132Z"}
|
||||||
|
[2026-09-28 09:39:05] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets?page=2","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:39:05.417Z"}
|
||||||
|
[2026-09-28 09:39:08] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets?page=3","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:39:08.531Z"}
|
||||||
|
[2026-09-28 09:42:15] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:42:15.037Z"}
|
||||||
|
[2026-09-28 09:44:20] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:44:20.199Z"}
|
||||||
|
[2026-09-28 09:45:34] local.INFO: Helpdesk module assets loaded {"url":"https://helpdesk.vm/admin/helpdesk/legacy/tickets?page=18","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36 Edg/154.0.0.0","timestamp":"2026-09-28T09:45:34.462Z"}
|
||||||
|
|||||||
Reference in New Issue
Block a user