CODEX - Thrid Try for the fix

This commit is contained in:
2026-02-23 12:13:52 +02:00
parent 14a7250eef
commit d49a9636e5

View File

@@ -958,8 +958,8 @@ export default function MelodyList() {
const selectClass = "px-3 py-2 rounded-md text-sm cursor-pointer border"; const selectClass = "px-3 py-2 rounded-md text-sm cursor-pointer border";
return ( return (
<div className="w-full min-w-0 max-w-full" style={{ overflowX: "clip" }}> <div className="w-full min-w-0 max-w-full overflow-hidden">
<div className="w-full max-w-full overflow-x-hidden relative z-40"> <div className="w-full min-w-0 relative" style={{ zIndex: 30 }}>
<div className="flex items-center justify-between mb-6 w-full min-w-0"> <div className="flex items-center justify-between mb-6 w-full min-w-0">
<h1 className="text-2xl font-bold" style={{ color: "var(--text-heading)" }}>Melodies</h1> <h1 className="text-2xl font-bold" style={{ color: "var(--text-heading)" }}>Melodies</h1>
{canEdit && ( {canEdit && (
@@ -973,187 +973,187 @@ export default function MelodyList() {
)} )}
</div> </div>
<div className="mb-4 space-y-3 w-full min-w-0"> <div className="mb-4 space-y-3 w-full min-w-0 relative" style={{ zIndex: 40 }}>
<SearchBar <SearchBar
onSearch={setSearch} onSearch={setSearch}
placeholder="Search by name, description, or tags..." placeholder="Search by name, description, or tags..."
/> />
<div className="flex flex-wrap gap-3 items-center w-full min-w-0"> <div className="w-full min-w-0 flex items-start justify-between gap-3 flex-wrap">
<select <div className="min-w-0 flex-1 flex flex-wrap gap-3 items-center">
value={typeFilter}
onChange={(e) => setTypeFilter(e.target.value)}
className={selectClass}
>
<option value="">All Types</option>
{MELODY_TYPES.filter(Boolean).map((t) => (
<option key={t} value={t}>
{t.charAt(0).toUpperCase() + t.slice(1)}
</option>
))}
</select>
<select
value={toneFilter}
onChange={(e) => setToneFilter(e.target.value)}
className={selectClass}
>
<option value="">All Tones</option>
{MELODY_TONES.filter(Boolean).map((t) => (
<option key={t} value={t}>
{t.charAt(0).toUpperCase() + t.slice(1)}
</option>
))}
</select>
<select
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
className={selectClass}
>
<option value="">All Statuses</option>
<option value="published">Published (Live)</option>
<option value="draft">Drafts</option>
</select>
<div className="relative z-50" ref={creatorPickerRef}>
<button
type="button"
onClick={() => setShowCreatorPicker((prev) => !prev)}
className="px-3 py-2 rounded-md text-sm transition-colors cursor-pointer flex items-center gap-1.5 border"
style={{ borderColor: "var(--border-primary)", color: "var(--text-secondary)" }}
>
Created By
{createdByFilter.length > 0 ? ` (${createdByFilter.length})` : ""}
</button>
{showCreatorPicker && (
<div
className="absolute left-0 top-full mt-1 z-[80] rounded-lg shadow-lg py-2 w-64 border max-h-64 overflow-auto"
style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
>
{allCreators.length === 0 ? (
<p className="px-3 py-1.5 text-sm" style={{ color: "var(--text-muted)" }}>No creators found</p>
) : (
allCreators.map((creator) => (
<label
key={creator}
className="flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer"
style={{ color: "var(--text-primary)" }}
>
<input
type="checkbox"
checked={createdByFilter.includes(creator)}
onChange={() => toggleCreator(creator)}
className="h-3.5 w-3.5 rounded cursor-pointer"
/>
{creator}
</label>
))
)}
{createdByFilter.length > 0 && (
<button
type="button"
onClick={() => setCreatedByFilter([])}
className="w-full text-left px-3 py-1.5 text-xs underline"
style={{ color: "var(--accent)", background: "none", border: "none" }}
>
Clear selection
</button>
)}
</div>
)}
</div>
{languages.length > 1 && (
<select <select
value={displayLang} value={typeFilter}
onChange={(e) => setDisplayLang(e.target.value)} onChange={(e) => setTypeFilter(e.target.value)}
className={selectClass} className={selectClass}
> >
{languages.map((l) => ( <option value="">All Types</option>
<option key={l} value={l}> {MELODY_TYPES.filter(Boolean).map((t) => (
{getLanguageName(l)} <option key={t} value={t}>
{t.charAt(0).toUpperCase() + t.slice(1)}
</option> </option>
))} ))}
</select> </select>
)}
{/* Column visibility dropdown */} <select
<div className="relative z-50" ref={columnPickerRef}> value={toneFilter}
<button onChange={(e) => setToneFilter(e.target.value)}
type="button" className={selectClass}
onClick={() => setShowColumnPicker((prev) => !prev)}
className="px-3 py-2 rounded-md text-sm transition-colors cursor-pointer flex items-center gap-1.5 border"
style={{
borderColor: "var(--border-primary)",
color: "var(--text-secondary)",
}}
> >
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <option value="">All Tones</option>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" /> {MELODY_TONES.filter(Boolean).map((t) => (
</svg> <option key={t} value={t}>
Columns {t.charAt(0).toUpperCase() + t.slice(1)}
</button> </option>
{showColumnPicker && ( ))}
<div </select>
className="absolute right-0 top-full mt-1 z-[80] rounded-lg shadow-lg py-2 w-56 border"
<select
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
className={selectClass}
>
<option value="">All Statuses</option>
<option value="published">Published (Live)</option>
<option value="draft">Drafts</option>
</select>
<div className="relative" ref={creatorPickerRef} style={{ zIndex: 60 }}>
<button
type="button"
onClick={() => setShowCreatorPicker((prev) => !prev)}
className="px-3 py-2 rounded-md text-sm transition-colors cursor-pointer flex items-center gap-1.5 border"
style={{ borderColor: "var(--border-primary)", color: "var(--text-secondary)" }}
>
Created By
{createdByFilter.length > 0 ? ` (${createdByFilter.length})` : ""}
</button>
{showCreatorPicker && (
<div
className="absolute left-0 top-full mt-1 rounded-lg shadow-lg py-2 w-64 border max-h-64 overflow-auto"
style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)", zIndex: 9999 }}
>
{allCreators.length === 0 ? (
<p className="px-3 py-1.5 text-sm" style={{ color: "var(--text-muted)" }}>No creators found</p>
) : (
allCreators.map((creator) => (
<label
key={creator}
className="flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer"
style={{ color: "var(--text-primary)" }}
>
<input
type="checkbox"
checked={createdByFilter.includes(creator)}
onChange={() => toggleCreator(creator)}
className="h-3.5 w-3.5 rounded cursor-pointer"
/>
{creator}
</label>
))
)}
{createdByFilter.length > 0 && (
<button
type="button"
onClick={() => setCreatedByFilter([])}
className="w-full text-left px-3 py-1.5 text-xs underline"
style={{ color: "var(--accent)", background: "none", border: "none" }}
>
Clear selection
</button>
)}
</div>
)}
</div>
{languages.length > 1 && (
<select
value={displayLang}
onChange={(e) => setDisplayLang(e.target.value)}
className={selectClass}
>
{languages.map((l) => (
<option key={l} value={l}>
{getLanguageName(l)}
</option>
))}
</select>
)}
<div className="relative" ref={columnPickerRef} style={{ zIndex: 60 }}>
<button
type="button"
onClick={() => setShowColumnPicker((prev) => !prev)}
className="px-3 py-2 rounded-md text-sm transition-colors cursor-pointer flex items-center gap-1.5 border"
style={{ style={{
backgroundColor: "var(--bg-card)",
borderColor: "var(--border-primary)", borderColor: "var(--border-primary)",
color: "var(--text-secondary)",
}} }}
> >
{orderedColumnPickerColumns.map((col) => { <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
const orderIdx = visibleColumns.indexOf(col.key); <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" />
const canMove = orderIdx >= 0; </svg>
return ( Columns
<label </button>
key={col.key} {showColumnPicker && (
className="flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer" <div
style={{ color: col.alwaysOn ? "var(--text-muted)" : "var(--text-primary)" }} className="absolute right-0 top-full mt-1 rounded-lg shadow-lg py-2 w-56 border"
> style={{
<input backgroundColor: "var(--bg-card)",
type="checkbox" borderColor: "var(--border-primary)",
checked={isVisible(col.key)} zIndex: 9999,
onChange={() => toggleColumn(col.key)} }}
disabled={col.alwaysOn} >
className="h-3.5 w-3.5 rounded cursor-pointer" {orderedColumnPickerColumns.map((col) => {
/> const orderIdx = visibleColumns.indexOf(col.key);
<span className="flex-1">{col.label}</span> const canMove = orderIdx >= 0;
{canMove && ( return (
<span className="inline-flex gap-1" onClick={(e) => e.stopPropagation()}> <label
<button key={col.key}
type="button" className="flex items-center gap-2 px-3 py-1.5 text-sm cursor-pointer"
onClick={() => moveColumn(col.key, "up")} style={{ color: col.alwaysOn ? "var(--text-muted)" : "var(--text-primary)" }}
className="text-[10px] px-1 rounded border" >
style={{ borderColor: "var(--border-primary)", color: "var(--text-muted)", background: "transparent" }} <input
title="Move up" type="checkbox"
> checked={isVisible(col.key)}
onChange={() => toggleColumn(col.key)}
</button> disabled={col.alwaysOn}
<button className="h-3.5 w-3.5 rounded cursor-pointer"
type="button" />
onClick={() => moveColumn(col.key, "down")} <span className="flex-1">{col.label}</span>
className="text-[10px] px-1 rounded border" {canMove && (
style={{ borderColor: "var(--border-primary)", color: "var(--text-muted)", background: "transparent" }} <span className="inline-flex gap-1" onClick={(e) => e.stopPropagation()}>
title="Move down" <button
> type="button"
onClick={() => moveColumn(col.key, "up")}
</button> className="text-[10px] px-1 rounded border"
</span> style={{ borderColor: "var(--border-primary)", color: "var(--text-muted)", background: "transparent" }}
)} title="Move up"
</label> >
);
})} </button>
</div> <button
)} type="button"
onClick={() => moveColumn(col.key, "down")}
className="text-[10px] px-1 rounded border"
style={{ borderColor: "var(--border-primary)", color: "var(--text-muted)", background: "transparent" }}
title="Move down"
>
</button>
</span>
)}
</label>
);
})}
</div>
)}
</div>
</div> </div>
<div className="ml-auto flex items-center gap-3 flex-nowrap min-w-0"> <div className="flex items-center justify-end gap-3 shrink-0 flex-wrap ml-auto">
<span className="text-sm whitespace-nowrap" style={{ color: "var(--text-muted)" }}> <span className="text-sm whitespace-nowrap" style={{ color: "var(--text-muted)" }}>
<span className="inline-block max-w-[48vw] overflow-hidden text-ellipsis align-bottom"> {hasAnyFilter
{hasAnyFilter ? `Filtered - Showing ${displayRows.length} / ${allMelodyCount || melodies.length} Melodies | ${offlineTaggedCount} Melodies tagged for Offline`
? `Filtered - Showing ${displayRows.length} / ${allMelodyCount || melodies.length} Melodies | ${offlineTaggedCount} Melodies tagged for Offline` : `Showing all (${allMelodyCount || melodies.length}) Melodies | ${offlineTaggedCount} Melodies tagged for Offline`}
: `Showing all (${allMelodyCount || melodies.length}) Melodies | ${offlineTaggedCount} Melodies tagged for Offline`}
</span>
</span> </span>
{canEdit && ( {canEdit && (
<button <button
@@ -1209,7 +1209,7 @@ export default function MelodyList() {
}} }}
> >
<div className="w-full max-w-full overflow-x-auto relative z-0"> <div className="w-full max-w-full overflow-x-auto relative z-0">
<table className="w-full text-sm min-w-max"> <table className="w-full min-w-full text-sm">
<thead> <thead>
<tr style={{ backgroundColor: "var(--bg-primary)", borderBottom: "1px solid var(--border-primary)" }}> <tr style={{ backgroundColor: "var(--bg-primary)", borderBottom: "1px solid var(--border-primary)" }}>
{activeColumns.map((col) => ( {activeColumns.map((col) => (