KPrashanth commited on
Commit
578769d
·
verified ·
1 Parent(s): 20b0fd6

Deploy Rachana Data Studio

Browse files
Files changed (1) hide show
  1. frontend/app/page.tsx +6 -5
frontend/app/page.tsx CHANGED
@@ -130,7 +130,7 @@ export default function Home() {
130
  const [message, setMessage] = useState("");
131
  const [authChecked, setAuthChecked] = useState(false);
132
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
133
- const canAccessAdmin = user ? user.role === "admin" || user.permissions.some((p) => ["import", "export", "manage_sources", "manage_users"].includes(p)) : false;
134
 
135
  const refreshOverview = useCallback(async (authToken: string) => {
136
  const data = await api<{ queues: QueueCounts; sources: Source[]; user: User; token_progress: TokenProgress; collaboration: Collaboration }>("/api/overview", authToken);
@@ -288,15 +288,16 @@ type EditorState = { cleaned: Record<string, unknown>; tags: string; notes: stri
288
  type ReviewLine = { id: string; left: string; right: string };
289
 
290
  function ReviewWorkspace({ queue, queues, sources, sample, busy, collaboration, onQueue, onClaim, onSubmit }: { queue: string; queues: QueueCounts; sources: Source[]; sample: Sample | null; busy: boolean; collaboration: Collaboration | null; onQueue: (q: string) => void; onClaim: (datasetKey?: string) => void; onSubmit: (action: string, editor: EditorState) => void }) {
291
- const [datasetKey, setDatasetKey] = useState(sources[0]?.dataset_key || "");
292
  useEffect(() => {
293
- if (sources.length && !sources.some((source) => source.dataset_key === datasetKey)) {
294
- setDatasetKey(sources[0].dataset_key);
295
  }
296
  }, [datasetKey, sources]);
297
  const selectedSource = sources.find((source) => source.dataset_key === datasetKey);
298
  const selectedQueue = selectedSource?.queue_name || queue;
299
- return <><header className="pageHeader"><div><span className="eyebrow">Review workspace</span><h1>Make one clear decision at a time.</h1><p>Each reviewer gets a random available sample. Token progress stays global across the whole team.</p></div><div className="headerStats">{collaboration && <div className="metricInline"><span>Total cleaned</span><strong>{collaboration.total_cleaned_samples.toLocaleString()}</strong></div>}{sample?.lease && <div className="lease">Reserved until {new Date(sample.lease.expires_at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</div>}</div></header><section className="tableCard connectedCard"><div className="connectedHeader"><div><h2>Connected datasets</h2><p>Pick a dataset, then claim from its queue. This keeps review focused without hiding other sources.</p></div><label>Active dataset<select value={datasetKey} onChange={(e) => { const next = e.target.value; setDatasetKey(next); const nextSource = sources.find((source) => source.dataset_key === next); if (nextSource) onQueue(nextSource.queue_name); }}>{sources.length ? null : <option value="">No connected datasets</option>}<option value="">Select a dataset</option>{sources.map((source) => <option key={source.dataset_key} value={source.dataset_key}>{source.name}</option>)}</select></label></div><div className="connectedList">{sources.map((source) => <button key={source.dataset_key} type="button" className={`connectedChip${source.dataset_key === datasetKey ? " active" : ""}`} onClick={() => { setDatasetKey(source.dataset_key); onQueue(source.queue_name); }}><strong>{source.name}</strong><small>{source.dataset_key}</small></button>)}</div></section><div className="queueTabs">{QUEUES.map((item) => <button key={item.id} className={queue === item.id ? "active" : ""} onClick={() => onQueue(item.id)}><strong>{item.label}</strong><span>{queues[item.id]?.pending || 0} pending</span></button>)}</div>{sample ? <ReviewEditor key={sample.sample_id} sample={sample} busy={busy} onSubmit={onSubmit} /> : <div className="emptyState"><div>✓</div><h2>Ready for the next item?</h2><p>{selectedSource ? `${selectedSource.name} is mapped to ${selectedQueue}.` : QUEUES.find((q) => q.id === queue)?.description}</p><button className="primary" onClick={() => onClaim(datasetKey || undefined)} disabled={busy}>{busy ? "Finding an item..." : "Claim random sample"}</button></div>}</>;
 
300
  }
301
 
302
  function ReviewEditor({ sample, busy, onSubmit }: { sample: Sample; busy: boolean; onSubmit: (action: string, editor: EditorState) => void }) {
 
130
  const [message, setMessage] = useState("");
131
  const [authChecked, setAuthChecked] = useState(false);
132
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
133
+ const canAccessAdmin = user ? ["admin", "owner"].includes(user.role) || user.permissions.some((p) => ["import", "export", "manage_sources", "manage_users"].includes(p)) : false;
134
 
135
  const refreshOverview = useCallback(async (authToken: string) => {
136
  const data = await api<{ queues: QueueCounts; sources: Source[]; user: User; token_progress: TokenProgress; collaboration: Collaboration }>("/api/overview", authToken);
 
288
  type ReviewLine = { id: string; left: string; right: string };
289
 
290
  function ReviewWorkspace({ queue, queues, sources, sample, busy, collaboration, onQueue, onClaim, onSubmit }: { queue: string; queues: QueueCounts; sources: Source[]; sample: Sample | null; busy: boolean; collaboration: Collaboration | null; onQueue: (q: string) => void; onClaim: (datasetKey?: string) => void; onSubmit: (action: string, editor: EditorState) => void }) {
291
+ const [datasetKey, setDatasetKey] = useState("");
292
  useEffect(() => {
293
+ if (datasetKey && !sources.some((source) => source.dataset_key === datasetKey)) {
294
+ setDatasetKey("");
295
  }
296
  }, [datasetKey, sources]);
297
  const selectedSource = sources.find((source) => source.dataset_key === datasetKey);
298
  const selectedQueue = selectedSource?.queue_name || queue;
299
+ const claimLabel = selectedSource ? `Claim from ${selectedSource.name}` : "Claim from all active datasets";
300
+ return <><header className="pageHeader"><div><span className="eyebrow">Review workspace</span><h1>Make one clear decision at a time.</h1><p>Each reviewer gets a random available sample. Token progress stays global across the whole team.</p></div><div className="headerStats">{collaboration && <div className="metricInline"><span>Total cleaned</span><strong>{collaboration.total_cleaned_samples.toLocaleString()}</strong></div>}{sample?.lease && <div className="lease">Reserved until {new Date(sample.lease.expires_at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</div>}</div></header><section className="tableCard connectedCard"><div className="connectedHeader"><div><h2>Connected datasets</h2><p>Leave the selector empty to pool across every active dataset in this queue.</p></div><label>Active dataset<select value={datasetKey} onChange={(e) => { const next = e.target.value; setDatasetKey(next); const nextSource = sources.find((source) => source.dataset_key === next); if (nextSource) onQueue(nextSource.queue_name); }}><option value="">All active datasets</option>{sources.map((source) => <option key={source.dataset_key} value={source.dataset_key}>{source.name}</option>)}</select></label></div><div className="connectedList">{sources.map((source) => <button key={source.dataset_key} type="button" className={`connectedChip${source.dataset_key === datasetKey ? " active" : ""}`} onClick={() => { setDatasetKey(source.dataset_key); onQueue(source.queue_name); }}><strong>{source.name}</strong><small>{source.dataset_key}</small></button>)}</div></section><div className="queueTabs">{QUEUES.map((item) => <button key={item.id} className={queue === item.id ? "active" : ""} onClick={() => onQueue(item.id)}><strong>{item.label}</strong><span>{queues[item.id]?.pending || 0} pending</span></button>)}</div>{sample ? <ReviewEditor key={sample.sample_id} sample={sample} busy={busy} onSubmit={onSubmit} /> : <div className="emptyState"><div>✓</div><h2>Ready for the next item?</h2><p>{selectedSource ? `${selectedSource.name} is mapped to ${selectedQueue}.` : QUEUES.find((q) => q.id === queue)?.description}</p><button className="primary" onClick={() => onClaim(datasetKey || undefined)} disabled={busy}>{busy ? "Finding an item..." : claimLabel}</button></div>}</>;
301
  }
302
 
303
  function ReviewEditor({ sample, busy, onSubmit }: { sample: Sample; busy: boolean; onSubmit: (action: string, editor: EditorState) => void }) {