Frontend checkbox fixes
This commit is contained in:
@@ -140,6 +140,11 @@ export function InboxPanel({ onBatchStarted }) {
|
||||
|
||||
const submissions = data?.submissions || [];
|
||||
const pending = data?.pending_count ?? 0;
|
||||
// Nothing ticked means "Start selected" cannot fire, which makes the two
|
||||
// stage toggles below inert. On a deployment running UPLOAD_AUTORUN=true that
|
||||
// is the permanent state - this inbox never fills - so they stay greyed, which
|
||||
// is exactly the point: they must not read as settings that govern uploads.
|
||||
const stagesIdle = !selected.size;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -150,10 +155,12 @@ export function InboxPanel({ onBatchStarted }) {
|
||||
<Inbox className="h-5 w-5 text-amber-500" /> Review Inbox
|
||||
</h2>
|
||||
<p className="text-xs text-slate-500 leading-relaxed max-w-3xl">
|
||||
Spreadsheets sent in by a colleague through the upload API. Nothing here has run
|
||||
yet — tick the files you want and press <strong>Start selected</strong> to
|
||||
send them through the 11-stage pipeline as one batch. Files from different drops
|
||||
can go in the same batch.
|
||||
Where spreadsheets wait <strong>when <code className="font-mono">UPLOAD_AUTORUN</code>
|
||||
{' '}is off</strong>. Nothing here has run yet — tick the files you want and
|
||||
press <strong>Start selected</strong> to send them through the 11-stage pipeline as
|
||||
one batch. Files from different drops can go in the same batch. With autorun on,
|
||||
uploads start on arrival and this stays empty; watch them under{' '}
|
||||
<strong>Dagster Orchestration</strong> instead.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -197,34 +204,66 @@ export function InboxPanel({ onBatchStarted }) {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Same defaults and the same warning as the batch tab. */}
|
||||
<div className="mt-4 flex flex-col gap-2">
|
||||
<label className="flex items-start gap-2 text-[11px] text-slate-600 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={fetchImages}
|
||||
onChange={(e) => setFetchImages(e.target.checked)}
|
||||
className="mt-0.5 accent-amber-500 cursor-pointer"
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Search for product images</span>
|
||||
{' '}— much slower, and makes outbound requests for every row.
|
||||
</span>
|
||||
</label>
|
||||
<label className="flex items-start gap-2 text-[11px] text-slate-600 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useLlm}
|
||||
onChange={(e) => setUseLlm(e.target.checked)}
|
||||
className="mt-0.5 accent-amber-500 cursor-pointer"
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Use the LLM for missing descriptions</span>
|
||||
{' '}— fills blank descriptions where an Ollama server is reachable. It is not
|
||||
in production, so rows there simply keep the description the sheet gave them.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{/* THESE TWO GOVERN THE MANUAL START ABOVE, AND NOTHING ELSE.
|
||||
An upload that ran itself never passed through here: POST
|
||||
/api/uploads/catalog reads UPLOAD_AUTORUN_FETCH_IMAGES and
|
||||
UPLOAD_AUTORUN_USE_LLM on the server and ignores whatever the
|
||||
request asked for. What a given run actually used is on its own row
|
||||
under Dagster Orchestration -> Recent runs. */}
|
||||
<fieldset
|
||||
disabled={stagesIdle}
|
||||
className={`mt-4 rounded-xl border border-ink-900/10 bg-white p-3 transition ${
|
||||
stagesIdle ? 'opacity-40' : ''
|
||||
}`}
|
||||
>
|
||||
<legend className="px-1 text-[10px] font-bold uppercase tracking-wide text-slate-400">
|
||||
Applies to Start selected
|
||||
{stagesIdle && (
|
||||
<span className="font-normal normal-case"> — tick a file below first</span>
|
||||
)}
|
||||
</legend>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label
|
||||
className={`flex items-start gap-2 text-[11px] text-slate-600 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={fetchImages}
|
||||
disabled={stagesIdle}
|
||||
onChange={(e) => setFetchImages(e.target.checked)}
|
||||
className={`mt-0.5 accent-amber-500 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Search for product images</span>
|
||||
{' '}— much slower, and makes outbound requests for every row.
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
className={`flex items-start gap-2 text-[11px] text-slate-600 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useLlm}
|
||||
disabled={stagesIdle}
|
||||
onChange={(e) => setUseLlm(e.target.checked)}
|
||||
className={`mt-0.5 accent-amber-500 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Use the LLM for missing descriptions</span>
|
||||
{' '}— fills blank descriptions where an Ollama server is reachable. It is not
|
||||
in production, so rows there simply keep the description the sheet gave them.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{notice && (
|
||||
<div className="mt-4 rounded-lg bg-emerald-500/5 border border-emerald-500/20 p-3 text-xs text-emerald-700 flex items-start gap-2">
|
||||
@@ -243,8 +282,13 @@ export function InboxPanel({ onBatchStarted }) {
|
||||
<div className="rounded-2xl border border-ink-900/10 bg-paper-50 p-10 text-center">
|
||||
<Inbox className="h-8 w-8 text-slate-300 mx-auto mb-3" />
|
||||
<p className="text-xs text-slate-500">
|
||||
Nothing waiting. Files sent to <code className="font-mono">/api/uploads/catalog</code>{' '}
|
||||
appear here for review.
|
||||
Nothing waiting — files sent to{' '}
|
||||
<code className="font-mono">/api/uploads/catalog</code> start on their own and appear
|
||||
under <strong>Dagster Orchestration → Recent runs</strong>.
|
||||
</p>
|
||||
<p className="text-[11px] text-slate-400 mt-2">
|
||||
Set <code className="font-mono">UPLOAD_AUTORUN=false</code> to hold them here for a
|
||||
decision instead.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -48,6 +48,16 @@ const FILE_TONE = {
|
||||
cancelled: 'bg-ink-100 text-slate-500 border-ink-900/10',
|
||||
};
|
||||
|
||||
// The two optional network stages, rendered per run under Recent runs. A run
|
||||
// that started on its own took these from the SERVER settings
|
||||
// (UPLOAD_AUTORUN_FETCH_IMAGES / UPLOAD_AUTORUN_USE_LLM), never from the
|
||||
// checkboxes on this page, so reading them back off the manifest is the only
|
||||
// honest report of what a colleague's upload actually did.
|
||||
const STAGE_FLAGS = [
|
||||
{ key: 'fetch_images', label: 'img', title: 'Product image search' },
|
||||
{ key: 'use_llm', label: 'llm', title: 'LLM description fill' },
|
||||
];
|
||||
|
||||
const FILE_ICON = {
|
||||
done: CheckCircle2,
|
||||
failed: XCircle,
|
||||
@@ -226,6 +236,11 @@ export function OrchestrationPanel() {
|
||||
// orchestrator is not running, or its sensor has not ticked yet.
|
||||
const awaitingOrchestrator =
|
||||
batch && batch.runner === 'dagster' && batch.status === 'queued';
|
||||
// Nothing ticked means "Start selected" cannot fire, which makes the two
|
||||
// stage toggles below inert. On a deployment running UPLOAD_AUTORUN=true that
|
||||
// is the permanent state - the inbox never fills - so they stay greyed, which
|
||||
// is exactly the point: they must not read as settings that govern uploads.
|
||||
const stagesIdle = !selected.size;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -274,34 +289,66 @@ export function OrchestrationPanel() {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Same defaults and the same warnings as the other ingestion tabs. */}
|
||||
<div className="mt-4 flex flex-col gap-2">
|
||||
<label className="flex items-start gap-2 text-[11px] text-slate-600 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={fetchImages}
|
||||
onChange={(e) => setFetchImages(e.target.checked)}
|
||||
className="mt-0.5 accent-amber-500 cursor-pointer"
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Search for product images</span>
|
||||
{' '}— much slower, and makes outbound requests for every row.
|
||||
</span>
|
||||
</label>
|
||||
<label className="flex items-start gap-2 text-[11px] text-slate-600 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useLlm}
|
||||
onChange={(e) => setUseLlm(e.target.checked)}
|
||||
className="mt-0.5 accent-amber-500 cursor-pointer"
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Use the LLM for missing descriptions</span>
|
||||
{' '}— fills blank descriptions where an Ollama server is reachable. It is not
|
||||
in production, so rows there simply keep the description the sheet gave them.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{/* THESE TWO GOVERN THE MANUAL START BELOW, AND NOTHING ELSE.
|
||||
An upload that ran itself never passed through here: POST
|
||||
/api/uploads/catalog reads UPLOAD_AUTORUN_FETCH_IMAGES and
|
||||
UPLOAD_AUTORUN_USE_LLM on the server and ignores whatever the
|
||||
request asked for. What a given run actually used is on its own row
|
||||
under Recent runs. */}
|
||||
<fieldset
|
||||
disabled={stagesIdle}
|
||||
className={`mt-4 rounded-xl border border-ink-900/10 bg-white p-3 transition ${
|
||||
stagesIdle ? 'opacity-40' : ''
|
||||
}`}
|
||||
>
|
||||
<legend className="px-1 text-[10px] font-bold uppercase tracking-wide text-slate-400">
|
||||
Applies to Start selected
|
||||
{stagesIdle && (
|
||||
<span className="font-normal normal-case"> — tick a file below first</span>
|
||||
)}
|
||||
</legend>
|
||||
<div className="flex flex-col gap-2">
|
||||
<label
|
||||
className={`flex items-start gap-2 text-[11px] text-slate-600 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={fetchImages}
|
||||
disabled={stagesIdle}
|
||||
onChange={(e) => setFetchImages(e.target.checked)}
|
||||
className={`mt-0.5 accent-amber-500 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Search for product images</span>
|
||||
{' '}— much slower, and makes outbound requests for every row.
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
className={`flex items-start gap-2 text-[11px] text-slate-600 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useLlm}
|
||||
disabled={stagesIdle}
|
||||
onChange={(e) => setUseLlm(e.target.checked)}
|
||||
className={`mt-0.5 accent-amber-500 ${
|
||||
stagesIdle ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
}`}
|
||||
/>
|
||||
<span>
|
||||
<span className="font-bold text-ink-950">Use the LLM for missing descriptions</span>
|
||||
{' '}— fills blank descriptions where an Ollama server is reachable. It is not
|
||||
in production, so rows there simply keep the description the sheet gave them.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{notice && (
|
||||
<div className="mt-4 rounded-lg bg-emerald-500/5 border border-emerald-500/20 p-3 text-xs text-emerald-700 flex items-start gap-2">
|
||||
@@ -350,6 +397,23 @@ export function OrchestrationPanel() {
|
||||
{run.files_total} file(s)
|
||||
{run.submitted_by ? ` from ${run.submitted_by}` : ''}
|
||||
</span>
|
||||
{/* Read off the manifest, not assumed from .env, so it stays
|
||||
true if a setting is changed without a redeploy. */}
|
||||
<span className="shrink-0 hidden sm:flex items-center gap-1">
|
||||
{STAGE_FLAGS.map(({ key, label, title }) => (
|
||||
<span
|
||||
key={key}
|
||||
title={`${title}: ${run[key] ? 'ran' : 'skipped'}`}
|
||||
className={`px-1.5 py-0.5 rounded border font-mono text-[10px] font-bold ${
|
||||
run[key]
|
||||
? 'border-amber-500/20 bg-amber-500/10 text-amber-700'
|
||||
: 'border-ink-900/10 bg-paper-100 text-slate-400 line-through'
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
<span
|
||||
className={`shrink-0 px-2 py-0.5 rounded-md border text-[10px] font-bold ${
|
||||
FILE_TONE[run.status] || FILE_TONE.queued
|
||||
|
||||
Reference in New Issue
Block a user