feat(npcs): drop binding; select NPCs on storyline export

Remove storyline/scene NPC binding and export chosen NPCs with relations/groups. Harden export modal so a missing npcs payload no longer blacks out the editor.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-07-30 10:05:09 +08:00
parent 04c75cd725
commit e08f5ef550
17 changed files with 418 additions and 522 deletions
+11 -2
View File
@@ -148,10 +148,14 @@ type Actions = {
npcResolutions?: NpcImportResolution[],
) => Promise<{ project: Project; report: StorylineImportMergeReport }>;
importProjectFromPath: (filePath: string) => Promise<void>;
getProjectStorylines: (projectId: ProjectId, labels: StorylineLabels) => Promise<StorylineListItem[]>;
getProjectStorylines: (
projectId: ProjectId,
labels: StorylineLabels,
) => Promise<{ storylines: StorylineListItem[]; npcs: { id: string; name: string }[] }>;
exportProject: (
projectId: ProjectId,
storylineSelections: StorylineSelection[],
npcIds: string[],
labels: StorylineLabels,
) => Promise<void>;
deleteProject: (projectId: ProjectId) => Promise<void>;
@@ -869,18 +873,23 @@ export function useProjectState(licenseActive: boolean, opts?: ProjectStateOpts)
const getProjectStorylines = async (projectId: ProjectId, labels: StorylineLabels) => {
const res = await api.invoke(ipcChannels.project.getProjectStorylines, { projectId, labels });
return res.storylines;
return {
storylines: Array.isArray(res?.storylines) ? res.storylines : [],
npcs: Array.isArray(res?.npcs) ? res.npcs : [],
};
};
const exportProject = async (
projectId: ProjectId,
storylineSelections: StorylineSelection[],
npcIds: string[],
labels: StorylineLabels,
) => {
try {
const res = await api.invoke(ipcChannels.project.exportZip, {
projectId,
storylineSelections,
npcIds,
labels,
});
if (res.canceled) return;