hasRole('super-admin') && Schema::hasTable('fe_xsd_versions'); } protected function getHeaderActions(): array { return [ Action::make('importa_xsd') ->label('Importa XSD') ->icon('heroicon-o-arrow-up-tray') ->modalWidth('7xl') ->form([ TextInput::make('version_label') ->label('Versione (etichetta)') ->helperText('Es: VFPR12 1.2.3') ->maxLength(100), Textarea::make('note') ->label('Note') ->rows(3), FileUpload::make('xsd_file') ->label('File XSD') ->disk('local') ->directory('tmp/fe-xsd') ->required(), ]) ->action(function (array $data): void { $user = Auth::user(); $createdBy = $user instanceof User ? $user : null; $path = (string) ($data['xsd_file'] ?? ''); if ($path === '') { Notification::make()->title('Seleziona un file XSD')->danger()->send(); return; } try { $importer = app(FeXsdCodesImporter::class); $res = $importer->importFromUploadedXsd( $path, isset($data['version_label']) ? (string) $data['version_label'] : null, isset($data['note']) ? (string) $data['note'] : null, $createdBy, ); $already = (bool) ($res['summary']['already_imported'] ?? false); $title = $already ? 'XSD già importato' : 'Import XSD completato'; $body = 'SHA256: ' . ($res['summary']['sha256'] ?? '') . ($already ? '' : (' · Domini: ' . ($res['summary']['domains'] ?? 0) . ' · Codici: ' . ($res['summary']['codes'] ?? 0))); Notification::make()->title($title)->body($body)->success()->send(); } catch (\Throwable $e) { Notification::make()->title('Errore import XSD')->body($e->getMessage())->danger()->send(); } }), ]; } public function getVersions() { return FeXsdVersion::query() ->orderByDesc('imported_at') ->orderByDesc('id') ->get(['id', 'version_label', 'original_filename', 'sha256', 'imported_at']); } public function getLatestVersion(): ?FeXsdVersion { return FeXsdVersion::query()->orderByDesc('imported_at')->orderByDesc('id')->first(); } public function getLatestDomains() { $latest = $this->getLatestVersion(); if (!$latest) { return collect(); } return FeXsdCodeDomain::query() ->where('version_id', $latest->id) ->orderBy('type_name') ->get(['type_name', 'codes_count']); } public function getSelectedDomainTypeName(): ?string { $domain = request()->query('domain'); if (! is_string($domain)) { return null; } $domain = trim($domain); if ($domain === '' || strlen($domain) > 190) { return null; } // Keep it simple: only allow characters that can appear in XSD type names. if (! preg_match('/^[A-Za-z0-9_\-\.]+$/', $domain)) { return null; } return $domain; } public function getSelectedDomainCodes() { $latest = $this->getLatestVersion(); if (! $latest) { return collect(); } $domain = $this->getSelectedDomainTypeName(); if (! $domain) { return collect(); } $domainId = FeXsdCodeDomain::query() ->where('version_id', $latest->id) ->where('type_name', $domain) ->value('id'); $domainId = is_numeric($domainId) ? (int) $domainId : null; if (! $domainId) { return collect(); } return FeXsdCode::query() ->where('domain_id', $domainId) ->orderBy('code') ->get(['code', 'documentation']); } public function getPreviousVersion(?FeXsdVersion $latest): ?FeXsdVersion { if (!$latest) { return null; } return FeXsdVersion::query() ->where('id', '<', $latest->id) ->orderByDesc('imported_at') ->orderByDesc('id') ->first(); } public function getDiffSummary(): ?array { $latest = $this->getLatestVersion(); if (!$latest) { return null; } $prev = $this->getPreviousVersion($latest); $diff = app(FeXsdCodesDiff::class); return $diff->diff($prev, $latest); } }