0.10.2-19 Frontend

This commit is contained in:
2026-03-17 11:58:04 +00:00
parent 7796587f16
commit 46bd235afc
13 changed files with 227 additions and 100 deletions
+102 -89
View File
@@ -878,8 +878,8 @@ export default function JobDetailDialog({
) : null}
<h4>Aktionen</h4>
<div className="actions-row">
{queueLocked ? (
{queueLocked ? (
<div className="actions-row">
<Button
label="Aus Queue löschen"
icon="pi pi-times"
@@ -890,103 +890,116 @@ export default function JobDetailDialog({
loading={actionBusy}
disabled={typeof onRemoveFromQueue !== 'function'}
/>
) : (
<>
{!isCd && !isAudiobook ? (
</div>
) : (
<div className="actions-section">
{!isCd ? (
<div className="actions-group">
<div className="actions-group-label"><i className="pi pi-play-circle" /> Kodierung</div>
{canResumeReady ? (
<div className="action-item">
<Button
label="Im Dashboard öffnen"
icon="pi pi-window-maximize"
severity="info"
outlined
size="small"
onClick={() => onResumeReady?.(job)}
loading={actionBusy}
/>
<span className="action-desc">Öffnet den wartenden Job im Dashboard zur Weiterverarbeitung.</span>
</div>
) : null}
{typeof onRestartEncode === 'function' ? (
<div className="action-item">
<Button
label="Encode neu starten"
icon="pi pi-play"
severity="success"
size="small"
onClick={() => onRestartEncode?.(job)}
loading={actionBusy}
disabled={!canRestartEncode}
/>
<span className="action-desc">Startet {isAudiobook ? 'FFmpeg' : 'HandBrake'} mit den zuletzt gespeicherten Einstellungen direkt neu ohne Review.</span>
</div>
) : null}
{!isAudiobook && typeof onRestartReview === 'function' ? (
<div className="action-item">
<Button
label="Review neu starten"
icon="pi pi-refresh"
severity="info"
outlined
size="small"
onClick={() => onRestartReview?.(job)}
loading={actionBusy}
disabled={!canRestartReview}
/>
<span className="action-desc">Zeigt den Review-Screen erneut (Spur- und Preset-Auswahl), um Einstellungen vor dem Encode zu ändern.</span>
</div>
) : null}
{!isAudiobook ? (
<div className="action-item">
<Button
label="RAW neu encodieren"
icon="pi pi-cog"
severity="info"
size="small"
onClick={() => onReencode?.(job)}
loading={reencodeBusy}
disabled={!canReencode || typeof onReencode !== 'function'}
/>
<span className="action-desc">Analysiert die Quelldatei neu (MediaInfo, Playlist-Check) und startet dann den Review. Unterschied zu Review neu starten": der Analyse-Schritt wird komplett wiederholt — sinnvoll wenn sich der RAW-Inhalt geändert hat.</span>
</div>
) : null}
</div>
) : null}
<div className="actions-group">
<div className="actions-group-label"><i className="pi pi-trash" /> Dateien löschen</div>
<div className="action-item">
<Button
label="OMDb neu zuordnen"
icon="pi pi-search"
severity="secondary"
size="small"
onClick={() => onAssignOmdb?.(job)}
loading={omdbAssignBusy}
disabled={running || typeof onAssignOmdb !== 'function'}
/>
) : (
<Button
label="MusicBrainz neu zuordnen"
icon="pi pi-search"
severity="secondary"
size="small"
onClick={() => onAssignCdMetadata?.(job)}
loading={cdMetadataAssignBusy}
disabled={running || typeof onAssignCdMetadata !== 'function'}
/>
)}
{!isCd && canResumeReady ? (
<Button
label="Im Dashboard öffnen"
icon="pi pi-window-maximize"
severity="info"
label="RAW löschen"
icon="pi pi-trash"
severity="warning"
outlined
size="small"
onClick={() => onResumeReady?.(job)}
onClick={() => onDeleteFiles?.(job, 'raw')}
loading={actionBusy}
disabled={!job.rawStatus?.exists || typeof onDeleteFiles !== 'function'}
/>
) : null}
{!isCd && typeof onRestartEncode === 'function' ? (
<span className="action-desc">Löscht die Quelldateien nach dem Rip ({isCd ? 'Audio-Rohdaten' : isAudiobook ? 'AAX/MP3-Quelldatei' : 'MKV-Datei von MakeMKV'}).</span>
</div>
<div className="action-item">
<Button
label="Encode neu starten"
icon="pi pi-play"
severity="success"
size="small"
onClick={() => onRestartEncode?.(job)}
loading={actionBusy}
disabled={!canRestartEncode}
/>
) : null}
{!isCd && !isAudiobook && typeof onRestartReview === 'function' ? (
<Button
label="Review neu starten"
icon="pi pi-refresh"
severity="info"
label={isCd ? 'Audio löschen' : (isAudiobook ? 'Ausgabe löschen' : 'Movie löschen')}
icon="pi pi-trash"
severity="warning"
outlined
size="small"
onClick={() => onRestartReview?.(job)}
onClick={() => onDeleteFiles?.(job, 'movie')}
loading={actionBusy}
disabled={!canRestartReview}
disabled={!job.outputStatus?.exists || typeof onDeleteFiles !== 'function'}
/>
) : null}
{!isCd && !isAudiobook ? (
<span className="action-desc">Löscht {isCd ? 'die fertig gerippten Audiodateien' : isAudiobook ? 'die fertig konvertierte Audiobook-Ausgabe' : 'die fertig encodierte Filmdatei'}.</span>
</div>
<div className="action-item">
<Button
label="RAW neu encodieren"
icon="pi pi-cog"
severity="info"
label="Beides löschen"
icon="pi pi-times"
severity="danger"
size="small"
onClick={() => onReencode?.(job)}
loading={reencodeBusy}
disabled={!canReencode || typeof onReencode !== 'function'}
onClick={() => onDeleteFiles?.(job, 'both')}
loading={actionBusy}
disabled={(!job.rawStatus?.exists && !job.outputStatus?.exists) || typeof onDeleteFiles !== 'function'}
/>
) : null}
<Button
label="RAW löschen"
icon="pi pi-trash"
severity="warning"
outlined
size="small"
onClick={() => onDeleteFiles?.(job, 'raw')}
loading={actionBusy}
disabled={!job.rawStatus?.exists || typeof onDeleteFiles !== 'function'}
/>
<Button
label={isCd ? 'Audio löschen' : (isAudiobook ? 'Ausgabe löschen' : 'Movie löschen')}
icon="pi pi-trash"
severity="warning"
outlined
size="small"
onClick={() => onDeleteFiles?.(job, 'movie')}
loading={actionBusy}
disabled={!job.outputStatus?.exists || typeof onDeleteFiles !== 'function'}
/>
<Button
label="Beides löschen"
icon="pi pi-times"
severity="danger"
size="small"
onClick={() => onDeleteFiles?.(job, 'both')}
loading={actionBusy}
disabled={(!job.rawStatus?.exists && !job.outputStatus?.exists) || typeof onDeleteFiles !== 'function'}
/>
<span className="action-desc">Löscht RAW-Quelldateien und Ausgabe gemeinsam.</span>
</div>
</div>
<div className="action-delete-entry">
<span className="action-desc">Entfernt diesen Eintrag aus der Verlaufsliste — Dateien auf der Festplatte bleiben erhalten.</span>
<Button
label="Historieneintrag löschen"
icon="pi pi-trash"
@@ -997,9 +1010,9 @@ export default function JobDetailDialog({
loading={deleteEntryBusy}
disabled={!canDeleteEntry}
/>
</>
)}
</div>
</div>
</div>
)}
<h4>Log</h4>
{showFinalLog ? (