创作数据流程收束
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
export function EditorEmptyState({ message }: { message: string }) {
|
||||
return (
|
||||
<div className="rounded-2xl border border-white/10 bg-black/20 p-6 text-sm text-zinc-300">
|
||||
{message}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { SaveBar, SelectField, type SelectFieldOption } from './FormFields';
|
||||
import { SectionCard } from './SectionCard';
|
||||
|
||||
export function EditorSelectionCard({
|
||||
title,
|
||||
description,
|
||||
selectLabel,
|
||||
selectValue,
|
||||
onSelectChange,
|
||||
selectOptions,
|
||||
saveLabel,
|
||||
onSave,
|
||||
isSaving,
|
||||
saveMessage,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
description?: string;
|
||||
selectLabel: string;
|
||||
selectValue: string | number;
|
||||
onSelectChange: (value: string) => void;
|
||||
selectOptions: SelectFieldOption[];
|
||||
saveLabel: string;
|
||||
onSave: () => void;
|
||||
isSaving: boolean;
|
||||
saveMessage: string | null;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<SectionCard title={title} description={description}>
|
||||
<SelectField
|
||||
label={selectLabel}
|
||||
value={selectValue}
|
||||
onChange={onSelectChange}
|
||||
options={selectOptions}
|
||||
/>
|
||||
{children}
|
||||
<SaveBar
|
||||
saveLabel={saveLabel}
|
||||
onSave={onSave}
|
||||
isSaving={isSaving}
|
||||
saveMessage={saveMessage}
|
||||
/>
|
||||
</SectionCard>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export function cloneValue<T>(value: T): T {
|
||||
if (typeof structuredClone === 'function') {
|
||||
return structuredClone(value);
|
||||
}
|
||||
|
||||
return JSON.parse(JSON.stringify(value)) as T;
|
||||
}
|
||||
@@ -27,10 +27,6 @@ export const ASSET_API_PATHS = {
|
||||
characterAnimationJobs: `${ASSETS_API_BASE_PATH}/character-animation/jobs`,
|
||||
characterAnimationImportVideo: `${ASSETS_API_BASE_PATH}/character-animation/import-video`,
|
||||
characterAnimationTemplates: `${ASSETS_API_BASE_PATH}/character-animation/templates`,
|
||||
qwenSpriteMaster: `${ASSETS_API_BASE_PATH}/qwen-sprite/master`,
|
||||
qwenSpriteSheet: `${ASSETS_API_BASE_PATH}/qwen-sprite/sheet`,
|
||||
qwenSpriteFrameRepair: `${ASSETS_API_BASE_PATH}/qwen-sprite/frame-repair`,
|
||||
qwenSpriteSave: `${ASSETS_API_BASE_PATH}/qwen-sprite/save`,
|
||||
} as const;
|
||||
|
||||
export const EDITOR_ITEM_CATALOG_API_PATH =
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
saveEditorJsonResource,
|
||||
type EditorJsonResourceId,
|
||||
} from './editorApiClient';
|
||||
|
||||
type UseJsonSaveOptions = {
|
||||
resourceId: EditorJsonResourceId;
|
||||
payload: Record<string, unknown>;
|
||||
validate?: () => string[];
|
||||
successMessage: string;
|
||||
errorMessage: string;
|
||||
};
|
||||
|
||||
export function useJsonSave({
|
||||
resourceId,
|
||||
payload,
|
||||
validate,
|
||||
successMessage,
|
||||
errorMessage,
|
||||
}: UseJsonSaveOptions) {
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [saveMessage, setSaveMessage] = useState<string | null>(null);
|
||||
|
||||
const save = async () => {
|
||||
setIsSaving(true);
|
||||
setSaveMessage(null);
|
||||
|
||||
const validationErrors = validate?.() ?? [];
|
||||
if (validationErrors.length > 0) {
|
||||
setSaveMessage(validationErrors.slice(0, 3).join(' | '));
|
||||
setIsSaving(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await saveEditorJsonResource(resourceId, payload, errorMessage);
|
||||
setSaveMessage(successMessage);
|
||||
} catch (error) {
|
||||
setSaveMessage(error instanceof Error ? error.message : errorMessage);
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { isSaving, saveMessage, save };
|
||||
}
|
||||
Reference in New Issue
Block a user