0.10.2-21 Job Infos

This commit is contained in:
2026-03-17 14:03:44 +00:00
parent b8cccd0045
commit cdb87b5759
8 changed files with 100 additions and 112 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "ripster-backend", "name": "ripster-backend",
"version": "0.10.2-20", "version": "0.10.2-21",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ripster-backend", "name": "ripster-backend",
"version": "0.10.2-20", "version": "0.10.2-21",
"dependencies": { "dependencies": {
"archiver": "^7.0.1", "archiver": "^7.0.1",
"cors": "^2.8.5", "cors": "^2.8.5",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "ripster-backend", "name": "ripster-backend",
"version": "0.10.2-20", "version": "0.10.2-21",
"private": true, "private": true,
"type": "commonjs", "type": "commonjs",
"scripts": { "scripts": {
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "ripster-frontend", "name": "ripster-frontend",
"version": "0.10.2-20", "version": "0.10.2-21",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ripster-frontend", "name": "ripster-frontend",
"version": "0.10.2-20", "version": "0.10.2-21",
"dependencies": { "dependencies": {
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"primereact": "^10.9.2", "primereact": "^10.9.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "ripster-frontend", "name": "ripster-frontend",
"version": "0.10.2-20", "version": "0.10.2-21",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+70 -91
View File
@@ -743,7 +743,7 @@ export default function JobDetailDialog({
<h4>Job-Infos</h4> <h4>Job-Infos</h4>
<div className="job-meta-grid job-meta-grid-compact"> <div className="job-meta-grid job-meta-grid-compact">
<div> <div>
<strong>Aktueller Status:</strong>{' '} <strong>Status:</strong>{' '}
<span <span
className={`job-status-icon tone-${statusMeta.tone}`} className={`job-status-icon tone-${statusMeta.tone}`}
title={statusMeta.label} title={statusMeta.label}
@@ -751,6 +751,7 @@ export default function JobDetailDialog({
> >
<i className={`pi ${statusMeta.icon}`} aria-hidden="true" /> <i className={`pi ${statusMeta.icon}`} aria-hidden="true" />
</span> </span>
{' '}<span className="job-meta-subtle">{statusMeta.label}</span>
</div> </div>
<div> <div>
<strong>Start:</strong> {job.start_time || '-'} <strong>Start:</strong> {job.start_time || '-'}
@@ -758,8 +759,22 @@ export default function JobDetailDialog({
<div> <div>
<strong>Ende:</strong> {job.end_time || '-'} <strong>Ende:</strong> {job.end_time || '-'}
</div> </div>
{isCd ? (
<div>
<strong>Rip:</strong> <BoolState value={job?.ripSuccessful} />
</div>
) : (
<>
<div>
<strong>{isAudiobook ? 'Import:' : 'Backup:'}</strong> <BoolState value={job?.backupSuccess} />
</div>
<div>
<strong>Encode:</strong> <BoolState value={job?.encodeSuccess} />
</div>
</>
)}
<PathField <PathField
label={isCd ? 'WAV Pfad:' : 'RAW Pfad:'} label={isCd ? 'WAV:' : 'RAW:'}
value={job.raw_path} value={job.raw_path}
onDownload={canDownloadRaw ? () => onDownloadArchive?.(job, 'raw') : null} onDownload={canDownloadRaw ? () => onDownloadArchive?.(job, 'raw') : null}
downloadDisabled={!canDownloadRaw} downloadDisabled={!canDownloadRaw}
@@ -772,80 +787,44 @@ export default function JobDetailDialog({
downloadDisabled={!canDownloadOutput} downloadDisabled={!canDownloadOutput}
downloadLoading={downloadBusyTarget === 'output'} downloadLoading={downloadBusyTarget === 'output'}
/> />
{!isCd ? ( {job.error_message ? (
<div> <div className="job-meta-col-span-2">
<strong>Encode Input:</strong> {job.encode_input_path || '-'} <strong>Fehler:</strong> {job.error_message}
</div> </div>
) : null} ) : null}
<div>
<strong>RAW vorhanden:</strong> <BoolState value={job.rawStatus?.exists} />
</div>
<div>
<strong>{isCd ? 'Audio-Dateien vorhanden:' : (isAudiobook ? (job.outputStatus?.isDirectory ? 'Audiobook-Dateien vorhanden:' : 'Audiobook-Datei vorhanden:') : 'Movie Datei vorhanden:')}</strong> <BoolState value={job.outputStatus?.exists} />
</div>
{isCd ? (
<div>
<strong>Rip erfolgreich:</strong> <BoolState value={job?.ripSuccessful} />
</div>
) : (
<>
<div>
<strong>{isAudiobook ? 'Import erfolgreich:' : 'Backup erfolgreich:'}</strong> <BoolState value={job?.backupSuccess} />
</div>
<div>
<strong>Encode erfolgreich:</strong> <BoolState value={job?.encodeSuccess} />
</div>
</>
)}
<div className="job-meta-col-span-2">
<strong>Letzter Fehler:</strong> {job.error_message || '-'}
</div>
</div> </div>
</section> </section>
{!isCd && !isAudiobook && (hasConfiguredSelection || encodePlanUserPreset) ? ( {!isCd && (hasConfiguredSelection || encodePlanUserPreset || executedHandBrakeCommand || job.handbrakeInfo?.preEncodeScripts?.configured > 0 || job.handbrakeInfo?.postEncodeScripts?.configured > 0) ? (
<section className="job-meta-block job-meta-block-full"> <section className="job-meta-block job-meta-block-full">
<h4>Hinterlegte Encode-Auswahl</h4> <h4>Encode-Konfiguration</h4>
<div className="job-configured-selection-grid"> {(hasConfiguredSelection || encodePlanUserPreset) && !isAudiobook ? (
<div className="job-meta-grid job-meta-grid-compact job-meta-encode-config">
<div> <div>
<strong>Pre-Encode Skripte:</strong> {configuredSelection.preScripts.length > 0 ? configuredSelection.preScripts.join(' | ') : '-'} <strong>Pre-Skripte:</strong> {configuredSelection.preScripts.length > 0 ? configuredSelection.preScripts.join(', ') : (configuredSelection.preChains.length > 0 ? configuredSelection.preChains.join(', ') : '-')}
</div> </div>
<div> <div>
<strong>Pre-Encode Ketten:</strong> {configuredSelection.preChains.length > 0 ? configuredSelection.preChains.join(' | ') : '-'} <strong>Post-Skripte:</strong> {configuredSelection.postScripts.length > 0 ? configuredSelection.postScripts.join(', ') : (configuredSelection.postChains.length > 0 ? configuredSelection.postChains.join(', ') : '-')}
</div>
<div>
<strong>Post-Encode Skripte:</strong> {configuredSelection.postScripts.length > 0 ? configuredSelection.postScripts.join(' | ') : '-'}
</div>
<div>
<strong>Post-Encode Ketten:</strong> {configuredSelection.postChains.length > 0 ? configuredSelection.postChains.join(' | ') : '-'}
</div> </div>
{encodePlanUserPreset ? (
<div className="job-meta-col-span-2"> <div className="job-meta-col-span-2">
<strong>User-Preset:</strong>{' '} <strong>Preset:</strong> {encodePlanUserPreset.name || '-'}{encodePlanUserPreset.handbrakePreset ? ` · ${encodePlanUserPreset.handbrakePreset}` : ''}{encodePlanUserPreset.extraArgs ? ` · ${encodePlanUserPreset.extraArgs}` : ''}
{encodePlanUserPreset
? `${encodePlanUserPreset.name || '-'} | Preset=${encodePlanUserPreset.handbrakePreset || '-'} | ExtraArgs=${encodePlanUserPreset.extraArgs || '-'}`
: '-'}
</div> </div>
</div>
</section>
) : null} ) : null}
</div>
{!isCd && executedHandBrakeCommand ? ( ) : null}
<section className="job-meta-block job-meta-block-full"> {executedHandBrakeCommand ? (
<h4>Ausgeführter Encode-Befehl</h4>
<div className="handbrake-command-preview"> <div className="handbrake-command-preview">
<small><strong>{isAudiobook ? 'FFmpeg' : 'HandBrakeCLI'} (tatsächlich gestartet):</strong></small> <small><strong>{isAudiobook ? 'FFmpeg' : 'HandBrakeCLI'}:</strong></small>
<pre>{executedHandBrakeCommand}</pre> <pre>{executedHandBrakeCommand}</pre>
</div> </div>
</section>
) : null} ) : null}
{!isAudiobook && (job.handbrakeInfo?.preEncodeScripts?.configured > 0 || job.handbrakeInfo?.postEncodeScripts?.configured > 0) ? (
{!isCd && !isAudiobook && (job.handbrakeInfo?.preEncodeScripts?.configured > 0 || job.handbrakeInfo?.postEncodeScripts?.configured > 0) ? (
<section className="job-meta-block job-meta-block-full">
<h4>Skripte</h4>
<div className="script-results-grid"> <div className="script-results-grid">
<ScriptSummarySection title="Pre-Encode" summary={job.handbrakeInfo?.preEncodeScripts} /> <ScriptSummarySection title="Pre-Encode" summary={job.handbrakeInfo?.preEncodeScripts} />
<ScriptSummarySection title="Post-Encode" summary={job.handbrakeInfo?.postEncodeScripts} /> <ScriptSummarySection title="Post-Encode" summary={job.handbrakeInfo?.postEncodeScripts} />
</div> </div>
) : null}
</section> </section>
) : null} ) : null}
@@ -877,6 +856,42 @@ export default function JobDetailDialog({
</> </>
) : null} ) : null}
<h4>Log</h4>
{showFinalLog ? (
<>
<div className="actions-row">
<Button
label={logLoaded ? 'Tail neu laden (800)' : 'Tail laden (800)'}
icon="pi pi-download"
severity="secondary"
outlined
size="small"
onClick={() => onLoadLog?.(job, 'tail')}
loading={logLoadingMode === 'tail'}
/>
<Button
label="Vollständiges Log laden"
icon="pi pi-list"
severity="secondary"
outlined
size="small"
onClick={() => onLoadLog?.(job, 'all')}
loading={logLoadingMode === 'all'}
disabled={logCount <= 0}
/>
<small>{`Log-Zeilen: ${logCount}`}</small>
{logTruncated ? <small>(gekürzt auf letzte 800 Zeilen)</small> : null}
</div>
{logLoaded ? (
<pre className="log-box">{job.log || ''}</pre>
) : (
<p>Log nicht vorgeladen. Über die Buttons oben laden.</p>
)}
</>
) : (
<p>Live-Log wird nur im Dashboard während laufender Analyse/Rip/Encode angezeigt.</p>
)}
<h4>Aktionen</h4> <h4>Aktionen</h4>
{queueLocked ? ( {queueLocked ? (
<div className="actions-row"> <div className="actions-row">
@@ -1005,42 +1020,6 @@ export default function JobDetailDialog({
</div> </div>
)} )}
<h4>Log</h4>
{showFinalLog ? (
<>
<div className="actions-row">
<Button
label={logLoaded ? 'Tail neu laden (800)' : 'Tail laden (800)'}
icon="pi pi-download"
severity="secondary"
outlined
size="small"
onClick={() => onLoadLog?.(job, 'tail')}
loading={logLoadingMode === 'tail'}
/>
<Button
label="Vollständiges Log laden"
icon="pi pi-list"
severity="secondary"
outlined
size="small"
onClick={() => onLoadLog?.(job, 'all')}
loading={logLoadingMode === 'all'}
disabled={logCount <= 0}
/>
<small>{`Log-Zeilen: ${logCount}`}</small>
{logTruncated ? <small>(gekürzt auf letzte 800 Zeilen)</small> : null}
</div>
{logLoaded ? (
<pre className="log-box">{job.log || ''}</pre>
) : (
<p>Log nicht vorgeladen. Über die Buttons oben laden.</p>
)}
</>
) : (
<p>Live-Log wird nur im Dashboard während laufender Analyse/Rip/Encode angezeigt.</p>
)}
{!queueLocked ? ( {!queueLocked ? (
<div className="action-delete-entry"> <div className="action-delete-entry">
<span className="action-desc">Entfernt diesen Eintrag aus der Verlaufsliste Dateien auf der Festplatte bleiben erhalten.</span> <span className="action-desc">Entfernt diesen Eintrag aus der Verlaufsliste Dateien auf der Festplatte bleiben erhalten.</span>
+9
View File
@@ -2588,6 +2588,15 @@ body {
grid-column: 1 / -1; grid-column: 1 / -1;
} }
.job-meta-subtle {
font-size: 0.82rem;
color: var(--text-color-secondary);
}
.job-meta-encode-config {
margin-bottom: 0.5rem;
}
.job-configured-selection-grid { .job-configured-selection-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "ripster", "name": "ripster",
"version": "0.10.2-20", "version": "0.10.2-21",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ripster", "name": "ripster",
"version": "0.10.2-20", "version": "0.10.2-21",
"devDependencies": { "devDependencies": {
"concurrently": "^9.1.2" "concurrently": "^9.1.2"
} }
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "ripster", "name": "ripster",
"private": true, "private": true,
"version": "0.10.2-20", "version": "0.10.2-21",
"scripts": { "scripts": {
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"", "dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
"dev:backend": "npm run dev --prefix backend", "dev:backend": "npm run dev --prefix backend",