feat: support deleting agent result cards
This commit is contained in:
parent
0a33d99c28
commit
83102c559f
@ -334,6 +334,8 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
const [agentProjectThumbnail, setAgentProjectThumbnail] = useState<string | null>(null);
|
const [agentProjectThumbnail, setAgentProjectThumbnail] = useState<string | null>(null);
|
||||||
const [agentProjectResultCollections, setAgentProjectResultCollections] =
|
const [agentProjectResultCollections, setAgentProjectResultCollections] =
|
||||||
useState<AgentGenerationProjectResultCollections>({});
|
useState<AgentGenerationProjectResultCollections>({});
|
||||||
|
const [agentProjectDeletedResultCollections, setAgentProjectDeletedResultCollections] =
|
||||||
|
useState<AgentGenerationProjectResultCollections>({});
|
||||||
const [isAgentProjectLoading, setIsAgentProjectLoading] = useState(false);
|
const [isAgentProjectLoading, setIsAgentProjectLoading] = useState(false);
|
||||||
const [isAgentProjectSaving, setIsAgentProjectSaving] = useState(false);
|
const [isAgentProjectSaving, setIsAgentProjectSaving] = useState(false);
|
||||||
const [isAgentProjectSheetOpen, setIsAgentProjectSheetOpen] = useState(false);
|
const [isAgentProjectSheetOpen, setIsAgentProjectSheetOpen] = useState(false);
|
||||||
@ -509,6 +511,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
setAgentProjectTitle("未命名生图项目");
|
setAgentProjectTitle("未命名生图项目");
|
||||||
setAgentProjectThumbnail(null);
|
setAgentProjectThumbnail(null);
|
||||||
setAgentProjectResultCollections({});
|
setAgentProjectResultCollections({});
|
||||||
|
setAgentProjectDeletedResultCollections({});
|
||||||
|
|
||||||
// 🆕 先清空当前画布状态,确保切换时不会显示旧数据
|
// 🆕 先清空当前画布状态,确保切换时不会显示旧数据
|
||||||
useCanvasStore.getState().clearCanvas();
|
useCanvasStore.getState().clearCanvas();
|
||||||
@ -658,6 +661,17 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
agentProjectResultCollections.sku_replacement
|
agentProjectResultCollections.sku_replacement
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
deletedResultCollections: {
|
||||||
|
scene_generation: normalizeResultCollectionUrls(
|
||||||
|
agentProjectDeletedResultCollections.scene_generation
|
||||||
|
),
|
||||||
|
detail_replacement: normalizeResultCollectionUrls(
|
||||||
|
agentProjectDeletedResultCollections.detail_replacement
|
||||||
|
),
|
||||||
|
sku_replacement: normalizeResultCollectionUrls(
|
||||||
|
agentProjectDeletedResultCollections.sku_replacement
|
||||||
|
),
|
||||||
|
},
|
||||||
resultImageUrls: Array.from(
|
resultImageUrls: Array.from(
|
||||||
new Set([
|
new Set([
|
||||||
...normalizeResultCollectionUrls(agentProjectResultCollections.scene_generation),
|
...normalizeResultCollectionUrls(agentProjectResultCollections.scene_generation),
|
||||||
@ -668,6 +682,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
agentModeState,
|
agentModeState,
|
||||||
|
agentProjectDeletedResultCollections,
|
||||||
agentProjectResultCollections,
|
agentProjectResultCollections,
|
||||||
agentWorkspaceState,
|
agentWorkspaceState,
|
||||||
currentAgentStage,
|
currentAgentStage,
|
||||||
@ -885,6 +900,9 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
setAgentProjectTitle(result.data.title || "未命名生图项目");
|
setAgentProjectTitle(result.data.title || "未命名生图项目");
|
||||||
setAgentProjectThumbnail(result.data.thumbnail || null);
|
setAgentProjectThumbnail(result.data.thumbnail || null);
|
||||||
setAgentProjectResultCollections(persistedState.resultCollections || {});
|
setAgentProjectResultCollections(persistedState.resultCollections || {});
|
||||||
|
setAgentProjectDeletedResultCollections(
|
||||||
|
persistedState.deletedResultCollections || {}
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
toast.error(error instanceof Error ? error.message : "加载生图项目失败");
|
toast.error(error instanceof Error ? error.message : "加载生图项目失败");
|
||||||
@ -1117,6 +1135,48 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
[agentProjectResultCollections]
|
[agentProjectResultCollections]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleAgentResultImageDelete = useCallback(
|
||||||
|
(modeType: AgentGenerationResultModeType, imageUrl: string) => {
|
||||||
|
const normalizedUrl = String(imageUrl || "").trim();
|
||||||
|
if (!/^https?:\/\//i.test(normalizedUrl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextCollections: AgentGenerationProjectResultCollections = {
|
||||||
|
...agentProjectResultCollections,
|
||||||
|
[modeType]: normalizeResultCollectionUrls(
|
||||||
|
(agentProjectResultCollections[modeType] || []).filter(
|
||||||
|
(url) => url !== normalizedUrl
|
||||||
|
)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
const nextDeletedCollections: AgentGenerationProjectResultCollections = {
|
||||||
|
...agentProjectDeletedResultCollections,
|
||||||
|
[modeType]: normalizeResultCollectionUrls([
|
||||||
|
...(agentProjectDeletedResultCollections[modeType] || []),
|
||||||
|
normalizedUrl,
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
|
||||||
|
setAgentProjectResultCollections((current) =>
|
||||||
|
areResultCollectionsEqual(current, nextCollections) ? current : nextCollections
|
||||||
|
);
|
||||||
|
setAgentProjectDeletedResultCollections((current) =>
|
||||||
|
areResultCollectionsEqual(current, nextDeletedCollections)
|
||||||
|
? current
|
||||||
|
: nextDeletedCollections
|
||||||
|
);
|
||||||
|
setAgentProjectThumbnail((current) => {
|
||||||
|
const nextThumbnail =
|
||||||
|
current === normalizedUrl
|
||||||
|
? getFirstResultUrlFromCollections(nextCollections)
|
||||||
|
: current;
|
||||||
|
return current === nextThumbnail ? current : nextThumbnail;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[agentProjectDeletedResultCollections, agentProjectResultCollections]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const normalizedBrand = workflowInputs.brand.trim().toLowerCase();
|
const normalizedBrand = workflowInputs.brand.trim().toLowerCase();
|
||||||
if (!normalizedBrand) {
|
if (!normalizedBrand) {
|
||||||
@ -1795,8 +1855,10 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
onAgentModeStateChange={setAgentModeState}
|
onAgentModeStateChange={setAgentModeState}
|
||||||
workspaceState={agentWorkspaceState}
|
workspaceState={agentWorkspaceState}
|
||||||
resultCollections={agentProjectResultCollections}
|
resultCollections={agentProjectResultCollections}
|
||||||
|
deletedResultCollections={agentProjectDeletedResultCollections}
|
||||||
onWorkspaceStateChange={setAgentWorkspaceState}
|
onWorkspaceStateChange={setAgentWorkspaceState}
|
||||||
onResultPreviewUrlsChange={handleAgentResultPreviewUrlsChange}
|
onResultPreviewUrlsChange={handleAgentResultPreviewUrlsChange}
|
||||||
|
onDeleteResultImage={handleAgentResultImageDelete}
|
||||||
siteName={siteSettingsData?.siteName}
|
siteName={siteSettingsData?.siteName}
|
||||||
siteLogo={siteSettingsData?.siteLogo}
|
siteLogo={siteSettingsData?.siteLogo}
|
||||||
siteLogoDark={siteSettingsData?.siteLogoDark}
|
siteLogoDark={siteSettingsData?.siteLogoDark}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import {
|
|||||||
Sparkles,
|
Sparkles,
|
||||||
Upload,
|
Upload,
|
||||||
UserRound,
|
UserRound,
|
||||||
|
Trash2,
|
||||||
X,
|
X,
|
||||||
Wand2,
|
Wand2,
|
||||||
Settings2,
|
Settings2,
|
||||||
@ -93,10 +94,15 @@ interface AgentGenerationWorkspaceDarkV2Props {
|
|||||||
workspaceState?: AgentGenerationProjectWorkspaceState | null;
|
workspaceState?: AgentGenerationProjectWorkspaceState | null;
|
||||||
onWorkspaceStateChange?: (next: AgentGenerationProjectWorkspaceState) => void;
|
onWorkspaceStateChange?: (next: AgentGenerationProjectWorkspaceState) => void;
|
||||||
resultCollections?: AgentGenerationProjectResultCollections | null;
|
resultCollections?: AgentGenerationProjectResultCollections | null;
|
||||||
|
deletedResultCollections?: AgentGenerationProjectResultCollections | null;
|
||||||
onResultPreviewUrlsChange?: (
|
onResultPreviewUrlsChange?: (
|
||||||
modeType: AgentGenerationResultModeType,
|
modeType: AgentGenerationResultModeType,
|
||||||
urls: string[]
|
urls: string[]
|
||||||
) => void;
|
) => void;
|
||||||
|
onDeleteResultImage?: (
|
||||||
|
modeType: AgentGenerationResultModeType,
|
||||||
|
imageUrl: string
|
||||||
|
) => void;
|
||||||
topNavRightSlot?: ReactNode;
|
topNavRightSlot?: ReactNode;
|
||||||
showcaseConfig?: AgentWorkflowShowcaseConfig | null;
|
showcaseConfig?: AgentWorkflowShowcaseConfig | null;
|
||||||
workflowStylePanel?: ReactNode;
|
workflowStylePanel?: ReactNode;
|
||||||
@ -145,6 +151,14 @@ function normalizeResultCollectionUrls(urls?: string[] | null) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function excludeDeletedResultUrls(
|
||||||
|
urls: string[] | undefined | null,
|
||||||
|
deletedUrls: string[] | undefined | null
|
||||||
|
) {
|
||||||
|
const deletedUrlSet = new Set(normalizeResultCollectionUrls(deletedUrls));
|
||||||
|
return normalizeResultCollectionUrls(urls).filter((url) => !deletedUrlSet.has(url));
|
||||||
|
}
|
||||||
|
|
||||||
function getResultModeLabel(modeType: AgentGenerationResultModeType) {
|
function getResultModeLabel(modeType: AgentGenerationResultModeType) {
|
||||||
return modeType === "detail_replacement"
|
return modeType === "detail_replacement"
|
||||||
? "详情替换"
|
? "详情替换"
|
||||||
@ -677,8 +691,10 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
onOpenCanvasEditor,
|
onOpenCanvasEditor,
|
||||||
workspaceState = null,
|
workspaceState = null,
|
||||||
resultCollections = null,
|
resultCollections = null,
|
||||||
|
deletedResultCollections = null,
|
||||||
onWorkspaceStateChange,
|
onWorkspaceStateChange,
|
||||||
onResultPreviewUrlsChange,
|
onResultPreviewUrlsChange,
|
||||||
|
onDeleteResultImage,
|
||||||
topNavRightSlot,
|
topNavRightSlot,
|
||||||
showcaseConfig,
|
showcaseConfig,
|
||||||
workflowStylePanel,
|
workflowStylePanel,
|
||||||
@ -759,6 +775,20 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
});
|
});
|
||||||
const [pendingGeneration, setPendingGeneration] =
|
const [pendingGeneration, setPendingGeneration] =
|
||||||
useState<LocalGenerationPendingState | null>(null);
|
useState<LocalGenerationPendingState | null>(null);
|
||||||
|
const normalizedDeletedResultCollections = useMemo(
|
||||||
|
() => ({
|
||||||
|
scene_generation: normalizeResultCollectionUrls(
|
||||||
|
deletedResultCollections?.scene_generation
|
||||||
|
),
|
||||||
|
detail_replacement: normalizeResultCollectionUrls(
|
||||||
|
deletedResultCollections?.detail_replacement
|
||||||
|
),
|
||||||
|
sku_replacement: normalizeResultCollectionUrls(
|
||||||
|
deletedResultCollections?.sku_replacement
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
[deletedResultCollections]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const restored = getStoredAgentPendingGenerations().find(
|
const restored = getStoredAgentPendingGenerations().find(
|
||||||
@ -1310,8 +1340,20 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
}, [assistantMessagesAfterLastUser, generatedGroups]);
|
}, [assistantMessagesAfterLastUser, generatedGroups]);
|
||||||
|
|
||||||
const allGeneratedImages = useMemo(
|
const allGeneratedImages = useMemo(
|
||||||
() => Array.from(new Set(generatedGroups.flatMap((group) => group.imageUrls))),
|
() =>
|
||||||
[generatedGroups]
|
Array.from(
|
||||||
|
new Set(
|
||||||
|
generatedGroups
|
||||||
|
.flatMap((group) => group.imageUrls)
|
||||||
|
.filter(
|
||||||
|
(url) =>
|
||||||
|
!normalizedDeletedResultCollections.scene_generation.includes(url) &&
|
||||||
|
!normalizedDeletedResultCollections.detail_replacement.includes(url) &&
|
||||||
|
!normalizedDeletedResultCollections.sku_replacement.includes(url)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
[generatedGroups, normalizedDeletedResultCollections]
|
||||||
);
|
);
|
||||||
const currentSceneGeneratedUrls = useMemo(
|
const currentSceneGeneratedUrls = useMemo(
|
||||||
() => Array.from(new Set(generatedGroupsAfterLastUser.flatMap((group) => group.imageUrls))),
|
() => Array.from(new Set(generatedGroupsAfterLastUser.flatMap((group) => group.imageUrls))),
|
||||||
@ -1357,8 +1399,11 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
() =>
|
() =>
|
||||||
latestReplacementResults
|
latestReplacementResults
|
||||||
.map((item) => item.url)
|
.map((item) => item.url)
|
||||||
.filter((url): url is string => Boolean(url)),
|
.filter((url): url is string => Boolean(url))
|
||||||
[latestReplacementResults]
|
.filter(
|
||||||
|
(url) => !normalizedDeletedResultCollections[currentResultModeType].includes(url)
|
||||||
|
),
|
||||||
|
[currentResultModeType, latestReplacementResults, normalizedDeletedResultCollections]
|
||||||
);
|
);
|
||||||
const currentLiveResultUrls = isReplacementPreset
|
const currentLiveResultUrls = isReplacementPreset
|
||||||
? latestReplacementResultUrls
|
? latestReplacementResultUrls
|
||||||
@ -1400,9 +1445,18 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
const mergedResultCollections = useMemo(
|
const mergedResultCollections = useMemo(
|
||||||
() => {
|
() => {
|
||||||
const baseCollections = {
|
const baseCollections = {
|
||||||
scene_generation: normalizeResultCollectionUrls(resultCollections?.scene_generation),
|
scene_generation: excludeDeletedResultUrls(
|
||||||
detail_replacement: normalizeResultCollectionUrls(resultCollections?.detail_replacement),
|
resultCollections?.scene_generation,
|
||||||
sku_replacement: normalizeResultCollectionUrls(resultCollections?.sku_replacement),
|
normalizedDeletedResultCollections.scene_generation
|
||||||
|
),
|
||||||
|
detail_replacement: excludeDeletedResultUrls(
|
||||||
|
resultCollections?.detail_replacement,
|
||||||
|
normalizedDeletedResultCollections.detail_replacement
|
||||||
|
),
|
||||||
|
sku_replacement: excludeDeletedResultUrls(
|
||||||
|
resultCollections?.sku_replacement,
|
||||||
|
normalizedDeletedResultCollections.sku_replacement
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1410,12 +1464,20 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
[currentResultModeType]: Array.from(
|
[currentResultModeType]: Array.from(
|
||||||
new Set([
|
new Set([
|
||||||
...baseCollections[currentResultModeType],
|
...baseCollections[currentResultModeType],
|
||||||
...normalizeResultCollectionUrls(currentLiveResultUrls),
|
...excludeDeletedResultUrls(
|
||||||
|
currentLiveResultUrls,
|
||||||
|
normalizedDeletedResultCollections[currentResultModeType]
|
||||||
|
),
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
} as Record<AgentGenerationResultModeType, string[]>;
|
} as Record<AgentGenerationResultModeType, string[]>;
|
||||||
},
|
},
|
||||||
[currentLiveResultUrls, currentResultModeType, resultCollections]
|
[
|
||||||
|
currentLiveResultUrls,
|
||||||
|
currentResultModeType,
|
||||||
|
normalizedDeletedResultCollections,
|
||||||
|
resultCollections,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
const availableResultModeTypes = useMemo(
|
const availableResultModeTypes = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -1434,43 +1496,61 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
() =>
|
() =>
|
||||||
detailReplacementReferenceCards.map((card, index) => {
|
detailReplacementReferenceCards.map((card, index) => {
|
||||||
const resultMeta = latestReplacementResults[index];
|
const resultMeta = latestReplacementResults[index];
|
||||||
const resultUrl = resultMeta?.url || null;
|
const resultUrl =
|
||||||
|
resultMeta?.url &&
|
||||||
|
!normalizedDeletedResultCollections.detail_replacement.includes(resultMeta.url)
|
||||||
|
? resultMeta.url
|
||||||
|
: null;
|
||||||
return {
|
return {
|
||||||
...card,
|
...card,
|
||||||
index,
|
index,
|
||||||
resultUrl,
|
resultUrl,
|
||||||
resultText: resultMeta?.text || "",
|
resultText: resultUrl ? resultMeta?.text || "" : "",
|
||||||
status: getReplacementCardStatus({
|
status: getReplacementCardStatus({
|
||||||
index,
|
index,
|
||||||
resultUrl,
|
resultUrl,
|
||||||
resultText: resultMeta?.text || "",
|
resultText: resultUrl ? resultMeta?.text || "" : "",
|
||||||
generatedCount: latestReplacementResults.length,
|
generatedCount: latestReplacementResults.length,
|
||||||
isGenerating: isDetailResultModeGenerating,
|
isGenerating: isDetailResultModeGenerating,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
[detailReplacementReferenceCards, isDetailResultModeGenerating, latestReplacementResults]
|
[
|
||||||
|
detailReplacementReferenceCards,
|
||||||
|
isDetailResultModeGenerating,
|
||||||
|
latestReplacementResults,
|
||||||
|
normalizedDeletedResultCollections.detail_replacement,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
const skuResultCards = useMemo(
|
const skuResultCards = useMemo(
|
||||||
() =>
|
() =>
|
||||||
skuReplacementReferenceCards.map((card, index) => {
|
skuReplacementReferenceCards.map((card, index) => {
|
||||||
const resultMeta = latestReplacementResults[index];
|
const resultMeta = latestReplacementResults[index];
|
||||||
const resultUrl = resultMeta?.url || null;
|
const resultUrl =
|
||||||
|
resultMeta?.url &&
|
||||||
|
!normalizedDeletedResultCollections.sku_replacement.includes(resultMeta.url)
|
||||||
|
? resultMeta.url
|
||||||
|
: null;
|
||||||
return {
|
return {
|
||||||
...card,
|
...card,
|
||||||
index,
|
index,
|
||||||
resultUrl,
|
resultUrl,
|
||||||
resultText: resultMeta?.text || "",
|
resultText: resultUrl ? resultMeta?.text || "" : "",
|
||||||
status: getReplacementCardStatus({
|
status: getReplacementCardStatus({
|
||||||
index,
|
index,
|
||||||
resultUrl,
|
resultUrl,
|
||||||
resultText: resultMeta?.text || "",
|
resultText: resultUrl ? resultMeta?.text || "" : "",
|
||||||
generatedCount: latestReplacementResults.length,
|
generatedCount: latestReplacementResults.length,
|
||||||
isGenerating: isSkuResultModeGenerating,
|
isGenerating: isSkuResultModeGenerating,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
[isSkuResultModeGenerating, latestReplacementResults, skuReplacementReferenceCards]
|
[
|
||||||
|
isSkuResultModeGenerating,
|
||||||
|
latestReplacementResults,
|
||||||
|
normalizedDeletedResultCollections.sku_replacement,
|
||||||
|
skuReplacementReferenceCards,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
const detailProcessedCount = useMemo(
|
const detailProcessedCount = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -1719,10 +1799,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasProgress =
|
const hasProgress = latestReplacementResults.length > 0;
|
||||||
pendingGeneration.modeType === "scene_generation"
|
|
||||||
? currentSceneGeneratedUrls.length > 0
|
|
||||||
: latestReplacementResults.length > 0;
|
|
||||||
|
|
||||||
if (!hasProgress) {
|
if (!hasProgress) {
|
||||||
setPendingGeneration(null);
|
setPendingGeneration(null);
|
||||||
@ -2090,6 +2167,25 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
toast.message("已打开原图,可右键另存为");
|
toast.message("已打开原图,可右键另存为");
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
const handleDeleteResultImage = useCallback(
|
||||||
|
(modeType: AgentGenerationResultModeType, imageUrl: string) => {
|
||||||
|
const normalizedUrl = String(imageUrl || "").trim();
|
||||||
|
if (!normalizedUrl || !onDeleteResultImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedResultUrl === normalizedUrl) {
|
||||||
|
setSelectedResultUrl(null);
|
||||||
|
}
|
||||||
|
if (fullscreenPreview === normalizedUrl) {
|
||||||
|
setFullscreenPreview(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteResultImage(modeType, normalizedUrl);
|
||||||
|
toast.success("结果图已删除");
|
||||||
|
},
|
||||||
|
[fullscreenPreview, onDeleteResultImage, selectedResultUrl]
|
||||||
|
);
|
||||||
|
|
||||||
const handleToolStepChange = useCallback(
|
const handleToolStepChange = useCallback(
|
||||||
(nextKey: ToolStepKey) => {
|
(nextKey: ToolStepKey) => {
|
||||||
@ -3370,6 +3466,16 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
当前联动
|
当前联动
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
handleDeleteResultImage("detail_replacement", card.resultUrl!)
|
||||||
|
}
|
||||||
|
className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full border border-rose-400/25 bg-black/60 text-rose-100 transition-colors hover:border-rose-300/45 hover:bg-rose-500/15"
|
||||||
|
aria-label="删除结果图"
|
||||||
|
>
|
||||||
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -3815,6 +3921,16 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
<div className={cn("absolute left-3 top-3 rounded-full border px-2.5 py-1 text-[11px]", statusMeta.className)}>
|
<div className={cn("absolute left-3 top-3 rounded-full border px-2.5 py-1 text-[11px]", statusMeta.className)}>
|
||||||
{statusMeta.label}
|
{statusMeta.label}
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
handleDeleteResultImage("sku_replacement", card.resultUrl!)
|
||||||
|
}
|
||||||
|
className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full border border-rose-400/25 bg-black/60 text-rose-100 transition-colors hover:border-rose-300/45 hover:bg-rose-500/15"
|
||||||
|
aria-label="删除结果图"
|
||||||
|
>
|
||||||
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -3926,12 +4042,25 @@ export function AgentGenerationWorkspaceDarkV2({
|
|||||||
>
|
>
|
||||||
<div className="relative aspect-[4/5] overflow-hidden bg-[linear-gradient(180deg,#090b0c_0%,#111417_100%)]">
|
<div className="relative aspect-[4/5] overflow-hidden bg-[linear-gradient(180deg,#090b0c_0%,#111417_100%)]">
|
||||||
{card.url ? (
|
{card.url ? (
|
||||||
<img
|
<>
|
||||||
src={card.url}
|
<img
|
||||||
alt={`${getResultModeLabel(activeResultModeType)} 结果图 ${card.index + 1}`}
|
src={card.url}
|
||||||
className="h-full w-full object-contain p-2"
|
alt={`${getResultModeLabel(activeResultModeType)} 结果图 ${card.index + 1}`}
|
||||||
loading="lazy"
|
className="h-full w-full object-contain p-2"
|
||||||
/>
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
handleDeleteResultImage(activeResultModeType, card.url!);
|
||||||
|
}}
|
||||||
|
className="absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full border border-rose-400/25 bg-black/60 text-rose-100 transition-colors hover:border-rose-300/45 hover:bg-rose-500/15"
|
||||||
|
aria-label="删除结果图"
|
||||||
|
>
|
||||||
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<AnimatedGenerationPlaceholderCard
|
<AnimatedGenerationPlaceholderCard
|
||||||
badge={card.status === "generating" ? "生成中" : card.status === "queued" ? "排队中" : "待生成"}
|
badge={card.status === "generating" ? "生成中" : card.status === "queued" ? "排队中" : "待生成"}
|
||||||
|
|||||||
@ -51,6 +51,7 @@ export function createEmptyAgentGenerationProjectPersistedState(): AgentGenerati
|
|||||||
workspaceState: createEmptyAgentGenerationProjectWorkspaceState(),
|
workspaceState: createEmptyAgentGenerationProjectWorkspaceState(),
|
||||||
resultImageUrls: [],
|
resultImageUrls: [],
|
||||||
resultCollections: {},
|
resultCollections: {},
|
||||||
|
deletedResultCollections: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,11 +275,13 @@ export function normalizeAgentGenerationProjectPersistedState(
|
|||||||
resultImageUrls,
|
resultImageUrls,
|
||||||
resultCollections: normalizeResultCollections(raw.resultCollections),
|
resultCollections: normalizeResultCollections(raw.resultCollections),
|
||||||
});
|
});
|
||||||
|
const deletedResultCollections = normalizeResultCollections(raw.deletedResultCollections);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
workflowState,
|
workflowState,
|
||||||
workspaceState: normalizeWorkspaceState(raw.workspaceState),
|
workspaceState: normalizeWorkspaceState(raw.workspaceState),
|
||||||
resultImageUrls,
|
resultImageUrls,
|
||||||
resultCollections,
|
resultCollections,
|
||||||
|
deletedResultCollections,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -349,6 +349,7 @@ export interface AgentGenerationProjectPersistedState {
|
|||||||
workspaceState?: AgentGenerationProjectWorkspaceState;
|
workspaceState?: AgentGenerationProjectWorkspaceState;
|
||||||
resultImageUrls?: string[];
|
resultImageUrls?: string[];
|
||||||
resultCollections?: AgentGenerationProjectResultCollections;
|
resultCollections?: AgentGenerationProjectResultCollections;
|
||||||
|
deletedResultCollections?: AgentGenerationProjectResultCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentGenerationProject {
|
export interface AgentGenerationProject {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user