Enhance mobile menu styles and update progress handling in RequestManagement component

This commit is contained in:
2025-12-24 07:50:15 -05:00
parent bc847629e6
commit bb71f662ed
8 changed files with 52 additions and 35 deletions

View File

@@ -17,9 +17,9 @@ interface RequestJob {
tracks: number;
quality: string;
status: string;
progress: number;
progress: number | string | null;
type?: string;
tarball_path?: string;
tarball?: string;
created_at?: string;
updated_at?: string;
[key: string]: unknown;
@@ -40,9 +40,13 @@ export default function RequestManagement() {
const pollingDetailRef = useRef<ReturnType<typeof setInterval> | null>(null);
const resolveTarballPath = (job: RequestJob) => job.tarball;
const tarballUrl = (absPath: string | undefined, quality: string) => {
if (!absPath) return null;
const filename = absPath.split("/").pop(); // get "SOMETHING.tar.gz"
// If the backend already stores a fully qualified URL, return as-is
if (/^https?:\/\//i.test(absPath)) return absPath;
return `${TAR_BASE_URL}/${quality}/${filename}`;
};
@@ -172,24 +176,21 @@ export default function RequestManagement() {
const formatProgress = (p: unknown) => {
if (p === null || p === undefined || p === "") return "—";
const num = Number(p);
if (Number.isNaN(num)) return "—";
const pct = num > 1 ? Math.round(num) : num;
const pct = computePct(p);
return `${pct}%`;
};
const computePct = (p: unknown) => {
if (p === null || p === undefined || p === "") return 0;
const num = Number(p);
if (Number.isNaN(num)) return 0;
return Math.min(100, Math.max(0, num > 1 ? Math.round(num) : Math.round(num * 100)));
if (!Number.isFinite(num)) return 0;
const normalized = num > 1 ? num : num * 100;
return Math.min(100, Math.max(0, Math.round(normalized)));
};
const progressBarTemplate = (rowData: RequestJob) => {
const p = rowData.progress;
if (p === null || p === undefined || p === 0) return "—";
const num = Number(p);
if (Number.isNaN(num)) return "—";
if (p === null || p === undefined || p === "") return "—";
const pct = computePct(p);
const getProgressColor = () => {
@@ -341,7 +342,7 @@ export default function RequestManagement() {
</span>
}
body={(row: RequestJob) => {
const url = tarballUrl(row.tarball_path, row.quality || "FLAC");
const url = tarballUrl(resolveTarballPath(row as RequestJob), row.quality || "FLAC");
if (!url) return "—";
const encodedURL = encodeURI(url);
@@ -409,18 +410,25 @@ export default function RequestManagement() {
<strong>Progress:</strong>
<div className="rm-progress-container mt-2">
<div className="rm-progress-track rm-progress-track-lg">
{(() => {
const pctDialog = computePct(selectedRequest.progress);
const status = selectedRequest.status;
const fillColor = status === "Failed" ? "bg-red-500" : status === "Finished" ? "bg-green-500" : "bg-blue-500";
return (
<div
className={`rm-progress-fill ${selectedRequest.status === "Failed" ? "bg-red-500" : selectedRequest.status === "Finished" ? "bg-green-500" : "bg-blue-500"}`}
style={{
['--rm-progress' as string]: (computePct(selectedRequest.progress) / 100).toString(),
borderTopRightRadius: computePct(selectedRequest.progress) >= 100 ? '999px' : 0,
borderBottomRightRadius: computePct(selectedRequest.progress) >= 100 ? '999px' : 0
}}
data-pct={computePct(selectedRequest.progress)}
aria-valuenow={Math.min(100, Math.max(0, Number(selectedRequest.progress) > 1 ? Math.round(selectedRequest.progress) : selectedRequest.progress * 100))}
aria-valuemin={0}
aria-valuemax={100}
/>
className={`rm-progress-fill ${fillColor}`}
style={{
['--rm-progress' as string]: (pctDialog / 100).toString(),
borderTopRightRadius: pctDialog >= 100 ? '999px' : 0,
borderBottomRightRadius: pctDialog >= 100 ? '999px' : 0
}}
data-pct={pctDialog}
aria-valuenow={pctDialog}
aria-valuemin={0}
aria-valuemax={100}
/>
);
})()}
</div>
<span className="rm-progress-text">{formatProgress(selectedRequest.progress)}</span>
</div>
@@ -437,17 +445,17 @@ export default function RequestManagement() {
{/* --- Tarball Card --- */}
{
selectedRequest.tarball_path && (
selectedRequest.tarball && (
<div className="p-3 bg-gray-100 dark:bg-neutral-800 rounded-md">
<p>
<strong>Tarball:</strong>{" "}
<a
href={encodeURI(tarballUrl(selectedRequest.tarball_path, selectedRequest.quality) || "")}
href={encodeURI(tarballUrl(resolveTarballPath(selectedRequest), selectedRequest.quality) || "")}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:underline"
>
{tarballUrl(selectedRequest.tarball_path, selectedRequest.quality)?.split("/").pop()}
{tarballUrl(resolveTarballPath(selectedRequest), selectedRequest.quality)?.split("/").pop()}
</a>
</p>
</div>