fix: scan visibility, NC folder validation, watcher logging
- nc-scan: detailed INFO logging of every path found, subfolder contents and skip reasons; 502 now includes the exact folder and error so user sees a real message instead of a blank result - band creation: if nc_base_path is explicitly given, verify the folder exists in Nextcloud before saving — returns 422 with a clear message to the user; auto-generated paths still do MKCOL - songs search: add ?unattributed=true to return songs with no session_id (files not in a YYMMDD folder) - BandPage: show "Unattributed Recordings" section below sessions so scanned files without a dated folder always appear - watcher event_loop: promote all per-activity log lines from DEBUG to INFO so they're visible in default Docker Compose log output; log normalized path and skip reason for every activity Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,12 @@ export function BandPage() {
|
||||
enabled: !!bandId && tab === "dates",
|
||||
});
|
||||
|
||||
const { data: unattributedSongs } = useQuery({
|
||||
queryKey: ["songs-unattributed", bandId],
|
||||
queryFn: () => api.get<SongSummary[]>(`/bands/${bandId}/songs/search?unattributed=true`),
|
||||
enabled: !!bandId && tab === "dates",
|
||||
});
|
||||
|
||||
const { data: members } = useQuery({
|
||||
queryKey: ["members", bandId],
|
||||
queryFn: () => api.get<BandMember[]>(`/bands/${bandId}/members`),
|
||||
@@ -121,6 +127,7 @@ export function BandPage() {
|
||||
mutationFn: () => api.post<NcScanResult>(`/bands/${bandId}/nc-scan`, {}),
|
||||
onSuccess: (result) => {
|
||||
qc.invalidateQueries({ queryKey: ["sessions", bandId] });
|
||||
qc.invalidateQueries({ queryKey: ["songs-unattributed", bandId] });
|
||||
if (result.imported > 0) {
|
||||
setScanMsg(`Imported ${result.imported} new song${result.imported !== 1 ? "s" : ""} from ${result.folder} (${result.skipped} already registered).`);
|
||||
} else if (result.files_found === 0) {
|
||||
@@ -404,11 +411,53 @@ export function BandPage() {
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
{sessions?.length === 0 && (
|
||||
{sessions?.length === 0 && !unattributedSongs?.length && (
|
||||
<p style={{ color: "var(--text-muted)", fontSize: 13 }}>
|
||||
No sessions yet. Scan Nextcloud to import from <code style={{ color: "var(--teal)" }}>{band.nc_folder_path ?? `bands/${band.slug}/`}</code>.
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Songs not linked to any dated session */}
|
||||
{!!unattributedSongs?.length && (
|
||||
<div style={{ marginTop: sessions?.length ? 24 : 0 }}>
|
||||
<div style={{ color: "var(--text-muted)", fontSize: 11, fontFamily: "monospace", letterSpacing: 1, marginBottom: 8 }}>
|
||||
UNATTRIBUTED RECORDINGS
|
||||
</div>
|
||||
<div style={{ display: "grid", gap: 6 }}>
|
||||
{unattributedSongs.map((song) => (
|
||||
<Link
|
||||
key={song.id}
|
||||
to={`/bands/${bandId}/songs/${song.id}`}
|
||||
style={{
|
||||
background: "var(--bg-inset)",
|
||||
border: "1px solid var(--border)",
|
||||
borderRadius: 8,
|
||||
padding: "14px 18px",
|
||||
textDecoration: "none",
|
||||
color: "var(--text)",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<div style={{ minWidth: 0 }}>
|
||||
<div style={{ fontWeight: 500, marginBottom: 4 }}>{song.title}</div>
|
||||
<div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
|
||||
{song.tags.map((t) => (
|
||||
<span key={t} style={{ background: "var(--teal-bg)", color: "var(--teal)", fontSize: 9, padding: "1px 6px", borderRadius: 3, fontFamily: "monospace" }}>{t}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<span style={{ color: "var(--text-muted)", fontSize: 12, whiteSpace: "nowrap" }}>
|
||||
<span style={{ background: "var(--bg-subtle)", borderRadius: 4, padding: "2px 6px", marginRight: 8, fontFamily: "monospace", fontSize: 10 }}>{song.status}</span>
|
||||
{song.version_count} version{song.version_count !== 1 ? "s" : ""}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user