feat(pdf): preview in Filament modal (iframe) instead of new tab
All "Vizualizare PDF" actions now open a wide (7xl) Filament modal containing an iframe pointing at the inline PDF endpoint, with a top-right "Descarcă" and "Deschide în tab nou" fallback. - WorkOrder edit action + WO table row action - InjectorProtocol edit action + protocols table row action - Dashboard Docs tab preview button (Alpine.js overlay since it's a plain Blade view, not a Filament action) The underlying /pdf routes stay unchanged (Content-Disposition: inline, ?download=1 for attachment) — the iframe just loads the same URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -266,8 +266,14 @@ class InjectorProtocolResource extends Resource
|
|||||||
->label(__('PDF'))
|
->label(__('PDF'))
|
||||||
->icon('heroicon-m-document-magnifying-glass')
|
->icon('heroicon-m-document-magnifying-glass')
|
||||||
->color('gray')
|
->color('gray')
|
||||||
->url(fn (InjectorProtocol $r) => route('tenant.injector-protocols.pdf', ['record' => $r->id]))
|
->modalHeading(fn (InjectorProtocol $r) => __('Protocol') . ' ' . $r->protocol_number)
|
||||||
->openUrlInNewTab(),
|
->modalSubmitAction(false)
|
||||||
|
->modalCancelActionLabel(__('Închide'))
|
||||||
|
->modalWidth('7xl')
|
||||||
|
->modalContent(fn (InjectorProtocol $r) => view('filament.tenant.pdf-preview', [
|
||||||
|
'pdfUrl' => route('tenant.injector-protocols.pdf', ['record' => $r->id]),
|
||||||
|
'downloadUrl' => route('tenant.injector-protocols.pdf', ['record' => $r->id, 'download' => 1]),
|
||||||
|
])),
|
||||||
Actions\EditAction::make(),
|
Actions\EditAction::make(),
|
||||||
Actions\DeleteAction::make(),
|
Actions\DeleteAction::make(),
|
||||||
])
|
])
|
||||||
|
|||||||
+8
-2
@@ -18,8 +18,14 @@ class EditInjectorProtocol extends EditRecord
|
|||||||
->label(__('Vizualizare PDF'))
|
->label(__('Vizualizare PDF'))
|
||||||
->icon('heroicon-m-document-magnifying-glass')
|
->icon('heroicon-m-document-magnifying-glass')
|
||||||
->color('gray')
|
->color('gray')
|
||||||
->url(fn (InjectorProtocol $record) => route('tenant.injector-protocols.pdf', ['record' => $record->id]))
|
->modalHeading(fn (InjectorProtocol $record) => __('Protocol') . ' ' . $record->protocol_number)
|
||||||
->openUrlInNewTab(),
|
->modalSubmitAction(false)
|
||||||
|
->modalCancelActionLabel(__('Închide'))
|
||||||
|
->modalWidth('7xl')
|
||||||
|
->modalContent(fn (InjectorProtocol $record) => view('filament.tenant.pdf-preview', [
|
||||||
|
'pdfUrl' => route('tenant.injector-protocols.pdf', ['record' => $record->id]),
|
||||||
|
'downloadUrl' => route('tenant.injector-protocols.pdf', ['record' => $record->id, 'download' => 1]),
|
||||||
|
])),
|
||||||
Actions\DeleteAction::make(),
|
Actions\DeleteAction::make(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,8 +188,14 @@ class WorkOrderResource extends Resource
|
|||||||
->label(__('PDF'))
|
->label(__('PDF'))
|
||||||
->icon('heroicon-m-document-magnifying-glass')
|
->icon('heroicon-m-document-magnifying-glass')
|
||||||
->color('gray')
|
->color('gray')
|
||||||
->url(fn (WorkOrder $r) => url('/app/work-orders/' . $r->id . '/pdf'))
|
->modalHeading(fn (WorkOrder $r) => __('Factură') . ' — WO #' . $r->number)
|
||||||
->openUrlInNewTab(),
|
->modalSubmitAction(false)
|
||||||
|
->modalCancelActionLabel(__('Închide'))
|
||||||
|
->modalWidth('7xl')
|
||||||
|
->modalContent(fn (WorkOrder $r) => view('filament.tenant.pdf-preview', [
|
||||||
|
'pdfUrl' => url('/app/work-orders/' . $r->id . '/pdf'),
|
||||||
|
'downloadUrl' => url('/app/work-orders/' . $r->id . '/pdf?download=1'),
|
||||||
|
])),
|
||||||
Actions\EditAction::make(),
|
Actions\EditAction::make(),
|
||||||
Actions\DeleteAction::make(),
|
Actions\DeleteAction::make(),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -87,8 +87,14 @@ class EditWorkOrder extends EditRecord
|
|||||||
->label(__('Vizualizare PDF'))
|
->label(__('Vizualizare PDF'))
|
||||||
->icon('heroicon-m-document-magnifying-glass')
|
->icon('heroicon-m-document-magnifying-glass')
|
||||||
->color('gray')
|
->color('gray')
|
||||||
->url(fn () => url('/app/work-orders/' . $this->record->id . '/pdf'))
|
->modalHeading(fn () => __('Factură') . ' — WO #' . $this->record->number)
|
||||||
->openUrlInNewTab(),
|
->modalSubmitAction(false)
|
||||||
|
->modalCancelActionLabel(__('Închide'))
|
||||||
|
->modalWidth('7xl')
|
||||||
|
->modalContent(fn () => view('filament.tenant.pdf-preview', [
|
||||||
|
'pdfUrl' => url('/app/work-orders/' . $this->record->id . '/pdf'),
|
||||||
|
'downloadUrl' => url('/app/work-orders/' . $this->record->id . '/pdf?download=1'),
|
||||||
|
])),
|
||||||
Actions\DeleteAction::make(),
|
Actions\DeleteAction::make(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -670,6 +670,7 @@
|
|||||||
"Deschide fișă nouă": "Open new order",
|
"Deschide fișă nouă": "Open new order",
|
||||||
"Deschide panoul pe telefon și acceptă notificările întâi.": "Open the panel on the phone and accept notifications first.",
|
"Deschide panoul pe telefon și acceptă notificările întâi.": "Open the panel on the phone and accept notifications first.",
|
||||||
"Deschide tenantul": "Deschide tenantul",
|
"Deschide tenantul": "Deschide tenantul",
|
||||||
|
"Deschide în tab nou": "Open in new tab",
|
||||||
"Deschide →": "Open →",
|
"Deschide →": "Open →",
|
||||||
"Deschidere ÎNAINTE": "Opening BEFORE",
|
"Deschidere ÎNAINTE": "Opening BEFORE",
|
||||||
"Deschis": "Opened",
|
"Deschis": "Opened",
|
||||||
@@ -1623,6 +1624,7 @@
|
|||||||
"Progres": "Progress",
|
"Progres": "Progress",
|
||||||
"Progres etapă": "Stage progress",
|
"Progres etapă": "Stage progress",
|
||||||
"Proprietar": "Owner",
|
"Proprietar": "Owner",
|
||||||
|
"Protocol": "Protocol",
|
||||||
"Protocol nou": "New protocol",
|
"Protocol nou": "New protocol",
|
||||||
"Provider implicit": "Default provider",
|
"Provider implicit": "Default provider",
|
||||||
"Provider:": "Provider:",
|
"Provider:": "Provider:",
|
||||||
|
|||||||
@@ -670,6 +670,7 @@
|
|||||||
"Deschide fișă nouă": "Открыть новый наряд",
|
"Deschide fișă nouă": "Открыть новый наряд",
|
||||||
"Deschide panoul pe telefon și acceptă notificările întâi.": "Сначала откройте панель на телефоне и разрешите уведомления.",
|
"Deschide panoul pe telefon și acceptă notificările întâi.": "Сначала откройте панель на телефоне и разрешите уведомления.",
|
||||||
"Deschide tenantul": "Deschide tenantul",
|
"Deschide tenantul": "Deschide tenantul",
|
||||||
|
"Deschide în tab nou": "Открыть в новой вкладке",
|
||||||
"Deschide →": "Открыть →",
|
"Deschide →": "Открыть →",
|
||||||
"Deschidere ÎNAINTE": "Открытие ДО",
|
"Deschidere ÎNAINTE": "Открытие ДО",
|
||||||
"Deschis": "Открыт",
|
"Deschis": "Открыт",
|
||||||
@@ -1623,6 +1624,7 @@
|
|||||||
"Progres": "Прогресс",
|
"Progres": "Прогресс",
|
||||||
"Progres etapă": "Прогресс этапа",
|
"Progres etapă": "Прогресс этапа",
|
||||||
"Proprietar": "Владелец",
|
"Proprietar": "Владелец",
|
||||||
|
"Protocol": "Протокол",
|
||||||
"Protocol nou": "Новый протокол",
|
"Protocol nou": "Новый протокол",
|
||||||
"Provider implicit": "Провайдер по умолчанию",
|
"Provider implicit": "Провайдер по умолчанию",
|
||||||
"Provider:": "Provider:",
|
"Provider:": "Provider:",
|
||||||
|
|||||||
@@ -687,13 +687,28 @@
|
|||||||
|
|
||||||
{{-- ── DOCUMENTS TAB ── --}}
|
{{-- ── DOCUMENTS TAB ── --}}
|
||||||
<div x-show="tab === 'docs'" x-cloak>
|
<div x-show="tab === 'docs'" x-cloak>
|
||||||
<div style="display:flex;flex-direction:column;gap:8px;">
|
<div style="display:flex;flex-direction:column;gap:8px;" x-data="{ pdfOpen: false }">
|
||||||
<a class="wd-btn" href="{{ url('/app/work-orders/' . $wo->id . '/pdf') }}" target="_blank">
|
<button type="button" class="wd-btn" @click="pdfOpen = true">
|
||||||
🔍 {{ __('Vizualizează factură (PDF)') }}
|
🔍 {{ __('Vizualizează factură (PDF)') }}
|
||||||
</a>
|
</button>
|
||||||
<a class="wd-btn" href="{{ url('/app/work-orders/' . $wo->id . '/pdf?download=1') }}">
|
<a class="wd-btn" href="{{ url('/app/work-orders/' . $wo->id . '/pdf?download=1') }}">
|
||||||
⬇️ {{ __('Descarcă factură (PDF)') }}
|
⬇️ {{ __('Descarcă factură (PDF)') }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
{{-- PDF preview modal (Alpine.js overlay) --}}
|
||||||
|
<div x-show="pdfOpen" x-cloak
|
||||||
|
style="position:fixed;inset:0;background:rgba(0,0,0,0.6);z-index:9999;display:flex;align-items:center;justify-content:center;padding:24px;"
|
||||||
|
@click.self="pdfOpen = false"
|
||||||
|
@keydown.escape.window="pdfOpen = false">
|
||||||
|
<div style="background:#fff;border-radius:8px;width:100%;max-width:1000px;height:90vh;display:flex;flex-direction:column;overflow:hidden;">
|
||||||
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #e5e7eb;">
|
||||||
|
<b style="font-size:14px;">{{ __('Factură') }} — WO #{{ $wo->number }}</b>
|
||||||
|
<button type="button" @click="pdfOpen = false" style="background:none;border:none;font-size:20px;cursor:pointer;color:#6b7280;">✕</button>
|
||||||
|
</div>
|
||||||
|
<iframe x-bind:src="pdfOpen ? '{{ url('/app/work-orders/' . $wo->id . '/pdf') }}#toolbar=1&navpanes=0' : ''"
|
||||||
|
style="flex:1;width:100%;border:none;" title="PDF"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@php $signed = $wo->getMedia('signed_documents'); @endphp
|
@php $signed = $wo->getMedia('signed_documents'); @endphp
|
||||||
@if ($signed->isNotEmpty())
|
@if ($signed->isNotEmpty())
|
||||||
<div style="font-size:11px;color:var(--wd-text-3);text-transform:uppercase;margin-top:12px;">{{ __('Documente semnate') }}</div>
|
<div style="font-size:11px;color:var(--wd-text-3);text-transform:uppercase;margin-top:12px;">{{ __('Documente semnate') }}</div>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{{-- Reusable PDF preview iframe (loaded inside a Filament action modal).
|
||||||
|
$pdfUrl — inline PDF endpoint (Content-Disposition: inline).
|
||||||
|
$downloadUrl — same URL with ?download=1, shown as a fallback link. --}}
|
||||||
|
<div style="display:flex;flex-direction:column;gap:10px;">
|
||||||
|
<div style="display:flex;justify-content:flex-end;gap:8px;">
|
||||||
|
<a href="{{ $downloadUrl }}" class="text-primary-600 hover:underline text-sm font-medium">
|
||||||
|
⬇️ {{ __('Descarcă') }}
|
||||||
|
</a>
|
||||||
|
<a href="{{ $pdfUrl }}" target="_blank" class="text-primary-600 hover:underline text-sm font-medium">
|
||||||
|
↗️ {{ __('Deschide în tab nou') }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<iframe src="{{ $pdfUrl }}#toolbar=1&navpanes=0" style="width:100%;height:75vh;border:1px solid var(--fi-color-gray-200,#e5e7eb);border-radius:6px;" title="PDF"></iframe>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user