fix: allow workflow saves without previews
This commit is contained in:
parent
61da591a5c
commit
2226ab34c7
@ -3875,22 +3875,6 @@ export function AgentWorkflowSettingsClient({
|
||||
return;
|
||||
}
|
||||
|
||||
if (changedEntries.some(({ field }) => field === "agentWorkflowUiConfig")) {
|
||||
const missingPreviewOptions = getAgentWorkflowMissingPreviewOptions(
|
||||
config.steps || [],
|
||||
{ enabledOnly: true }
|
||||
);
|
||||
if (missingPreviewOptions.length > 0) {
|
||||
const firstItems = missingPreviewOptions
|
||||
.slice(0, 3)
|
||||
.map((item) => `${item.stepPath} / ${item.path}`)
|
||||
.join(";");
|
||||
throw new Error(
|
||||
`当前有 ${missingPreviewOptions.length} 个已启用卡片缺少自己的预览图,请先补图或关闭对应卡片后再保存。${firstItems}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const conflictedFields = changedEntries
|
||||
.filter(({ field }) => latestServerSignatures[field] !== baseSignatures[field])
|
||||
.map(({ field }) => AGENT_WORKFLOW_SETTINGS_FIELD_LABELS[field]);
|
||||
@ -3968,6 +3952,11 @@ export function AgentWorkflowSettingsClient({
|
||||
);
|
||||
return;
|
||||
}
|
||||
const savedMissingPreviewOptions = savedWorkflowConfigWasChanged
|
||||
? getAgentWorkflowMissingPreviewOptions(savedWorkflowConfig.steps || [], {
|
||||
enabledOnly: true,
|
||||
})
|
||||
: [];
|
||||
|
||||
const updatedServerState = createAgentWorkflowSettingsStateFromPayload(
|
||||
updatedSettings || latestSettings
|
||||
@ -3985,6 +3974,11 @@ export function AgentWorkflowSettingsClient({
|
||||
.map(({ field }) => AGENT_WORKFLOW_SETTINGS_FIELD_LABELS[field])
|
||||
.join("、")}`
|
||||
);
|
||||
if (savedMissingPreviewOptions.length > 0) {
|
||||
toast.warning(
|
||||
`仍有 ${savedMissingPreviewOptions.length} 个启用卡片缺少预览图,前台会自动隐藏这些无图卡片。`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof DOMException && error.name === "AbortError") {
|
||||
toast.error("保存请求超时,请检查网络或稍后重试");
|
||||
|
||||
@ -35,7 +35,6 @@ import {
|
||||
AGENT_WORKFLOW_UI_CONFIG_KEY,
|
||||
AGENT_WORKFLOW_PROMPT_FRAGMENT_MAX_LENGTH,
|
||||
defaultAgentWorkflowUiConfig,
|
||||
getAgentWorkflowMissingPreviewOptions,
|
||||
normalizeAgentWorkflowStepOrdering,
|
||||
normalizeAgentWorkflowUiConfig,
|
||||
} from "@/lib/agents/workflow-ui-config";
|
||||
@ -177,29 +176,6 @@ const defaultRealtimeCanvasModeIconConfig: RealtimeCanvasModeIconConfig = {
|
||||
enhanceLabel: DEFAULT_ENHANCE_CANVAS_MODE_LABEL,
|
||||
};
|
||||
|
||||
function createAgentWorkflowMissingPreviewResponse(
|
||||
steps: ReturnType<typeof normalizeAgentWorkflowUiConfig>["steps"]
|
||||
) {
|
||||
const missingPreviewOptions = getAgentWorkflowMissingPreviewOptions(steps || [], {
|
||||
enabledOnly: true,
|
||||
});
|
||||
|
||||
if (missingPreviewOptions.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: `当前有 ${missingPreviewOptions.length} 个已启用卡片缺少自己的预览图,请先补图或关闭对应卡片后再保存。`,
|
||||
details: missingPreviewOptions.slice(0, 30).map((item) => ({
|
||||
path: ["agentWorkflowUiConfig", item.stepPath, item.path],
|
||||
message: `缺少预览图:${item.stepPath} / ${item.path}`,
|
||||
})),
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
async function readCanvasFeatureAvailability(valueByKey: Map<string, unknown>) {
|
||||
const [enabledTripoProviders, enabledWorldlabsProviders] = await Promise.all([
|
||||
db
|
||||
@ -2403,12 +2379,6 @@ export async function PUT(request: NextRequest) {
|
||||
|
||||
if (agentWorkflowUiConfig !== undefined) {
|
||||
const normalized = normalizeAgentWorkflowUiConfig(agentWorkflowUiConfig);
|
||||
const missingPreviewResponse = createAgentWorkflowMissingPreviewResponse(
|
||||
normalized.steps
|
||||
);
|
||||
if (missingPreviewResponse) {
|
||||
return missingPreviewResponse;
|
||||
}
|
||||
await persistSystemSettingWithHistory(
|
||||
AGENT_WORKFLOW_UI_CONFIG_KEY,
|
||||
normalized,
|
||||
@ -3062,12 +3032,6 @@ export async function PUT(request: NextRequest) {
|
||||
|
||||
if (agentWorkflowUiConfig !== undefined) {
|
||||
const normalized = normalizeAgentWorkflowUiConfig(agentWorkflowUiConfig);
|
||||
const missingPreviewResponse = createAgentWorkflowMissingPreviewResponse(
|
||||
normalized.steps
|
||||
);
|
||||
if (missingPreviewResponse) {
|
||||
return missingPreviewResponse;
|
||||
}
|
||||
await persistSystemSettingWithHistory(
|
||||
AGENT_WORKFLOW_UI_CONFIG_KEY,
|
||||
normalized,
|
||||
|
||||
@ -389,6 +389,15 @@ function buildPsdLayerPreviewUrl(
|
||||
});
|
||||
}
|
||||
|
||||
function getPsdLayerPreviewSourceUrl(
|
||||
layer: Pick<AgentPsdTemplateLayerSlot, "sourceUrl" | "previewUrl">
|
||||
) {
|
||||
return (
|
||||
String(layer.sourceUrl || "").trim() ||
|
||||
String(layer.previewUrl || "").trim()
|
||||
);
|
||||
}
|
||||
|
||||
function buildTemplatePreviewFallbackUrls(
|
||||
template: Pick<AgentPsdTemplate, "previewUrl" | "renderBaseUrl">,
|
||||
params?: {
|
||||
@ -2032,7 +2041,7 @@ export function AgentPsdTemplateEditorDialog({
|
||||
() =>
|
||||
orderedVisiblePreviewLayers.length === 0 ||
|
||||
orderedVisiblePreviewLayers.some(
|
||||
(layer) => !String(layer.sourceUrl || "").trim()
|
||||
(layer) => !getPsdLayerPreviewSourceUrl(layer)
|
||||
),
|
||||
[orderedVisiblePreviewLayers]
|
||||
);
|
||||
@ -4102,7 +4111,8 @@ export function AgentPsdTemplateEditorDialog({
|
||||
const assignedUrl =
|
||||
effectiveImageAssignments[layer.id];
|
||||
const layerImageUrl =
|
||||
assignedUrl || layer.sourceUrl;
|
||||
assignedUrl ||
|
||||
getPsdLayerPreviewSourceUrl(layer);
|
||||
if (!layerImageUrl) {
|
||||
return null;
|
||||
}
|
||||
@ -4206,8 +4216,13 @@ export function AgentPsdTemplateEditorDialog({
|
||||
resolvedTextColor,
|
||||
textPositionOffset
|
||||
);
|
||||
const layerPreviewSourceUrl =
|
||||
getPsdLayerPreviewSourceUrl(layer);
|
||||
|
||||
if (!shouldUseEditedPreview && layer.sourceUrl) {
|
||||
if (
|
||||
!shouldUseEditedPreview &&
|
||||
layerPreviewSourceUrl
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
className={`absolute overflow-hidden ${
|
||||
@ -4249,10 +4264,13 @@ export function AgentPsdTemplateEditorDialog({
|
||||
alt={layer.layerName}
|
||||
className="h-full w-full object-fill"
|
||||
decoding="async"
|
||||
src={buildPsdLayerPreviewUrl(layer.sourceUrl, {
|
||||
width: layer.width,
|
||||
quality: 68,
|
||||
})}
|
||||
src={buildPsdLayerPreviewUrl(
|
||||
layerPreviewSourceUrl,
|
||||
{
|
||||
width: layer.width,
|
||||
quality: 68,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -4549,8 +4567,10 @@ export function AgentPsdTemplateEditorDialog({
|
||||
const resolvedTextColor =
|
||||
effectiveTextColorAssignments[layer.id] ||
|
||||
layer.textColor;
|
||||
const layerPreviewSourceUrl =
|
||||
getPsdLayerPreviewSourceUrl(layer);
|
||||
const preserveSourceAppearance =
|
||||
!!layer.sourceUrl &&
|
||||
!!layerPreviewSourceUrl &&
|
||||
!hasCustomizedTextLayerAppearance(
|
||||
layer,
|
||||
currentValue,
|
||||
@ -4582,15 +4602,18 @@ export function AgentPsdTemplateEditorDialog({
|
||||
}}
|
||||
>
|
||||
{preserveSourceAppearance &&
|
||||
layer.sourceUrl ? (
|
||||
layerPreviewSourceUrl ? (
|
||||
<img
|
||||
alt={layer.layerName}
|
||||
className="pointer-events-none absolute inset-0 h-full w-full object-fill"
|
||||
decoding="async"
|
||||
src={buildPsdLayerPreviewUrl(layer.sourceUrl, {
|
||||
width: layer.width,
|
||||
quality: 68,
|
||||
})}
|
||||
src={buildPsdLayerPreviewUrl(
|
||||
layerPreviewSourceUrl,
|
||||
{
|
||||
width: layer.width,
|
||||
quality: 68,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
{preserveSourceAppearance ? null : (
|
||||
|
||||
@ -858,7 +858,10 @@ export function getAgentWorkflowMissingPreviewOptions(
|
||||
const label = option.buttonName || option.key;
|
||||
const pathParts = [...parentPath, label];
|
||||
|
||||
if ((!enabledOnly || !disabled) && !hasAgentWorkflowOptionOwnPreview(option)) {
|
||||
if (
|
||||
(!enabledOnly || !disabled) &&
|
||||
!hasAgentWorkflowOptionRenderablePreview(option)
|
||||
) {
|
||||
missingOptions.push({
|
||||
key: option.key,
|
||||
label,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user