added support for legacy tickets, fixed switching of modes and also style updates
This commit is contained in:
@@ -5,31 +5,19 @@ declare(strict_types=1);
|
|||||||
namespace Modules\Documentation\Console;
|
namespace Modules\Documentation\Console;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
use Modules\Documentation\Models\DocumentationCategory;
|
use Modules\Documentation\Models\DocumentationCategory;
|
||||||
|
|
||||||
use Modules\Documentation\Models\DocumentationDocument;
|
use Modules\Documentation\Models\DocumentationDocument;
|
||||||
|
|
||||||
use SplFileInfo;
|
use SplFileInfo;
|
||||||
|
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
final class ImportDocumentationCommand extends Command
|
final class ImportDocumentationCommand extends Command
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* The console command signature.
|
* The console command signature.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected $signature = 'helpdesk:import-documentation
|
protected $signature = 'helpdesk:import-documentation
|
||||||
|
|
||||||
{path? : Directory containing Markdown files; defaults to the bundled Sentinel documentation}
|
{path? : Directory containing Markdown files; defaults to the bundled Sentinel documentation}
|
||||||
@@ -39,21 +27,14 @@ final class ImportDocumentationCommand extends Command
|
|||||||
{--fresh : Remove previously imported documents in this category before importing}';
|
{--fresh : Remove previously imported documents in this category before importing}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected $description = 'Import Markdown documentation into the Helpdesk Documentation module.';
|
protected $description = 'Import Markdown documentation into the Helpdesk Documentation module.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$path = $this->resolvePath();
|
$path = $this->resolvePath();
|
||||||
@@ -164,7 +145,7 @@ final class ImportDocumentationCommand extends Command
|
|||||||
|
|
||||||
$this->importFile($category, $file, $path);
|
$this->importFile($category, $file, $path);
|
||||||
|
|
||||||
++$imported;
|
$imported++;
|
||||||
|
|
||||||
$progress->advance();
|
$progress->advance();
|
||||||
|
|
||||||
@@ -217,13 +198,9 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Resolve the requested documentation source directory.
|
* Resolve the requested documentation source directory.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function resolvePath(): string
|
private function resolvePath(): string
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$argument = $this->argument('path');
|
$argument = $this->argument('path');
|
||||||
@@ -247,17 +224,13 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Find Markdown files recursively.
|
* Find Markdown files recursively.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
* @return list<SplFileInfo>
|
* @return list<SplFileInfo>
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function markdownFiles(string $path): array
|
private function markdownFiles(string $path): array
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$finder = Finder::create()
|
$finder = Finder::create()
|
||||||
@@ -273,7 +246,6 @@ final class ImportDocumentationCommand extends Command
|
|||||||
->sortByName();
|
->sortByName();
|
||||||
|
|
||||||
/** @var list<SplFileInfo> $files */
|
/** @var list<SplFileInfo> $files */
|
||||||
|
|
||||||
$files = iterator_to_array($finder, false);
|
$files = iterator_to_array($finder, false);
|
||||||
|
|
||||||
return $files;
|
return $files;
|
||||||
@@ -281,11 +253,8 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Import one Markdown document.
|
* Import one Markdown document.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function importFile(
|
private function importFile(
|
||||||
|
|
||||||
DocumentationCategory $category,
|
DocumentationCategory $category,
|
||||||
@@ -301,7 +270,6 @@ final class ImportDocumentationCommand extends Command
|
|||||||
if ($realPath === false || ! is_readable($realPath)) {
|
if ($realPath === false || ! is_readable($realPath)) {
|
||||||
|
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
|
|
||||||
sprintf('Unable to read documentation file: %s', $file->getPathname()),
|
sprintf('Unable to read documentation file: %s', $file->getPathname()),
|
||||||
|
|
||||||
);
|
);
|
||||||
@@ -313,7 +281,6 @@ final class ImportDocumentationCommand extends Command
|
|||||||
if ($body === false) {
|
if ($body === false) {
|
||||||
|
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException(
|
||||||
|
|
||||||
sprintf('Unable to read documentation file: %s', $realPath),
|
sprintf('Unable to read documentation file: %s', $realPath),
|
||||||
|
|
||||||
);
|
);
|
||||||
@@ -377,13 +344,9 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Extract the first Markdown H1 heading.
|
* Extract the first Markdown H1 heading.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function extractTitle(string $body, SplFileInfo $file): string
|
private function extractTitle(string $body, SplFileInfo $file): string
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (preg_match('/^\s*#\s+(.+?)\s*$/m', $body, $matches) === 1) {
|
if (preg_match('/^\s*#\s+(.+?)\s*$/m', $body, $matches) === 1) {
|
||||||
@@ -417,13 +380,9 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Extract a useful summary from the first normal Markdown paragraph.
|
* Extract a useful summary from the first normal Markdown paragraph.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function extractSummary(string $body): ?string
|
private function extractSummary(string $body): ?string
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$lines = preg_split('/\R/', $body);
|
$lines = preg_split('/\R/', $body);
|
||||||
@@ -507,13 +466,9 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Generate a stable globally unique slug from the source path.
|
* Generate a stable globally unique slug from the source path.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function makeSlug(string $relativePath, string $title): string
|
private function makeSlug(string $relativePath, string $title): string
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$withoutExtension = preg_replace(
|
$withoutExtension = preg_replace(
|
||||||
@@ -545,13 +500,9 @@ final class ImportDocumentationCommand extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
* Remove a UTF-8 byte-order mark.
|
* Remove a UTF-8 byte-order mark.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function stripBom(string $contents): string
|
private function stripBom(string $contents): string
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (str_starts_with($contents, "\xEF\xBB\xBF")) {
|
if (str_starts_with($contents, "\xEF\xBB\xBF")) {
|
||||||
@@ -563,6 +514,4 @@ final class ImportDocumentationCommand extends Command
|
|||||||
return $contents;
|
return $contents;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ class DocumentationCategory extends Model
|
|||||||
* Active category scope.
|
* Active category scope.
|
||||||
*
|
*
|
||||||
* @param Builder<DocumentationCategory> $query
|
* @param Builder<DocumentationCategory> $query
|
||||||
*
|
|
||||||
* @return Builder<DocumentationCategory>
|
* @return Builder<DocumentationCategory>
|
||||||
*/
|
*/
|
||||||
public function scopeActive(Builder $query): Builder
|
public function scopeActive(Builder $query): Builder
|
||||||
@@ -79,7 +78,6 @@ class DocumentationCategory extends Model
|
|||||||
* Ordered category scope.
|
* Ordered category scope.
|
||||||
*
|
*
|
||||||
* @param Builder<DocumentationCategory> $query
|
* @param Builder<DocumentationCategory> $query
|
||||||
*
|
|
||||||
* @return Builder<DocumentationCategory>
|
* @return Builder<DocumentationCategory>
|
||||||
*/
|
*/
|
||||||
public function scopeOrdered(Builder $query): Builder
|
public function scopeOrdered(Builder $query): Builder
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ class DocumentationDocument extends Model
|
|||||||
* Published document scope.
|
* Published document scope.
|
||||||
*
|
*
|
||||||
* @param Builder<DocumentationDocument> $query
|
* @param Builder<DocumentationDocument> $query
|
||||||
*
|
|
||||||
* @return Builder<DocumentationDocument>
|
* @return Builder<DocumentationDocument>
|
||||||
*/
|
*/
|
||||||
public function scopePublished(Builder $query): Builder
|
public function scopePublished(Builder $query): Builder
|
||||||
@@ -114,7 +113,6 @@ class DocumentationDocument extends Model
|
|||||||
* Featured document scope.
|
* Featured document scope.
|
||||||
*
|
*
|
||||||
* @param Builder<DocumentationDocument> $query
|
* @param Builder<DocumentationDocument> $query
|
||||||
*
|
|
||||||
* @return Builder<DocumentationDocument>
|
* @return Builder<DocumentationDocument>
|
||||||
*/
|
*/
|
||||||
public function scopeFeatured(Builder $query): Builder
|
public function scopeFeatured(Builder $query): Builder
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace Modules\Documentation\Providers;
|
|||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Modules\Documentation\Console\ImportDocumentationCommand;
|
||||||
|
|
||||||
final class DocumentationServiceProvider extends ServiceProvider
|
final class DocumentationServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@@ -43,7 +44,7 @@ final class DocumentationServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->commands([
|
$this->commands([
|
||||||
\Modules\Documentation\Console\ImportDocumentationCommand::class,
|
ImportDocumentationCommand::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ namespace Modules\Documentation\Tests\Feature;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Modules\Documentation\Models\DocumentationAttachment;
|
|
||||||
use Modules\Documentation\Models\DocumentationDocument;
|
use Modules\Documentation\Models\DocumentationDocument;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class DocumentationModuleTest extends TestCase
|
|||||||
* Add a CSRF token for projects that keep web middleware enabled during tests.
|
* Add a CSRF token for projects that keep web middleware enabled during tests.
|
||||||
*
|
*
|
||||||
* @param array<string, mixed> $payload
|
* @param array<string, mixed> $payload
|
||||||
*
|
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
private function csrfPayload(array $payload): array
|
private function csrfPayload(array $payload): array
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use Throwable;
|
|||||||
final class ImportLegacyHelpdeskCommand extends Command
|
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 $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';
|
protected $description = 'Import the old Helpdesk tickets and categories into the read-only Legacy System';
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
@@ -33,6 +34,7 @@ final class ImportLegacyHelpdeskCommand extends Command
|
|||||||
foreach (['tickets', 'tickets_categories'] as $table) {
|
foreach (['tickets', 'tickets_categories'] as $table) {
|
||||||
if (! $schema->hasTable($table)) {
|
if (! $schema->hasTable($table)) {
|
||||||
$this->error("Source table {$table} was not found on connection [{$connectionName}].");
|
$this->error("Source table {$table} was not found on connection [{$connectionName}].");
|
||||||
|
|
||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +51,7 @@ final class ImportLegacyHelpdeskCommand extends Command
|
|||||||
$this->refreshCategoryCounts();
|
$this->refreshCategoryCounts();
|
||||||
|
|
||||||
$this->info(sprintf('Legacy import complete: %d tickets, %d categories, %d comments.', LegacyTicket::count(), LegacyCategory::count(), LegacyComment::count()));
|
$this->info(sprintf('Legacy import complete: %d tickets, %d categories, %d comments.', LegacyTicket::count(), LegacyCategory::count(), LegacyComment::count()));
|
||||||
|
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +75,7 @@ final class ImportLegacyHelpdeskCommand extends Command
|
|||||||
'user' => $this->lookup($source, $schema, 'users'),
|
'user' => $this->lookup($source, $schema, 'users'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$source->table('tickets')->orderBy('id')->chunk(250, function ($rows) use ($columns, $lookups): void {
|
$source->table('tickets')->orderBy('id')->chunk(250, function ($rows) use ($lookups): void {
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$data = (array) $row;
|
$data = (array) $row;
|
||||||
LegacyTicket::updateOrCreate(['legacy_id' => $row->id], [
|
LegacyTicket::updateOrCreate(['legacy_id' => $row->id], [
|
||||||
@@ -99,7 +102,9 @@ final class ImportLegacyHelpdeskCommand extends Command
|
|||||||
|
|
||||||
private function importComments(ConnectionInterface $source, $schema): void
|
private function importComments(ConnectionInterface $source, $schema): void
|
||||||
{
|
{
|
||||||
if (! $schema->hasTable('tickets_comments')) return;
|
if (! $schema->hasTable('tickets_comments')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$users = $this->lookup($source, $schema, 'users');
|
$users = $this->lookup($source, $schema, 'users');
|
||||||
$source->table('tickets_comments')->orderBy('id')->chunk(500, function ($rows) use ($users): void {
|
$source->table('tickets_comments')->orderBy('id')->chunk(500, function ($rows) use ($users): void {
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
@@ -118,11 +123,19 @@ final class ImportLegacyHelpdeskCommand extends Command
|
|||||||
|
|
||||||
private function lookup(ConnectionInterface $source, $schema, string $table): array
|
private function lookup(ConnectionInterface $source, $schema, string $table): array
|
||||||
{
|
{
|
||||||
if (! $schema->hasTable($table)) return [];
|
if (! $schema->hasTable($table)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
$columns = $schema->getColumnListing($table);
|
$columns = $schema->getColumnListing($table);
|
||||||
$nameColumn = in_array('name', $columns, true) ? 'name' : (in_array('username', $columns, true) ? 'username' : null);
|
$nameColumn = in_array('name', $columns, true) ? 'name' : (in_array('username', $columns, true) ? 'username' : null);
|
||||||
if ($nameColumn === null) return [];
|
if ($nameColumn === null) {
|
||||||
try { return $source->table($table)->pluck($nameColumn, 'id')->map(fn ($v) => (string) $v)->all(); } catch (Throwable) { return []; }
|
return [];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return $source->table($table)->pluck($nameColumn, 'id')->map(fn ($v) => (string) $v)->all();
|
||||||
|
} catch (Throwable) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function refreshCategoryCounts(): void
|
private function refreshCategoryCounts(): void
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,8 @@ use Illuminate\Database\Migrations\Migration;
|
|||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration {
|
return new class extends Migration
|
||||||
|
{
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('helpdesk_legacy_categories', function (Blueprint $table): void {
|
Schema::create('helpdesk_legacy_categories', function (Blueprint $table): void {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ final class LegacySystemController
|
|||||||
public function show(LegacyTicket $ticket): View
|
public function show(LegacyTicket $ticket): View
|
||||||
{
|
{
|
||||||
$ticket->load('comments');
|
$ticket->load('comments');
|
||||||
|
|
||||||
return view('helpdesk::legacy.show', compact('ticket'));
|
return view('helpdesk::legacy.show', compact('ticket'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ final class ArchivedTicketIndex extends Component
|
|||||||
public string $search = '';
|
public string $search = '';
|
||||||
|
|
||||||
public bool $deleteModalOpen = false;
|
public bool $deleteModalOpen = false;
|
||||||
|
|
||||||
public ?int $pendingDeleteTicketId = null;
|
public ?int $pendingDeleteTicketId = null;
|
||||||
|
|
||||||
public ?string $pendingDeleteTicketReference = null;
|
public ?string $pendingDeleteTicketReference = null;
|
||||||
|
|
||||||
public ?string $pendingDeleteTicketSubject = null;
|
public ?string $pendingDeleteTicketSubject = null;
|
||||||
|
|
||||||
public function updatedSearch(): void
|
public function updatedSearch(): void
|
||||||
@@ -75,6 +78,7 @@ final class ArchivedTicketIndex extends Component
|
|||||||
{
|
{
|
||||||
if ($this->pendingDeleteTicketId === null) {
|
if ($this->pendingDeleteTicketId === null) {
|
||||||
$this->resetDeleteState();
|
$this->resetDeleteState();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ final class HelpdeskDashboardWidget extends Component
|
|||||||
|
|
||||||
public function updatedDays(): void
|
public function updatedDays(): void
|
||||||
{
|
{
|
||||||
if (! in_array($this->days, [7, 14, 30], true)) $this->days = 7;
|
if (! in_array($this->days, [7, 14, 30], true)) {
|
||||||
|
$this->days = 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): View
|
public function render(): View
|
||||||
@@ -33,6 +35,7 @@ final class HelpdeskDashboardWidget extends Component
|
|||||||
$trendRows = (clone $base)->where('created_at', '>=', now()->subDays($this->days - 1)->startOfDay())->get(['created_at', 'completed_at']);
|
$trendRows = (clone $base)->where('created_at', '>=', now()->subDays($this->days - 1)->startOfDay())->get(['created_at', 'completed_at']);
|
||||||
$trend = collect($period)->map(function ($date) use ($trendRows): array {
|
$trend = collect($period)->map(function ($date) use ($trendRows): array {
|
||||||
$day = $date->toDateString();
|
$day = $date->toDateString();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'label' => $date->format('M j'),
|
'label' => $date->format('M j'),
|
||||||
'created' => $trendRows->filter(fn ($ticket) => optional($ticket->created_at)->toDateString() === $day)->count(),
|
'created' => $trendRows->filter(fn ($ticket) => optional($ticket->created_at)->toDateString() === $day)->count(),
|
||||||
|
|||||||
@@ -39,17 +39,29 @@ final class SettingsManager extends Component
|
|||||||
public bool $teamModalOpen = false;
|
public bool $teamModalOpen = false;
|
||||||
|
|
||||||
public bool $statusModalOpen = false;
|
public bool $statusModalOpen = false;
|
||||||
|
|
||||||
public bool $priorityModalOpen = false;
|
public bool $priorityModalOpen = false;
|
||||||
|
|
||||||
public bool $categoryModalOpen = false;
|
public bool $categoryModalOpen = false;
|
||||||
|
|
||||||
public bool $projectModalOpen = false;
|
public bool $projectModalOpen = false;
|
||||||
|
|
||||||
public bool $boardModalOpen = false;
|
public bool $boardModalOpen = false;
|
||||||
|
|
||||||
public bool $repositoryModalOpen = false;
|
public bool $repositoryModalOpen = false;
|
||||||
|
|
||||||
public bool $workflowModalOpen = false;
|
public bool $workflowModalOpen = false;
|
||||||
|
|
||||||
public bool $cannedModalOpen = false;
|
public bool $cannedModalOpen = false;
|
||||||
|
|
||||||
public bool $slaModalOpen = false;
|
public bool $slaModalOpen = false;
|
||||||
|
|
||||||
public bool $automationModalOpen = false;
|
public bool $automationModalOpen = false;
|
||||||
|
|
||||||
public bool $checklistModalOpen = false;
|
public bool $checklistModalOpen = false;
|
||||||
|
|
||||||
public bool $tagModalOpen = false;
|
public bool $tagModalOpen = false;
|
||||||
|
|
||||||
public bool $productModalOpen = false;
|
public bool $productModalOpen = false;
|
||||||
|
|
||||||
/** @var array<string, mixed> */
|
/** @var array<string, mixed> */
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
final class LegacyCategory extends Model
|
final class LegacyCategory extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'helpdesk_legacy_categories';
|
protected $table = 'helpdesk_legacy_categories';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
final class LegacyComment extends Model
|
final class LegacyComment extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'helpdesk_legacy_comments';
|
protected $table = 'helpdesk_legacy_comments';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = ['legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime'];
|
protected $casts = ['legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime'];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
final class LegacyTicket extends Model
|
final class LegacyTicket extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'helpdesk_legacy_tickets';
|
protected $table = 'helpdesk_legacy_tickets';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = ['legacy_data' => 'array', 'legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime', 'completed_at' => 'datetime', 'archived_at' => 'datetime'];
|
protected $casts = ['legacy_data' => 'array', 'legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime', 'completed_at' => 'datetime', 'archived_at' => 'datetime'];
|
||||||
|
|
||||||
public function comments(): HasMany
|
public function comments(): HasMany
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||||||
namespace Modules\Helpdesk\Models;
|
namespace Modules\Helpdesk\Models;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ final class Ticket extends Model
|
|||||||
return $this->belongsTo(User::class, 'user_id');
|
return $this->belongsTo(User::class, 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compatibility alias for the requester.
|
* Compatibility alias for the requester.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use Illuminate\Support\Facades\Schema;
|
|||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
final class HelpdeskSyncService
|
final class HelpdeskSyncService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ final class UserController extends Controller
|
|||||||
public function createRole(): View
|
public function createRole(): View
|
||||||
{
|
{
|
||||||
return view('modules.user-management.role-form', [
|
return view('modules.user-management.role-form', [
|
||||||
'role' => new Role(),
|
'role' => new Role,
|
||||||
'permissions' => Permission::query()->orderBy('name')->get(),
|
'permissions' => Permission::query()->orderBy('name')->get(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ final class UserController extends Controller
|
|||||||
|
|
||||||
public function createPermission(): View
|
public function createPermission(): View
|
||||||
{
|
{
|
||||||
return view('modules.user-management.permission-form', ['permission' => new Permission()]);
|
return view('modules.user-management.permission-form', ['permission' => new Permission]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storePermission(Request $request): RedirectResponse
|
public function storePermission(Request $request): RedirectResponse
|
||||||
|
|||||||
@@ -18,5 +18,4 @@ class Appearance extends Component
|
|||||||
resource_path('themes/backend/views/livewire/settings/appearance.blade.php')
|
resource_path('themes/backend/views/livewire/settings/appearance.blade.php')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Settings;
|
namespace App\Livewire\Settings;
|
||||||
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use App\Concerns\PasswordValidationRules;
|
use App\Concerns\PasswordValidationRules;
|
||||||
use App\Livewire\Actions\Logout;
|
use App\Livewire\Actions\Logout;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@@ -27,11 +27,11 @@ class DeleteUserForm extends Component
|
|||||||
|
|
||||||
$this->redirect('/', navigate: true);
|
$this->redirect('/', navigate: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): View
|
public function render(): View
|
||||||
{
|
{
|
||||||
return view()->file(
|
return view()->file(
|
||||||
resource_path('themes/backend/views/livewire/settings/delete-user-form.blade.php')
|
resource_path('themes/backend/views/livewire/settings/delete-user-form.blade.php')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Settings;
|
namespace App\Livewire\Settings;
|
||||||
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use App\Concerns\ProfileValidationRules;
|
use App\Concerns\ProfileValidationRules;
|
||||||
use Flux\Flux;
|
use Flux\Flux;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Attributes\Layout;
|
|
||||||
use Livewire\Attributes\Computed;
|
use Livewire\Attributes\Computed;
|
||||||
|
use Livewire\Attributes\Layout;
|
||||||
use Livewire\Attributes\Title;
|
use Livewire\Attributes\Title;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@@ -83,6 +83,7 @@ class Profile extends Component
|
|||||||
|
|
||||||
return ! $user instanceof MustVerifyEmail || $user->hasVerifiedEmail();
|
return ! $user instanceof MustVerifyEmail || $user->hasVerifiedEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Layout('layouts.app')]
|
#[Layout('layouts.app')]
|
||||||
public function render(): View
|
public function render(): View
|
||||||
{
|
{
|
||||||
@@ -90,5 +91,4 @@ class Profile extends Component
|
|||||||
resource_path('themes/backend/views/livewire/settings/profile.blade.php')
|
resource_path('themes/backend/views/livewire/settings/profile.blade.php')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Settings;
|
namespace App\Livewire\Settings;
|
||||||
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use App\Concerns\PasswordValidationRules;
|
use App\Concerns\PasswordValidationRules;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Flux\Flux;
|
use Flux\Flux;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication;
|
use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication;
|
||||||
@@ -14,8 +14,8 @@ use Laravel\Fortify\Actions\EnableTwoFactorAuthentication;
|
|||||||
use Laravel\Fortify\Features;
|
use Laravel\Fortify\Features;
|
||||||
use Laravel\Fortify\Fortify;
|
use Laravel\Fortify\Fortify;
|
||||||
use Laravel\Passkeys\Actions\DeletePasskey;
|
use Laravel\Passkeys\Actions\DeletePasskey;
|
||||||
use Livewire\Attributes\Layout;
|
|
||||||
use Livewire\Attributes\Computed;
|
use Livewire\Attributes\Computed;
|
||||||
|
use Livewire\Attributes\Layout;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Attributes\Title;
|
use Livewire\Attributes\Title;
|
||||||
use Livewire\Attributes\Validate;
|
use Livewire\Attributes\Validate;
|
||||||
@@ -311,6 +311,7 @@ class Security extends Component
|
|||||||
'buttonText' => __('Continue'),
|
'buttonText' => __('Continue'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Layout('layouts.app')]
|
#[Layout('layouts.app')]
|
||||||
public function render(): View
|
public function render(): View
|
||||||
{
|
{
|
||||||
@@ -318,5 +319,4 @@ class Security extends Component
|
|||||||
resource_path('themes/backend/views/livewire/settings/security.blade.php')
|
resource_path('themes/backend/views/livewire/settings/security.blade.php')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Settings\TwoFactor;
|
namespace App\Livewire\Settings\TwoFactor;
|
||||||
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
use Laravel\Fortify\Actions\GenerateNewRecoveryCodes;
|
use Laravel\Fortify\Actions\GenerateNewRecoveryCodes;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
@@ -49,11 +49,11 @@ class RecoveryCodes extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): View
|
public function render(): View
|
||||||
{
|
{
|
||||||
return view()->file(
|
return view()->file(
|
||||||
resource_path('themes/backend/views/livewire/settings/two-factor/recovery-codes.blade.php')
|
resource_path('themes/backend/views/livewire/settings/two-factor/recovery-codes.blade.php')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -6,6 +6,7 @@ use Database\Factories\UserFactory;
|
|||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
@@ -14,7 +15,6 @@ use Laravel\Fortify\Contracts\PasskeyUser;
|
|||||||
use Laravel\Fortify\PasskeyAuthenticatable;
|
use Laravel\Fortify\PasskeyAuthenticatable;
|
||||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||||
use Modules\UserManagement\Models\Role;
|
use Modules\UserManagement\Models\Role;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
@@ -50,8 +50,6 @@ class User extends Authenticatable implements PasskeyUser
|
|||||||
: $initials;
|
: $initials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function gravatarUrl(int $size = 160): string
|
public function gravatarUrl(int $size = 160): string
|
||||||
{
|
{
|
||||||
$email = strtolower(trim((string) $this->email));
|
$email = strtolower(trim((string) $this->email));
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ host('mpba')
|
|||||||
->set('branch', 'main')
|
->set('branch', 'main')
|
||||||
->set('deploy_path', '/var/www/helpdesk_mpba');
|
->set('deploy_path', '/var/www/helpdesk_mpba');
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Install the root npm tree, then every module that owns its own lock file,
|
* Install the root npm tree, then every module that owns its own lock file,
|
||||||
* then run ONE root Vite build. Because Vite is compiling a module source file,
|
* then run ONE root Vite build. Because Vite is compiling a module source file,
|
||||||
|
|||||||
Reference in New Issue
Block a user