Skip to content

Commit 35d8b15

Browse files
committed
feat(rpa): add browser close option for formal runs
1 parent 01d1cc3 commit 35d8b15

5 files changed

Lines changed: 41 additions & 9 deletions

File tree

plugins/pages/rpa-workflow/src/api/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ export interface RpaTaskInputVariable {
6666
required: boolean;
6767
}
6868

69+
export interface RpaTaskRunOptions {
70+
closeBrowserOnComplete: boolean;
71+
}
72+
6973
export interface PaginatedRpaTaskList {
7074
items: RpaTask[];
7175
total: number;
@@ -140,6 +144,7 @@ interface StoredWorkflowMetaVariable {
140144
interface StoredWorkflowMeta {
141145
start_step_id?: string | null;
142146
global_variables?: StoredWorkflowMetaVariable[];
147+
close_browser_on_complete?: boolean;
143148
}
144149

145150
function normalizeStatus(status: string): RpaTask['status'] {
@@ -351,6 +356,14 @@ export function extractTaskInputVariables(detail: RpaTaskDetailDto): RpaTaskInpu
351356
.filter((variable) => variable.name && variable.promptOnRun);
352357
}
353358

359+
export function extractTaskRunOptions(detail: RpaTaskDetailDto): RpaTaskRunOptions {
360+
const workflowMeta = extractStoredWorkflowMeta(detail);
361+
362+
return {
363+
closeBrowserOnComplete: workflowMeta?.close_browser_on_complete === true,
364+
};
365+
}
366+
354367
export function extractWorkflowSchema(detail: RpaTaskDetailDto): RpaWorkflowSchema | null {
355368
const tags = toStringArray(detail.task.tags);
356369
const orderedSteps = [...detail.steps].sort(

plugins/pages/rpa-workflow/src/components/task-editor/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ function createDefaultTaskConfig(): TaskConfig {
7474
timeout: 300,
7575
concurrency: 1,
7676
stopOnError: true,
77+
closeBrowserOnComplete: false,
7778
notifyOnComplete: false,
7879
notifyOnError: false,
7980
};

plugins/pages/rpa-workflow/src/components/task-editor/task-settings-form.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export interface TaskConfig {
4545
timeout: number;
4646
concurrency: number;
4747
stopOnError: boolean;
48+
closeBrowserOnComplete: boolean;
4849
notifyOnComplete: boolean;
4950
notifyOnError: boolean;
5051
}
@@ -215,6 +216,7 @@ export function TaskSettingsForm({ config, onConfigChange }: TaskSettingsFormPro
215216
`超时 ${config.timeout}s`,
216217
`重试 ${config.retryCount} 次`,
217218
config.stopOnError ? '出错即停止' : '允许继续执行',
219+
config.closeBrowserOnComplete ? '结束后关闭浏览器' : '结束后保留浏览器',
218220
].join(' · ');
219221

220222
return (
@@ -474,6 +476,12 @@ export function TaskSettingsForm({ config, onConfigChange }: TaskSettingsFormPro
474476
checked={config.stopOnError}
475477
onCheckedChange={(value) => handleChange('stopOnError', value)}
476478
/>
479+
<StrategySwitch
480+
label="结束后关闭浏览器"
481+
description="仅影响正式执行。启用后,任务执行完成会自动关闭本次启动的浏览器。"
482+
checked={config.closeBrowserOnComplete}
483+
onCheckedChange={(value) => handleChange('closeBrowserOnComplete', value)}
484+
/>
477485
<StrategySwitch
478486
label="完成时通知"
479487
description="任务完成后发送通知。"

plugins/pages/rpa-workflow/src/components/task-editor/workflow-mapper.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ interface StoredWorkflowMeta {
4444
prompt_on_run?: boolean;
4545
required?: boolean;
4646
}>;
47+
close_browser_on_complete?: boolean;
4748
start_position?: {
4849
x?: number;
4950
y?: number;
@@ -450,6 +451,7 @@ export function buildTaskPayload(
450451
required: variable.promptOnRun === true && variable.required === true,
451452
}))
452453
.filter((variable) => variable.name),
454+
close_browser_on_complete: config.closeBrowserOnComplete === true,
453455
start_position: specialPositions.start,
454456
end_position: specialPositions.end,
455457
},
@@ -514,13 +516,14 @@ export function mapTaskDetailToEditorState(detail: RpaTaskDetailDto): EditorStat
514516
runMode: detail.task.run_mode === 'parallel' ? 'parallel' : 'sequential',
515517
globalVariables: storedGlobalVariables,
516518
retryCount: detail.task.retry_count ?? 3,
517-
retryInterval: detail.task.retry_interval ?? 5,
518-
timeout: detail.task.timeout ?? 300,
519-
concurrency: detail.task.concurrency ?? 1,
520-
stopOnError: detail.task.stop_on_error ?? true,
521-
notifyOnComplete: detail.task.notify_on_complete ?? false,
522-
notifyOnError: detail.task.notify_on_error ?? true,
523-
};
519+
retryInterval: detail.task.retry_interval ?? 5,
520+
timeout: detail.task.timeout ?? 300,
521+
concurrency: detail.task.concurrency ?? 1,
522+
stopOnError: detail.task.stop_on_error ?? true,
523+
closeBrowserOnComplete: storedWorkflowMeta?.close_browser_on_complete === true,
524+
notifyOnComplete: detail.task.notify_on_complete ?? false,
525+
notifyOnError: detail.task.notify_on_error ?? true,
526+
};
524527

525528
return {
526529
config,
@@ -610,6 +613,7 @@ export function mapPortableTaskToEditorState(document: PortableRpaTaskDocument):
610613
timeout: document.task.timeout ?? 300,
611614
concurrency: document.task.concurrency ?? 1,
612615
stopOnError: document.task.stop_on_error ?? true,
616+
closeBrowserOnComplete: storedWorkflowMeta?.close_browser_on_complete === true,
613617
notifyOnComplete: document.task.notify_on_complete ?? false,
614618
notifyOnError: document.task.notify_on_error ?? true,
615619
};

plugins/pages/rpa-workflow/src/hooks/use-rpa-execution.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { useCallback, useMemo, useRef, useState } from 'react';
22
import { toast } from 'sonner';
3-
import { extractWorkflowSchema, getRpaTaskDetail, type RpaTaskDetailDto } from '../api';
3+
import {
4+
extractTaskRunOptions,
5+
extractWorkflowSchema,
6+
getRpaTaskDetail,
7+
type RpaTaskDetailDto,
8+
} from '../api';
49
import type { RpaTask, RpaWorkflowStep } from '../types';
510
import { RpaRunner } from '../runtime/runner';
611
import { CdpBrowserAdapter } from '../runtime/cdp-browser-adapter';
@@ -230,6 +235,7 @@ export function useRpaExecution(params: UseRpaExecutionParams): UseRpaExecutionR
230235
toast.error('任务流程数据无效');
231236
return;
232237
}
238+
const runOptions = extractTaskRunOptions(pendingExecution.detail);
233239

234240
if (!pendingExecution.detail.environment_uuids?.length) {
235241
toast.error('请先绑定环境后再执行');
@@ -368,7 +374,7 @@ export function useRpaExecution(params: UseRpaExecutionParams): UseRpaExecutionR
368374
break;
369375
}
370376
} finally {
371-
if (startedByRuntime) {
377+
if (startedByRuntime && runOptions.closeBrowserOnComplete) {
372378
await stopEnvironmentRuntime(envUuid).catch(() => undefined);
373379
}
374380
}

0 commit comments

Comments
 (0)