From bf72c40ae15a43c094829375e3ae07f6d2c6a4b7 Mon Sep 17 00:00:00 2001 From: mboehmlaender Date: Mon, 16 Mar 2026 11:30:09 +0000 Subject: [PATCH] 0.10.2-11 Layout --- backend/package-lock.json | 4 +- backend/package.json | 2 +- frontend/package-lock.json | 4 +- frontend/package.json | 2 +- .../src/components/DynamicSettingsForm.jsx | 176 +++------- frontend/src/pages/DashboardPage.jsx | 311 +++++++++--------- frontend/src/pages/SettingsPage.jsx | 2 +- package-lock.json | 4 +- package.json | 2 +- 9 files changed, 214 insertions(+), 293 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index e713edc..6a6afea 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "ripster-backend", - "version": "0.10.2-10", + "version": "0.10.2-11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ripster-backend", - "version": "0.10.2-10", + "version": "0.10.2-11", "dependencies": { "archiver": "^7.0.1", "cors": "^2.8.5", diff --git a/backend/package.json b/backend/package.json index ad12aa3..4425f92 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "ripster-backend", - "version": "0.10.2-10", + "version": "0.10.2-11", "private": true, "type": "commonjs", "scripts": { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b40a63c..04315c4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "ripster-frontend", - "version": "0.10.2-10", + "version": "0.10.2-11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ripster-frontend", - "version": "0.10.2-10", + "version": "0.10.2-11", "dependencies": { "primeicons": "^7.0.0", "primereact": "^10.9.2", diff --git a/frontend/package.json b/frontend/package.json index c93603c..6a18f4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "ripster-frontend", - "version": "0.10.2-10", + "version": "0.10.2-11", "private": true, "type": "module", "scripts": { diff --git a/frontend/src/components/DynamicSettingsForm.jsx b/frontend/src/components/DynamicSettingsForm.jsx index 120ef8e..f63f736 100644 --- a/frontend/src/components/DynamicSettingsForm.jsx +++ b/frontend/src/components/DynamicSettingsForm.jsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from 'react'; import { TabView, TabPanel } from 'primereact/tabview'; +import { Accordion, AccordionTab } from 'primereact/accordion'; import { InputText } from 'primereact/inputtext'; import { InputNumber } from 'primereact/inputnumber'; import { InputSwitch } from 'primereact/inputswitch'; @@ -68,7 +69,8 @@ const EXPERT_ONLY_SETTING_KEYS = new Set([ 'makemkv_analyze_extra_args_dvd', 'makemkv_rip_extra_args_bluray', 'makemkv_rip_extra_args_dvd', - 'cdparanoia_command' + 'cdparanoia_command', + 'script_test_timeout_ms' ]); function toBoolean(value) { @@ -331,51 +333,6 @@ function SettingField({ ); } -function PathMediumCard({ title, pathSettings, settingsByKey, values, errors, dirtyKeys, onChange }) { - // Filter out _owner keys since they're rendered inline - const visibleSettings = pathSettings.filter( - (s) => !String(s?.key || '').endsWith('_owner') - ); - - if (visibleSettings.length === 0) { - return null; - } - - return ( -
-
-

{title}

-
-
- {visibleSettings.map((setting) => { - const value = values?.[setting.key]; - const error = errors?.[setting.key] || null; - const dirty = Boolean(dirtyKeys?.has?.(setting.key)); - const ownerKey = `${setting.key}_owner`; - const ownerSetting = settingsByKey.get(ownerKey) || null; - const ownerValue = values?.[ownerKey]; - const ownerError = errors?.[ownerKey] || null; - const ownerDirty = Boolean(dirtyKeys?.has?.(ownerKey)); - - return ( - - ); - })} -
-
- ); -} function PathCategoryTab({ settings, values, errors, dirtyKeys, onChange, effectivePaths }) { const list = Array.isArray(settings) ? settings : []; @@ -478,84 +435,55 @@ function PathCategoryTab({ settings, values, errors, dirtyKeys, onChange, effect - {/* Medium-Karten */} -
- - - - - -
- - {/* Log-Ordner */} - {logSettings.length > 0 && ( -
-
-

Logs

-
-
- {logSettings.map((setting) => { - const value = values?.[setting.key]; - const error = errors?.[setting.key] || null; - const dirty = Boolean(dirtyKeys?.has?.(setting.key)); - return ( - - ); - })} -
-
- )} + {/* Medium-Karten als Accordion */} + + {[ + { title: 'Blu-ray', pathSettings: bluraySettings }, + { title: 'DVD', pathSettings: dvdSettings }, + { title: 'CD / Audio', pathSettings: cdSettings }, + { title: 'Audiobook', pathSettings: audiobookSettings }, + { title: 'Downloads', pathSettings: downloadSettings }, + ...(logSettings.length > 0 ? [{ title: 'Logs', pathSettings: logSettings }] : []) + ] + .filter(({ pathSettings }) => + pathSettings.filter((s) => !String(s?.key || '').endsWith('_owner')).length > 0 + ) + .map(({ title, pathSettings }) => { + const visibleSettings = pathSettings.filter( + (s) => !String(s?.key || '').endsWith('_owner') + ); + return ( + +
+ {visibleSettings.map((setting) => { + const value = values?.[setting.key]; + const error = errors?.[setting.key] || null; + const dirty = Boolean(dirtyKeys?.has?.(setting.key)); + const ownerKey = `${setting.key}_owner`; + const ownerSetting = settingsByKey.get(ownerKey) || null; + const ownerValue = values?.[ownerKey]; + const ownerError = errors?.[ownerKey] || null; + const ownerDirty = Boolean(dirtyKeys?.has?.(ownerKey)); + return ( + + ); + })} +
+
+ ); + })} +
); } diff --git a/frontend/src/pages/DashboardPage.jsx b/frontend/src/pages/DashboardPage.jsx index 7b24451..a94f065 100644 --- a/frontend/src/pages/DashboardPage.jsx +++ b/frontend/src/pages/DashboardPage.jsx @@ -2113,165 +2113,6 @@ export default function DashboardPage({
- {monitoringState.enabled ? ( - -
- -
- - {monitoringState.error ? ( - {monitoringState.error} - ) : null} - - {!monitoringState.enabled ? ( -

Monitoring ist deaktiviert. Aktivierung in den Settings unter Kategorie "Monitoring".

- ) : !monitoringSample ? ( -

Monitoring ist aktiv. Erste Messwerte werden gesammelt ...

- ) : ( -
-
-

CPU

-
-
- - {formatPercent(cpuMetrics?.overallUsagePercent)} -
-
- - {formatTemperature(cpuMetrics?.overallTemperatureC)} -
-
-
- - {Array.isArray(cpuMetrics?.loadAverage) ? cpuMetrics.loadAverage.join(' / ') : '-'} -
- {cpuPerCoreMetrics.length > 0 ? ( - - ) : null} -
-
- {cpuPerCoreMetrics.length === 0 ? ( - Pro-Core-Daten sind noch nicht verfuegbar. - ) : null} - {cpuPerCoreMetrics.length > 0 && cpuCoresExpanded ? ( -
- {cpuPerCoreMetrics.map((core) => ( -
-
C{core.index}
-
- - {formatPercent(core.usagePercent)} -
-
- - {formatTemperature(core.temperatureC)} -
-
- ))} -
- ) : null} -
- -
-

RAM

-
-
- - {formatPercent(memoryMetrics?.usagePercent)} -
-
- - {formatBytes(memoryMetrics?.usedBytes)} -
-
- - {formatBytes(memoryMetrics?.freeBytes)} -
-
- - {formatBytes(memoryMetrics?.totalBytes)} -
-
-
- -
-

GPU

- {!gpuMetrics?.available ? ( - {gpuMetrics?.message || 'Keine GPU-Metriken verfuegbar.'} - ) : ( -
- {gpuDevices.map((gpu, index) => ( -
- - GPU {gpu?.index ?? index} - {gpu?.name ? ` | ${gpu.name}` : ''} - - Load: {formatPercent(gpu?.utilizationPercent)} - Mem-Load: {formatPercent(gpu?.memoryUtilizationPercent)} - Temp: {formatTemperature(gpu?.temperatureC)} - VRAM: {formatBytes(gpu?.memoryUsedBytes)} / {formatBytes(gpu?.memoryTotalBytes)} - Power: {Number.isFinite(Number(gpu?.powerDrawW)) ? `${gpu.powerDrawW} W` : 'n/a'} / {Number.isFinite(Number(gpu?.powerLimitW)) ? `${gpu.powerLimitW} W` : 'n/a'} -
- ))} -
- )} -
- -
-

Freier Speicher

-
- {storageGroups.map((group) => { - const rep = group.representative; - const tone = getStorageUsageTone(rep?.usagePercent); - const usagePercent = Number(rep?.usagePercent); - const barValue = Number.isFinite(usagePercent) - ? Math.max(0, Math.min(100, usagePercent)) - : 0; - const hasError = group.entries.every((e) => e?.error); - const groupKey = group.mountPoint || group.entries.map((e) => e?.key).join('-'); - const labels = group.entries.map((e) => e?.label || e?.key || 'Pfad').join(' · '); - return ( -
- {labels} - {hasError ? ( - {rep?.error} - ) : ( - <> -
-
- -
- - {formatPercent(rep?.usagePercent)} - -
-
- Frei: {formatBytes(rep?.freeBytes)} - Gesamt: {formatBytes(rep?.totalBytes)} -
- - )} -
- ); - })} -
-
-
- )} -
- ) : null} -
@@ -2390,6 +2231,48 @@ export default function DashboardPage({

Aktuell keine Disk erkannt.

)}
+ + +
+ {storageGroups.map((group) => { + const rep = group.representative; + const tone = getStorageUsageTone(rep?.usagePercent); + const usagePercent = Number(rep?.usagePercent); + const barValue = Number.isFinite(usagePercent) + ? Math.max(0, Math.min(100, usagePercent)) + : 0; + const hasError = group.entries.every((e) => e?.error); + const groupKey = group.mountPoint || group.entries.map((e) => e?.key).join('-'); + const labels = group.entries.map((e) => e?.label || e?.key || 'Pfad').join(' · '); + return ( +
+ {labels} + {hasError ? ( + {rep?.error} + ) : ( + <> +
+
+ +
+ + {formatPercent(rep?.usagePercent)} + +
+
+ Frei: {formatBytes(rep?.freeBytes)} + Gesamt: {formatBytes(rep?.totalBytes)} +
+ + )} +
+ ); + })} +
+
@@ -2923,6 +2806,116 @@ export default function DashboardPage({
+ {monitoringState.enabled ? ( + +
+ {!monitoringState.enabled ? ( + Hardware-Monitoring ist deaktiviert. + ) : !monitoringSample ? ( + Warte auf erste Messung ... + ) : ( +
+
+

CPU

+
+
+ + {formatPercent(cpuMetrics?.overallUsagePercent)} +
+
+ + {formatTemperature(cpuMetrics?.overallTemperatureC)} +
+
+
+ + {Array.isArray(cpuMetrics?.loadAverage) ? cpuMetrics.loadAverage.join(' / ') : '-'} +
+ {cpuPerCoreMetrics.length > 0 ? ( + + ) : null} +
+
+ {cpuPerCoreMetrics.length === 0 ? ( + Pro-Core-Daten sind noch nicht verfuegbar. + ) : null} + {cpuPerCoreMetrics.length > 0 && cpuCoresExpanded ? ( +
+ {cpuPerCoreMetrics.map((core) => ( +
+
C{core.index}
+
+ + {formatPercent(core.usagePercent)} +
+
+ + {formatTemperature(core.temperatureC)} +
+
+ ))} +
+ ) : null} +
+ +
+

RAM

+
+
+ + {formatPercent(memoryMetrics?.usagePercent)} +
+
+ + {formatBytes(memoryMetrics?.usedBytes)} +
+
+ + {formatBytes(memoryMetrics?.freeBytes)} +
+
+ + {formatBytes(memoryMetrics?.totalBytes)} +
+
+
+ +
+

GPU

+ {!gpuMetrics?.available ? ( + {gpuMetrics?.message || 'Keine GPU-Metriken verfuegbar.'} + ) : ( +
+ {gpuDevices.map((gpu, index) => ( +
+ + GPU {gpu?.index ?? index} + {gpu?.name ? ` | ${gpu.name}` : ''} + + Load: {formatPercent(gpu?.utilizationPercent)} + Mem-Load: {formatPercent(gpu?.memoryUtilizationPercent)} + Temp: {formatTemperature(gpu?.temperatureC)} + VRAM: {formatBytes(gpu?.memoryUsedBytes)} / {formatBytes(gpu?.memoryTotalBytes)} + Power: {Number.isFinite(Number(gpu?.powerDrawW)) ? `${gpu.powerDrawW} W` : 'n/a'} / {Number.isFinite(Number(gpu?.powerLimitW)) ? `${gpu.powerLimitW} W` : 'n/a'} +
+ ))} +
+ )} +
+
+ )} +
+
+ ) : null} + - {activationBytes.length > 0 && ( + {expertModeEnabled && activationBytes.length > 0 && (