mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
112 lines
4.3 KiB
TypeScript
112 lines
4.3 KiB
TypeScript
import { PlusSquare, Upload } from "lucide-react";
|
|
import { Button } from "../../../shared/components";
|
|
import { resolveAutomationScriptPublicAPIConfig, type AutomationScriptRecord } from "../automationScripts";
|
|
import { AutomationScriptSummaryCard } from "./AutomationScriptSummaryCard";
|
|
import type { AutomationCardPresentation } from "./AutomationPage.helpers";
|
|
|
|
interface AutomationCardsSectionProps {
|
|
loading: boolean;
|
|
cards: AutomationCardPresentation[];
|
|
scripts: AutomationScriptRecord[];
|
|
selectedScriptIds: string[];
|
|
onCreate: () => void;
|
|
onImport: () => void;
|
|
onToggleScriptSelection: (scriptId: string, selected: boolean) => void;
|
|
onOpenScript: (scriptId: string) => void;
|
|
onRunAutomationScript: (script: AutomationScriptRecord) => void;
|
|
onOpenPublicApi: (script: AutomationScriptRecord, options?: { focusTest?: boolean }) => void;
|
|
}
|
|
|
|
export function AutomationCardsSection({
|
|
loading,
|
|
cards,
|
|
scripts,
|
|
selectedScriptIds,
|
|
onCreate,
|
|
onImport,
|
|
onToggleScriptSelection,
|
|
onOpenScript,
|
|
onRunAutomationScript,
|
|
onOpenPublicApi,
|
|
}: AutomationCardsSectionProps) {
|
|
const scriptMap = new Map(scripts.map((script) => [script.id, script]));
|
|
const selectedScriptIdSet = new Set(selectedScriptIds);
|
|
|
|
return (
|
|
<section className="rounded-[28px] border border-[var(--color-border-default)] bg-[var(--color-bg-subtle)] p-3 shadow-[var(--shadow-sm)] md:p-4">
|
|
{loading ? (
|
|
<div className="rounded-2xl border border-dashed border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-6 py-12 text-center text-sm text-[var(--color-text-muted)]">
|
|
正在加载脚本列表...
|
|
</div>
|
|
) : cards.length === 0 ? (
|
|
<div className="rounded-2xl border border-dashed border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-6 py-14 text-center">
|
|
<div className="text-base font-medium text-[var(--color-text-primary)]">
|
|
还没有脚本
|
|
</div>
|
|
<div className="mt-2 text-sm text-[var(--color-text-muted)]">
|
|
先新建一套脚本,或者导入已有脚本。
|
|
</div>
|
|
<div className="mt-5 flex justify-center gap-2">
|
|
<Button size="sm" onClick={() => onCreate()}>
|
|
<PlusSquare className="h-4 w-4" />
|
|
新建
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="secondary"
|
|
onClick={() => onImport()}
|
|
>
|
|
<Upload className="h-4 w-4" />
|
|
导入
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div
|
|
className="grid items-stretch gap-3"
|
|
style={{
|
|
gridTemplateColumns:
|
|
"repeat(auto-fit, minmax(min(100%, max(458px, calc((100% - 24px) / 3))), 1fr))",
|
|
}}
|
|
>
|
|
{cards.map((card) => {
|
|
const scriptId = card.scriptId;
|
|
const onOpen = scriptId ? () => onOpenScript(scriptId) : undefined;
|
|
const script = scriptId ? scriptMap.get(scriptId) : undefined;
|
|
const publicAPIEnabled = script
|
|
? resolveAutomationScriptPublicAPIConfig(script).enabled
|
|
: false;
|
|
const runScriptAction = script && script.type !== "launch-api"
|
|
? () => onRunAutomationScript(script)
|
|
: undefined;
|
|
const onRunAPI = script
|
|
? () =>
|
|
onOpenPublicApi(script, {
|
|
focusTest: publicAPIEnabled,
|
|
})
|
|
: undefined;
|
|
|
|
return (
|
|
<div key={card.key} className="min-w-0">
|
|
<AutomationScriptSummaryCard
|
|
card={card}
|
|
onOpen={onOpen}
|
|
onRunScript={runScriptAction}
|
|
onRunAPI={onRunAPI}
|
|
selected={scriptId ? selectedScriptIdSet.has(scriptId) : false}
|
|
onSelectedChange={
|
|
scriptId
|
|
? (selected) => onToggleScriptSelection(scriptId, selected)
|
|
: undefined
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</section>
|
|
);
|
|
|
|
}
|