jobs: after creating a job, show a View/Close confirmation instead of navigating away
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+36
-2
@@ -740,9 +740,10 @@ type ScriptRunnerProps = {
|
||||
entryType?: 'file' | 'directory';
|
||||
filePath?: string;
|
||||
selectedNames?: string[];
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePath, selectedNames }: ScriptRunnerProps) => {
|
||||
const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePath, selectedNames, onClose }: ScriptRunnerProps) => {
|
||||
const runner = useTaskRunner();
|
||||
const client = useClient();
|
||||
const navigate = useNavigate();
|
||||
@@ -751,6 +752,8 @@ const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePa
|
||||
const [inline, setInline] = useState(false);
|
||||
// Is a job already running? (drives the Run vs Queue affordance).
|
||||
const [jobRunning, setJobRunning] = useState(false);
|
||||
// After a job is created, show a confirmation (View / Close) rather than navigating away.
|
||||
const [created, setCreated] = useState<{ jobId: string; action: 'start' | 'queue' } | null>(null);
|
||||
const bottomRef = useRef<HTMLDivElement | null>(null);
|
||||
const [inputDefs, setInputDefs] = useState<Record<string, TaskInputDef> | null>(null);
|
||||
const [formValues, setFormValues] = useState<Record<string, string>>({});
|
||||
@@ -938,12 +941,42 @@ const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePa
|
||||
const submitJob = async (action: 'start' | 'queue') => {
|
||||
try {
|
||||
const { jobId } = await client.post<{ jobId: string }>('/jobs', { taskDirName, inputs: buildAllInputs(), cwd, action });
|
||||
navigate(action === 'queue' ? '/jobs' : `/jobs/${jobId}`);
|
||||
setCreated({ jobId, action });
|
||||
} catch {
|
||||
/* stays on the modal so the user can retry */
|
||||
}
|
||||
};
|
||||
|
||||
if (created) {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 p-8 text-center">
|
||||
<CircleCheck className="h-10 w-10 text-duck-teal" />
|
||||
<div>
|
||||
<div className="text-base font-medium text-duck-dark dark:text-foreground">
|
||||
{created.action === 'queue' ? 'Job queued' : 'Job started'}
|
||||
</div>
|
||||
<div className="text-sm text-duck-dark/50 dark:text-foreground/50 mt-1">
|
||||
{created.action === 'queue' ? 'It will run when the current job finishes.' : "It’s running in the background."}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => { onClose(); navigate(created.action === 'queue' ? '/jobs' : `/jobs/${created.jobId}`); }}
|
||||
className="flex items-center gap-2 px-5 py-2 rounded-lg bg-duck-teal text-white text-sm font-medium hover:bg-duck-teal/90 cursor-pointer"
|
||||
>
|
||||
<ExternalLink className="h-4 w-4" /> {created.action === 'queue' ? 'View queue' : 'View job'}
|
||||
</button>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="px-5 py-2 rounded-lg text-sm font-medium text-duck-dark/70 dark:text-foreground/70 hover:bg-duck-dark/5 dark:hover:bg-foreground/5 cursor-pointer"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (runner.phase === 'ready') {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col">
|
||||
@@ -1475,6 +1508,7 @@ export const TaskRunnerModal = ({ open, onOpenChange, task, entryName, entryFull
|
||||
entryType={effectiveEntryType}
|
||||
filePath={multi ? cwd.path || undefined : entryName ? (cwd.path ? `${cwd.path}/${entryName}` : entryName) : undefined}
|
||||
selectedNames={multi ? selectedNames : undefined}
|
||||
onClose={() => onOpenChange(false)}
|
||||
/>
|
||||
) : (
|
||||
<PiMonoInner
|
||||
|
||||
Reference in New Issue
Block a user