diff --git a/services/web-ui/public/screens-library.jsx b/services/web-ui/public/screens-library.jsx index 6a19443..daf8972 100644 --- a/services/web-ui/public/screens-library.jsx +++ b/services/web-ui/public/screens-library.jsx @@ -23,18 +23,18 @@ function Library({ navigate, onOpenAsset, openProject }) { }, [openProject]); const createBin = () => { - if (!openProject) { - window.alert('Open a project first (Projects → click a project), then create a bin inside it.'); - return; - } - const name = prompt('Bin name', ''); - if (!name || !name.trim()) return; + if (!openProject) { window.alert('Open a project first (Projects → click a project), then create a bin inside it.'); return; } + setNewBinName(''); setCreatingBin(true); + }; + + const submitBin = (name) => { + if (!name || !name.trim()) { setCreatingBin(false); return; } + setCreatingBin(false); window.ZAMPP_API.fetch('/bins', { method: 'POST', body: JSON.stringify({ project_id: openProject.id, name: name.trim() }), }) .then(() => { - // Re-fetch project-scoped list to get the count column. window.ZAMPP_API.fetch('/bins?project_id=' + openProject.id) .then(list => setBins((list || []).map(b => ({ ...b, count: b.asset_count || 0, icon: b.type || 'grid' })))); }) @@ -48,6 +48,9 @@ function Library({ navigate, onOpenAsset, openProject }) { // a full app reload — keeps ZAMPP_DATA in sync as the cache of record. const [allAssets, setAllAssets] = React.useState(window.ZAMPP_DATA.ASSETS || []); const [ctxMenu, setCtxMenu] = React.useState(null); // { asset, x, y } + const [renamingAsset, setRenamingAsset] = React.useState(null); + const [creatingBin, setCreatingBin] = React.useState(false); + const [newBinName, setNewBinName] = React.useState(''); const refreshAssets = React.useCallback(() => { window.ZAMPP_API.fetch('/assets?limit=500') @@ -83,14 +86,21 @@ function Library({ navigate, onOpenAsset, openProject }) { setCtxMenu({ asset, x: e.clientX, y: e.clientY }); }; + const [selectedBinId, setSelectedBinId] = React.useState(null); + // Clear bin filter on project change so a stale id doesn't hide everything. + React.useEffect(() => { setSelectedBinId(null); }, [openProject?.id]); let assets = openProject ? allAssets.filter(function(a) { return a.project_id === openProject.id; }) : allAssets; const ALL_ASSETS = allAssets; if (filter !== 'all') assets = assets.filter(function(a) { return a.status === filter; }); if (search) assets = assets.filter(function(a) { return a.name.toLowerCase().includes(search.toLowerCase()); }); + if (selectedBinId) assets = assets.filter(function(a) { return a.bin_id === selectedBinId; }); - const displayTitle = openProject ? openProject.name : 'All Assets'; + const activeBin = selectedBinId ? BINS.find(b => b.id === selectedBinId) : null; + const displayTitle = activeBin + ? (openProject ? openProject.name + ' · ' : '') + activeBin.name + : (openProject ? openProject.name : 'All Assets'); const errorCount = ALL_ASSETS.filter(function(a) { return a.status === 'error'; }).length; const recentCount = ALL_ASSETS.filter(function(a) { return (Date.now() - new Date(a.created_at)) < 86400000; }).length; @@ -127,13 +137,35 @@ function Library({ navigate, onOpenAsset, openProject }) {