From 5a0faad429c716d5f8201b6e190fafadfc3a18ae Mon Sep 17 00:00:00 2001 From: bonamin Date: Sun, 22 Feb 2026 21:20:16 +0200 Subject: [PATCH] CODEX - Moar Changes --- frontend/src/melodies/MelodyList.jsx | 127 ++++++++++++++++++++------- 1 file changed, 97 insertions(+), 30 deletions(-) diff --git a/frontend/src/melodies/MelodyList.jsx b/frontend/src/melodies/MelodyList.jsx index 9f4c1f4..35a416b 100644 --- a/frontend/src/melodies/MelodyList.jsx +++ b/frontend/src/melodies/MelodyList.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef, useMemo } from "react"; +import { useState, useEffect, useRef, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import api from "../api/client"; import { useAuth } from "../auth/AuthContext"; @@ -14,6 +14,12 @@ import { const MELODY_TYPES = ["", "orthodox", "catholic", "all"]; const MELODY_TONES = ["", "normal", "festive", "cheerful", "lamentation"]; const NOTE_LABELS = "ABCDEFGHIJKLMNOP"; +const SORTABLE_COLUMN_TO_KEY = { + name: "name", + totalActiveBells: "totalActiveBells", + dateCreated: "dateCreated", + dateEdited: "dateEdited", +}; // All available columns with their defaults const ALL_COLUMNS = [ @@ -271,7 +277,7 @@ export default function MelodyList() { switch (key) { case "name": return getDisplayName(info.name).toLowerCase(); - case "totalBells": + case "totalActiveBells": return Number(info.totalActiveBells || 0); case "dateEdited": return parseDateValue(metadata.dateEdited); @@ -300,6 +306,24 @@ export default function MelodyList() { }); }, [melodies, createdByFilter, sortBy, sortDir]); // eslint-disable-line react-hooks/exhaustive-deps + const handleSortClick = (columnKey) => { + const nextSortKey = SORTABLE_COLUMN_TO_KEY[columnKey]; + if (!nextSortKey) return; + if (sortBy === nextSortKey) { + setSortDir((prev) => (prev === "asc" ? "desc" : "asc")); + return; + } + setSortBy(nextSortKey); + setSortDir(nextSortKey === "dateCreated" || nextSortKey === "dateEdited" ? "desc" : "asc"); + }; + + const getSortIndicator = (columnKey) => { + const sortKey = SORTABLE_COLUMN_TO_KEY[columnKey]; + if (!sortKey) return null; + if (sortBy !== sortKey) return "↕"; + return sortDir === "asc" ? "▲" : "▼"; + }; + const renderCellValue = (key, row) => { const info = row.information || {}; const ds = row.default_settings || {}; @@ -398,7 +422,44 @@ export default function MelodyList() { ); case "duration": - return ds.duration != null ? formatDuration(ds.duration) : "-"; + if (ds.duration == null) return "-"; + if (Number(ds.duration) === 0) { + return ( + + Single Run + + ); + } + { + const allDurationValues = melodySettings?.duration_values || []; + const nonZeroDurations = allDurationValues.filter((v) => Number(v) > 0); + const idx = nonZeroDurations.indexOf(Number(ds.duration)); + const percent = idx >= 0 && nonZeroDurations.length > 0 + ? Math.round(((idx + 1) / nonZeroDurations.length) * 100) + : 0; + return ( +
+
+ {formatDuration(ds.duration)} +
+
+
+
+
+ ); + } case "totalRunDuration": return ds.totalRunDuration ?? "-"; case "pauseDuration": @@ -417,14 +478,14 @@ export default function MelodyList() { ); case "noteAssignments": return ds.noteAssignments?.length > 0 ? ( -
+
{ds.noteAssignments.map((assignedBell, noteIdx) => (
- {assignedBell > 0 ? assignedBell : "—"} + {assignedBell > 0 ? assignedBell : "—"}
))} @@ -551,26 +612,6 @@ export default function MelodyList() { - - - -
+ ) : null} +
+ )} ))} {canEdit && ( @@ -748,7 +812,9 @@ export default function MelodyList() { {activeColumns.map((col) => ( {renderCellValue(col.key, row)} @@ -819,3 +885,4 @@ export default function MelodyList() {
); } +