debugger: show animated button and pulse code editor when we think co… (#3618)

This commit is contained in:
Jonathan Dobson
2025-10-06 10:00:35 -04:00
committed by GitHub
parent e729681f17
commit a9d0280336
2 changed files with 104 additions and 72 deletions

View File

@@ -40,6 +40,7 @@ type Props = {
cacheKeyValue: string | null; cacheKeyValue: string | null;
cacheKeyValues: CacheKeyValuesResponse | undefined; cacheKeyValues: CacheKeyValuesResponse | undefined;
cacheKeyValuesPanelOpen: boolean; cacheKeyValuesPanelOpen: boolean;
isGeneratingCode?: boolean;
parametersPanelOpen: boolean; parametersPanelOpen: boolean;
saving: boolean; saving: boolean;
showAllCode: boolean; showAllCode: boolean;
@@ -59,6 +60,7 @@ function WorkflowHeader({
cacheKeyValue, cacheKeyValue,
cacheKeyValues, cacheKeyValues,
cacheKeyValuesPanelOpen, cacheKeyValuesPanelOpen,
isGeneratingCode,
parametersPanelOpen, parametersPanelOpen,
saving, saving,
showAllCode, showAllCode,
@@ -132,76 +134,88 @@ function WorkflowHeader({
/> />
</div> </div>
<div className="flex h-full items-center justify-end gap-4"> <div className="flex h-full items-center justify-end gap-4">
{user && (cacheKeyValues?.total_count ?? 0) > 0 && ( {user &&
<> !isGeneratingCode &&
{debugStore.isDebugMode && ( (cacheKeyValues?.total_count ?? 0) > 0 && (
<Button <>
className="pl-2 pr-3" {debugStore.isDebugMode && (
size="lg" <Button
variant={!showAllCode ? "tertiary" : "default"} className="pl-2 pr-3"
onClick={handleShowAllCode} size="lg"
variant={!showAllCode ? "tertiary" : "default"}
onClick={handleShowAllCode}
>
<CodeIcon className="mr-2 h-6 w-6" />
Show Code
</Button>
)}
<div
tabIndex={1}
className="flex max-w-[10rem] items-center justify-center gap-1 rounded-md border border-input pr-1 focus-within:ring-1 focus-within:ring-ring"
> >
<CodeIcon className="mr-2 h-6 w-6" /> <Input
Show Code ref={dom.input}
</Button> className="focus-visible:transparent focus-visible:none h-[2.75rem] text-ellipsis whitespace-nowrap border-none focus-visible:outline-none focus-visible:ring-0"
)} onChange={(e) => {
<div setChosenCacheKeyValue(e.target.value);
tabIndex={1} onCacheKeyValuesFilter(e.target.value);
className="flex max-w-[10rem] items-center justify-center gap-1 rounded-md border border-input pr-1 focus-within:ring-1 focus-within:ring-ring" }}
> onMouseDown={() => {
<Input if (!cacheKeyValuesPanelOpen) {
ref={dom.input} onCacheKeyValuesClick();
className="focus-visible:transparent focus-visible:none h-[2.75rem] text-ellipsis whitespace-nowrap border-none focus-visible:outline-none focus-visible:ring-0"
onChange={(e) => {
setChosenCacheKeyValue(e.target.value);
onCacheKeyValuesFilter(e.target.value);
}}
onMouseDown={() => {
if (!cacheKeyValuesPanelOpen) {
onCacheKeyValuesClick();
}
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
const numFiltered = cacheKeyValues?.values?.length ?? 0;
if (numFiltered === 1) {
const first = cacheKeyValues?.values?.[0];
if (first) {
setChosenCacheKeyValue(first);
onCacheKeyValueAccept(first);
}
return;
} }
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
const numFiltered = cacheKeyValues?.values?.length ?? 0;
setChosenCacheKeyValue(chosenCacheKeyValue); if (numFiltered === 1) {
onCacheKeyValueAccept(chosenCacheKeyValue); const first = cacheKeyValues?.values?.[0];
} if (first) {
onCacheKeyValuesKeydown(e); setChosenCacheKeyValue(first);
}} onCacheKeyValueAccept(first);
placeholder="Code Key Value" }
value={chosenCacheKeyValue ?? undefined} return;
onBlur={(e) => { }
onCacheKeyValuesBlurred(e.target.value);
setChosenCacheKeyValue(e.target.value); setChosenCacheKeyValue(chosenCacheKeyValue);
}} onCacheKeyValueAccept(chosenCacheKeyValue);
/> }
{cacheKeyValuesPanelOpen ? ( onCacheKeyValuesKeydown(e);
<ChevronUpIcon }}
className="h-6 w-6 cursor-pointer" placeholder="Code Key Value"
onClick={onCacheKeyValuesClick} value={chosenCacheKeyValue ?? undefined}
/> onBlur={(e) => {
) : ( onCacheKeyValuesBlurred(e.target.value);
<ChevronDownIcon setChosenCacheKeyValue(e.target.value);
className="h-6 w-6 cursor-pointer"
onClick={() => {
dom.input.current?.focus();
onCacheKeyValuesClick();
}} }}
/> />
)} {cacheKeyValuesPanelOpen ? (
</div> <ChevronUpIcon
</> className="h-6 w-6 cursor-pointer"
onClick={onCacheKeyValuesClick}
/>
) : (
<ChevronDownIcon
className="h-6 w-6 cursor-pointer"
onClick={() => {
dom.input.current?.focus();
onCacheKeyValuesClick();
}}
/>
)}
</div>
</>
)}
{isGeneratingCode && (
<Button
className="size-10 min-w-[6rem]"
variant={!showAllCode ? "tertiary" : "default"}
onClick={handleShowAllCode}
>
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
Code
</Button>
)} )}
{isGlobalWorkflow ? ( {isGlobalWorkflow ? (
<Button <Button

View File

@@ -157,7 +157,7 @@ function Workspace({
const saveWorkflow = useWorkflowSave(); const saveWorkflow = useWorkflowSave();
const { data: workflowRun } = useWorkflowRunQuery(); const { data: workflowRun } = useWorkflowRunQuery();
const isFinalized = workflowRun ? statusIsFinalized(workflowRun) : null; const isFinalized = workflowRun ? statusIsFinalized(workflowRun) : false;
const interactor = workflowRun && isFinalized === false ? "agent" : "human"; const interactor = workflowRun && isFinalized === false ? "agent" : "human";
const [openCycleBrowserDialogue, setOpenCycleBrowserDialogue] = const [openCycleBrowserDialogue, setOpenCycleBrowserDialogue] =
@@ -231,13 +231,27 @@ function Workspace({
} }
}, [cacheKeyValue, searchParams, setSearchParams]); }, [cacheKeyValue, searchParams, setSearchParams]);
const { data: blockScripts } = useBlockScriptsQuery({ const { data: blockScriptsPublished } = useBlockScriptsQuery({
cacheKey, cacheKey,
cacheKeyValue, cacheKeyValue,
workflowPermanentId, workflowPermanentId,
status: "published", status: "published",
}); });
const publishedLabelCount = Object.keys(blockScriptsPublished ?? {}).length;
const isGeneratingCode =
publishedLabelCount === 0 && !isFinalized && Boolean(workflowRun);
const { data: blockScriptsPending } = useBlockScriptsQuery({
cacheKey,
cacheKeyValue,
workflowPermanentId,
pollIntervalMs: isGeneratingCode ? 3000 : undefined,
status: "pending",
workflowRunId: workflowRun?.workflow_run_id,
});
const { data: cacheKeyValues, isLoading: cacheKeyValuesLoading } = const { data: cacheKeyValues, isLoading: cacheKeyValuesLoading } =
useCacheKeyValuesQuery({ useCacheKeyValuesQuery({
cacheKey, cacheKey,
@@ -375,9 +389,9 @@ function Workspace({
}, []); }, []);
useEffect(() => { useEffect(() => {
blockScriptStore.setScripts(blockScripts ?? {}); blockScriptStore.setScripts(blockScriptsPublished ?? {});
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [blockScripts]); }, [blockScriptsPublished]);
const afterCycleBrowser = () => { const afterCycleBrowser = () => {
setOpenCycleBrowserDialogue(false); setOpenCycleBrowserDialogue(false);
@@ -657,7 +671,8 @@ function Workspace({
} }
const orderedBlockLabels = getOrderedBlockLabels(workflow); const orderedBlockLabels = getOrderedBlockLabels(workflow);
const code = getCode(orderedBlockLabels, blockScripts).join(""); const code = getCode(orderedBlockLabels, blockScriptsPublished).join("");
const codePending = getCode(orderedBlockLabels, blockScriptsPending).join("");
const handleCompareVersions = ( const handleCompareVersions = (
version1: WorkflowVersion, version1: WorkflowVersion,
@@ -852,6 +867,7 @@ function Workspace({
<WorkflowHeader <WorkflowHeader
cacheKeyValue={cacheKeyValue} cacheKeyValue={cacheKeyValue}
cacheKeyValues={cacheKeyValues} cacheKeyValues={cacheKeyValues}
isGeneratingCode={isGeneratingCode}
saving={workflowChangesStore.saveIsPending} saving={workflowChangesStore.saveIsPending}
cacheKeyValuesPanelOpen={ cacheKeyValuesPanelOpen={
workflowPanelState.active && workflowPanelState.active &&
@@ -1158,9 +1174,11 @@ function Workspace({
<CopyText text={code} /> <CopyText text={code} />
</div> </div>
<CodeEditor <CodeEditor
className="w-full overflow-y-scroll" className={cn("w-full overflow-y-scroll", {
"animate-pulse": isGeneratingCode,
})}
language="python" language="python"
value={code} value={isGeneratingCode ? codePending : code}
lineWrap={false} lineWrap={false}
readOnly readOnly
fontSize={10} fontSize={10}