ELNOR REPO READER TEXT MIRROR Original path: Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/Q_BROWSER_R13 (DOC20).jsx Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- import { useState, useRef, useEffect, useMemo } from "react"; const font={sans:"'Söhne','Helvetica Neue',-apple-system,BlinkMacSystemFont,sans-serif"}; const R={sm:"6px",md:"10px",lg:"14px",full:"9999px"}; const c={bgApp:"#F8F8F6",bgPanel:"#FFFFFF",bgPanelAlt:"#F9FAFB",bgCard:"#FFFFFF",bgInput:"#EFF1F3",bgSidebar:"#131820",textPri:"#1A1D21",textSec:"#5E6570",textTer:"#8B919A",accentBtn:"#31588c",warn:"#D97706",error:"#B04040",border:"#E0E2E5",borderLight:"#ECEEF0",green:"#2E8B57",neutral:"#6B7280",agentAv:"#a1a7aa",borderDark:"#263040"}; const Ic=({d,size=18,color,sw=1.75})=>; const I={Search:p=>,Plus:p=>,ChevR:p=>,ChevD:p=>,Pin:p=>,Folder:p=>,File:p=>,X:p=>,Check:p=>,Save:p=>,Trash:p=>,}; const Dot=({color,size=8})=>; const Toast=({msg,onDone})=>{useEffect(()=>{const t=setTimeout(onDone,2200);return()=>clearTimeout(t)},[onDone]);return
{msg}
}; const typeColors={Note:c.accentBtn,Chat:c.green,Doc:c.textTer,Task:c.warn,Artifact:"#8B5CF6",Prompt:"#D97706",Preset:c.neutral,Skill:c.neutral,Agent:"#5B5F97"}; const projects=[{id:1,name:"Henderson v. DataCorp",color:"#31588c"},{id:2,name:"Quark Research",color:"#2E8B57"},{id:3,name:"Internal Ops",color:"#8B7355"}]; const collections=[{name:"Priority",color:"#B04040"},{name:"Research",color:"#2E8B57"},{name:"Draft",color:"#D97706"},{name:"Archive",color:"#6B7280"},{name:"Urgent",color:"#9E5E5E"},{name:"Reference",color:"#5B5F97"}]; const scopeFams=["Collection","Project","Bucket","Places","Folders","Saved Views"]; const typeChips=["Document","Chat","Preset","Skill","Task","Agent","Overlay","Note","Artifact","Prompt"]; const sortOptions=["Modified","Alphabetical","Type","Created","Running"]; const savedViews=[{id:"sv1",name:"Current",sys:true},{id:"sv2",name:"Recent",sys:true},{id:"sv3",name:"No Project",sys:true}]; const initFolders=[{id:"f1",title:"Henderson Case",parent:null},{id:"f2",title:"Privilege Issues",parent:"f1"},{id:"f3",title:"Motion Practice",parent:"f1"},{id:"f4",title:"Quark Patents",parent:null},{id:"f5",title:"Reference Materials",parent:null}]; const initPlaces=[{id:"p1",title:"Henderson Case Files",path:"~/OneDrive-schallfirm/Henderson",status:"ok"},{id:"p2",title:"Firm Templates",path:"~/OneDrive-schallfirm/Templates",status:"ok"},{id:"p3",title:"Local Research",path:"~/Documents/Research",status:"ok"},{id:"p4",title:"Archived Cases",path:"/Volumes/External/Cases",status:"missing"}]; const placeContents={root:[{name:"Expert_Reports",isFolder:true},{name:"Exhibits",isFolder:true},{name:"Correspondence",isFolder:true},{name:"Henderson_Complaint.pdf",type:"PDF",size:"2.4 MB",mod:"1d"},{name:"Privilege_Log_v4.docx",type:"DOCX",size:"340 KB",mod:"3h"},{name:".DS_Store",type:"System",size:"4 KB",mod:"1d",dimmed:true}],Expert_Reports:[{name:"Dr_Smith_Report.pdf",type:"PDF",size:"1.2 MB",mod:"1w"},{name:"Valuation_Analysis.xlsx",type:"XLSX",size:"890 KB",mod:"2w"}],Exhibits:[{name:"Exhibit_A.pdf",type:"PDF",size:"3.1 MB",mod:"3d"},{name:"Exhibit_B.pdf",type:"PDF",size:"1.8 MB",mod:"3d"},{name:"Photos",isFolder:true}],Correspondence:[{name:"Letter_Mar15.docx",type:"DOCX",size:"45 KB",mod:"1d"}],Photos:[{name:"scene_01.jpg",type:"JPG",size:"4.2 MB",mod:"2w"}]}; const allItems=[ {type:"Note",title:"Henderson Discovery Priorities",time:"2h",pin:true,proj:1,cols:["Priority"]}, {type:"Note",title:"Weekly Task List",time:"4h",pin:true,proj:1,cols:[]}, {type:"Chat",title:"Henderson discovery analysis",time:"2m",unread:true,proj:1,cols:["Priority"]}, {type:"Artifact",title:"Motion for Summary Judgment Brief",time:"10m",proj:1,cols:[]}, {type:"Doc",title:"Henderson_Complaint.pdf",time:"1d",proj:1,cols:["Reference"]}, {type:"Note",title:"Quark Patent Analysis",time:"1d",proj:2,cols:["Research"]}, {type:"Task",title:"Review batch #4",time:"2h",proj:1,st:"running",cols:[]}, {type:"Chat",title:"Quark patent search",time:"1h",proj:2,cols:["Research"]}, {type:"Artifact",title:"Henderson Timeline Analysis",time:"2h",proj:1,cols:[]}, {type:"Doc",title:"Patent_US20240001.pdf",time:"2d",proj:2,cols:[]}, {type:"Note",title:"Judge Chen Conference Notes",time:"3d",proj:1,cols:[]}, {type:"Task",title:"Draft motion response",time:"4h",proj:1,st:"waiting",cols:["Priority"]}, {type:"Artifact",title:"Privilege Log Summary v3",time:"3d",proj:1,cols:[]}, {type:"Prompt",title:"Discovery Review Template",time:"1w",proj:null,cols:[]}, {type:"Preset",title:"Standard Review Preset",time:"1w",proj:null,cols:[]}, {type:"Doc",title:"Standing_Orders.md",time:"3d",proj:null,cols:["Reference"]}, ]; const timeVal=t=>{if(t.includes("m"))return parseInt(t);if(t.includes("h"))return parseInt(t)*60;if(t.includes("d"))return parseInt(t)*1440;if(t.includes("w"))return parseInt(t)*10080;return 99999}; export default function BrowserV4(){ const [activeScope,setActiveScope]=useState(null); const [activeProjIdx,setActiveProjIdx]=useState(0);const [noProject,setNoProject]=useState(false); const [activeTypes,setActiveTypes]=useState(new Set()); const [selectedCollections,setSelectedCollections]=useState(new Set()); const [splitterPos,setSplitterPos]=useState(120); const [browserWidth,setBrowserWidth]=useState(290); const [selectedIdx,setSelectedIdx]=useState(null); const [folders,setFolders]=useState(initFolders); const [expandedFolders,setExpandedFolders]=useState(new Set(["f1"])); const [activeFolder,setActiveFolder]=useState(null); const [places,setPlaces]=useState(initPlaces); const [activePlace,setActivePlace]=useState(null);const [placePath,setPlacePath]=useState([]); const [searchMode,setSearchMode]=useState("this_view"); const [sortKey,setSortKey]=useState("Modified");const [sortDrop,setSortDrop]=useState(false); const [newFolderMode,setNewFolderMode]=useState(null);const [newFolderName,setNewFolderName]=useState(""); const [hoverFolder,setHoverFolder]=useState(null);const [hoverPlace,setHoverPlace]=useState(null); const [toast,setToast]=useState(null); const [activeSavedView,setActiveSavedView]=useState(null); const [saveViewMode,setSaveViewMode]=useState(false);const [saveViewName,setSaveViewName]=useState(""); const [hoverSavedView,setHoverSavedView]=useState(null);const [userSavedViews,setUserSavedViews]=useState([]); const [saveFromBar,setSaveFromBar]=useState(false); const [deletingFolder,setDeletingFolder]=useState(null); const [removingPlace,setRemovingPlace]=useState(null); // FOLDER OVERLAY — independent of scope const [folderOverlay,setFolderOverlay]=useState(false); const [dropTarget,setDropTarget]=useState(null); const [dragItem,setDragItem]=useState(null); const nfRef=useRef(null); const flash=msg=>setToast(msg); const toggleType=t=>{const s=new Set(activeTypes);s.has(t)?s.delete(t):s.add(t);setActiveTypes(s)}; const toggleCollection=name=>{const s=new Set(selectedCollections);s.has(name)?s.delete(name):s.add(name);setSelectedCollections(s)}; const toggleFolder=id=>{const s=new Set(expandedFolders);s.has(id)?s.delete(id):s.add(id);setExpandedFolders(s)}; const selectScope=s=>{if(activeScope===s){setActiveScope(null);setActiveFolder(null);setActivePlace(null);setPlacePath([]);setNoProject(false);setActiveSavedView(null)}else{setActiveScope(s);setActiveFolder(null);setActivePlace(null);setPlacePath([]);setNoProject(false);setActiveSavedView(null)}}; const createFolder=parent=>{if(!newFolderName.trim())return;setFolders(p=>[...p,{id:"f"+(p.length+10),title:newFolderName.trim(),parent}]);if(parent){const s=new Set(expandedFolders);s.add(parent);setExpandedFolders(s)}setNewFolderMode(null);setNewFolderName("");flash("Folder created")}; const deleteFolder=id=>{setFolders(p=>p.filter(f=>f.id!==id&&f.parent!==id));setDeletingFolder(null);if(activeFolder===id)setActiveFolder(null);flash("Folder deleted — items unfiled")}; const removePlace=id=>{setPlaces(p=>p.filter(x=>x.id!==id));setRemovingPlace(null);if(activePlace!==null&&places[activePlace]?.id===id){setActivePlace(null);setPlacePath([])}flash("Place removed")}; const filtered=useMemo(()=>{ let items=[...allItems]; if(activeScope==="Project"&&!noProject)items=items.filter(it=>it.proj===projects[activeProjIdx].id); if(activeScope==="Project"&&noProject)items=items.filter(it=>it.proj===null); if(selectedCollections.size>0)items=items.filter(it=>[...selectedCollections].every(col=>it.cols?.includes(col))); if(activeTypes.size>0)items=items.filter(it=>activeTypes.has(it.type)); if(sortKey==="Alphabetical")items.sort((a,b)=>a.title.localeCompare(b.title)); else if(sortKey==="Type")items.sort((a,b)=>a.type.localeCompare(b.type)); else if(sortKey==="Running")items.sort((a,b)=>(b.st==="running"?1:0)-(a.st==="running"?1:0)); else items.sort((a,b)=>timeVal(a.time)-timeVal(b.time)); const pinned=items.filter(x=>x.pin);const unpinned=items.filter(x=>!x.pin); return [...pinned,...unpinned]; },[activeScope,activeProjIdx,noProject,selectedCollections,activeTypes,sortKey]); const currentPlaceFiles=()=>{const key=placePath.length?placePath[placePath.length-1]:"root";return placeContents[key]||[{name:"(empty)",dimmed:true,type:"—",size:"—",mod:"—"}]}; // Folder tree renderer (shared between Folders scope and overlay) const renderFolderTree=(parentId,depth,isOverlay=false)=>folders.filter(f=>f.parent===parentId).map(f=>{ const hasChildren=folders.some(ch=>ch.parent===f.id);const isExp=expandedFolders.has(f.id); const isActive=!isOverlay&&activeFolder===f.id;const isDrop=dropTarget===f.id;const isHover=hoverFolder===f.id; const isDeleting=deletingFolder===f.id; return
{if(isOverlay)return;setActiveFolder(isActive?null:f.id)}} onMouseEnter={()=>setHoverFolder(f.id)} onMouseLeave={()=>setHoverFolder(null)} onDragOver={e=>{e.preventDefault();setDropTarget(f.id)}} onDragLeave={()=>setDropTarget(null)} onDrop={e=>{e.preventDefault();setDropTarget(null);if(dragItem)flash(`Added "${dragItem}" to ${f.title}`)}} style={{display:"flex",alignItems:"center",gap:3,padding:isOverlay?"2px 6px":"3px 8px",paddingLeft:(isOverlay?6:8)+depth*(isOverlay?12:14),borderRadius:R.sm,cursor:isOverlay?"default":"pointer",backgroundColor:isDrop?c.accentBtn+"20":isActive?c.accentBtn+"10":"transparent",fontSize:isOverlay?10.5:11.5,fontWeight:isActive?600:400,color:isActive?c.accentBtn:c.textSec,border:isDrop?`1px dashed ${c.accentBtn}`:"1px solid transparent",transition:"all .1s"}}> {hasChildren?{e.stopPropagation();toggleFolder(f.id)}} style={{display:"flex",width:10}}>{isExp?:}:} {f.title} {isHover&&!isOverlay&&!isDeleting&&<> {e.stopPropagation();setNewFolderMode({parent:f.id});setNewFolderName("");setTimeout(()=>nfRef.current?.focus(),50)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Add subfolder"> {e.stopPropagation();setDeletingFolder(f.id)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Delete folder"> } {isDeleting&&e.stopPropagation()}> Delete? deleteFolder(f.id)}>Yes setDeletingFolder(null)}>No }
{isExp&&hasChildren&&renderFolderTree(f.id,depth+1,isOverlay)} {!isOverlay&&newFolderMode&&newFolderMode.parent===f.id&&
setNewFolderName(e.target.value)} placeholder="Subfolder…" onKeyDown={e=>{if(e.key==="Enter")createFolder(f.id);if(e.key==="Escape"){setNewFolderMode(null);setNewFolderName("")}}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
}
; }); return (
setSortDrop(false)}> {toast&&setToast(null)}/>}
Q
{/* Search */}
{/* Collections */}
{collections.map(col=>{const sel=selectedCollections.has(col.name);return }
{/* Scope chips + folder overlay toggle */}
{scopeFams.map(s=>)}
{/* Scope detail */}
{activeScope===null&&
No scope — showing all items
} {activeScope==="Project"&&
{projects.map((p,i)=>)}
} {activeScope==="Folders"&&
Folders
{newFolderMode&&newFolderMode.parent===null&&
setNewFolderName(e.target.value)} placeholder="Folder name…" onKeyDown={e=>{if(e.key==="Enter")createFolder(null);if(e.key==="Escape"){setNewFolderMode(null);setNewFolderName("")}}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
} {renderFolderTree(null,0,false)}
} {activeScope==="Places"&&
Places
{places.map((p,i)=>
setHoverPlace(p.id)} onMouseLeave={()=>setHoverPlace(null)} style={{display:"flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:R.sm,cursor:"pointer",backgroundColor:activePlace===i?c.accentBtn+"10":"transparent",opacity:p.status==="missing"?.5:1}}>
{setActivePlace(i);setPlacePath([])}} style={{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0}}>
{p.title}
{p.path}
{hoverPlace===p.id&&removingPlace!==p.id&&setRemovingPlace(p.id)} style={{cursor:"pointer",display:"flex",color:c.textTer,flexShrink:0}} title="Remove place">} {removingPlace===p.id&&e.stopPropagation()}> Remove? removePlace(p.id)}>Yes setRemovingPlace(null)}>No } {removingPlace!==p.id&&hoverPlace!==p.id&&{p.status}}
)}
} {activeScope==="Saved Views"&&
Saved Views
{saveViewMode&&
setSaveViewName(e.target.value)} placeholder="View name…" autoFocus onKeyDown={e=>{if(e.key==="Enter"&&saveViewName.trim()){setUserSavedViews(p=>[...p,{id:"usv"+p.length,name:saveViewName.trim()}]);flash(`"${saveViewName}" saved`);setSaveViewMode(false)}if(e.key==="Escape")setSaveViewMode(false)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
} {savedViews.map(sv=>)} {userSavedViews.map(sv=>
setHoverSavedView(sv.id)} onMouseLeave={()=>setHoverSavedView(null)} style={{display:"flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:R.sm,cursor:"pointer",backgroundColor:activeSavedView===sv.id?c.accentBtn+"10":"transparent"}}>setActiveSavedView(activeSavedView===sv.id?null:sv.id)} style={{fontSize:11.5,fontWeight:activeSavedView===sv.id?600:400,color:activeSavedView===sv.id?c.accentBtn:c.textSec,flex:1}}>{sv.name}{hoverSavedView===sv.id&&<>flash("Rename…")} style={{fontSize:9,color:c.textTer,cursor:"pointer"}}>rename{setUserSavedViews(p=>p.filter(v=>v.id!==sv.id));flash("Deleted")}} style={{fontSize:9,color:c.error,cursor:"pointer"}}>delete}
)}
} {activeScope&&!["Project","Folders","Places","Saved Views"].includes(activeScope)&&
{activeScope}…
}
{/* Splitter */}
{const sY=e.clientY,sP=splitterPos;const m=ev=>setSplitterPos(Math.max(60,Math.min(250,sP+(ev.clientY-sY))));const u=()=>{document.removeEventListener("mousemove",m);document.removeEventListener("mouseup",u)};document.addEventListener("mousemove",m);document.addEventListener("mouseup",u)}}>
{/* ═══ FOLDER OVERLAY — persistent across scopes ═══ */} {folderOverlay&&activeScope!=="Folders"&&
Drag items to folders
{renderFolderTree(null,0,true)}
} {/* Type chips */}
{typeChips.map(t=>)} {activeTypes.size>0&&}
{/* Filter/Sort bar + save view */}
{activeScope==="Places"&&activePlace!==null?currentPlaceFiles().length:filtered.length} items
{e.stopPropagation();setSortDrop(!sortDrop)}}>{sortKey} ▾ {sortDrop&&
e.stopPropagation()} style={{position:"absolute",top:16,right:0,backgroundColor:c.bgCard,border:`1px solid ${c.border}`,borderRadius:R.sm,boxShadow:"0 4px 12px rgba(0,0,0,0.1)",zIndex:50,minWidth:120,padding:3}}> {sortOptions.map(s=>)}
}
{saveFromBar&&
setSaveViewName(e.target.value)} placeholder="View name…" autoFocus onKeyDown={e=>{if(e.key==="Enter"&&saveViewName.trim()){setUserSavedViews(p=>[...p,{id:"usv"+p.length,name:saveViewName.trim()}]);flash(`"${saveViewName}" saved`);setSaveFromBar(false)}if(e.key==="Escape")setSaveFromBar(false)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
} {/* Results */}
{activeScope==="Places"&&activePlace!==null?
setPlacePath([])}>← {places[activePlace]?.title} {placePath.map((p,i)=>/setPlacePath(placePath.slice(0,i+1))}>{p})}
{currentPlaceFiles().filter(f=>f.isFolder).map((f,i)=>
setPlacePath([...placePath,f.name])} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 8px",height:34,borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer",backgroundColor:c.bgPanelAlt+"80"}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.accentBtn+"06"} onMouseLeave={e=>e.currentTarget.style.backgroundColor=c.bgPanelAlt+"80"}>{f.name}
)} {currentPlaceFiles().filter(f=>!f.isFolder).map((f,i)=>
{f.name}{f.type}{f.size}{f.mod}
)}
:<>{filtered.map((item,i)=>
setDragItem(item.title)} onDragEnd={()=>setDragItem(null)} onClick={()=>setSelectedIdx(i)} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 8px",height:32,borderBottom:`1px solid ${c.borderLight}`,cursor:folderOverlay?"grab":"pointer",backgroundColor:selectedIdx===i?c.accentBtn+"08":"transparent"}} onMouseEnter={e=>{if(selectedIdx!==i)e.currentTarget.style.backgroundColor=c.bgPanelAlt}} onMouseLeave={e=>{if(selectedIdx!==i)e.currentTarget.style.backgroundColor="transparent"}}> {item.pin&&} {item.unread&&} {item.title} {item.st&&{item.st}} {item.type} {item.time}
)} {filtered.length===0&&
No items match
} }
{/* Browser footer */}
{activeScope?{activeScope}:All} {activeScope==="Project"&&!noProject&&· {projects[activeProjIdx].name}} {activeScope==="Project"&&noProject&&· No Project} {selectedCollections.size>0&&· {[...selectedCollections].join(", ")}} {activeTypes.size>0&&· {[...activeTypes].join(", ")}} {folderOverlay&&· 📁 Folders} {sortKey}
{const sX=e.clientX,sW=browserWidth;const m=ev=>setBrowserWidth(Math.max(200,Math.min(450,sW+(ev.clientX-sX))));const u=()=>{document.removeEventListener("mousemove",m);document.removeEventListener("mouseup",u)};document.addEventListener("mousemove",m);document.addEventListener("mouseup",u)}}/>
Browser R1.3

Folder overlay — click the dashed "📁 Folders" button at the end of the scope chip row. A compact folder tree appears above the type chips. Drag items from the results list onto folders. Works in any scope — Project, search, type filters all stay active while the overlay is visible. Click X to hide.

Remove places — hover a place in Places scope → X icon appears. Click → "Remove? Yes/No" inline confirmation. Files aren't deleted, just the alias is removed.

Delete folders — hover a folder in Folders scope → trash icon appears (next to the + subfolder icon). Click → "Delete? Yes/No" confirmation. Items inside become unfiled. Subfolders are also deleted.

Drag to folder — when folder overlay is active, result items show a grab cursor. Drag onto a folder name — it highlights with a dashed blue border. Drop to assign. Toast confirms.

• All previous features: scope deselection, sort, collections, save view from anywhere, Prompt/Artifact types.

); }