From f5153485afffc209c0787afd406a07c3325eeaad Mon Sep 17 00:00:00 2001 From: CPTN Cosmo Date: Sat, 24 Jan 2026 15:23:33 +0100 Subject: [PATCH 1/2] Add options to import documents into specific folders or compendium packs and sort them by tier. --- module.json | 4 +- scripts/app.js | 9 +++- scripts/importer.js | 101 +++++++++++++++++++++++++++++++++++++++--- templates/preview.hbs | 29 ++++++++++++ 4 files changed, 133 insertions(+), 10 deletions(-) diff --git a/module.json b/module.json index 90458b6..c9d7f99 100644 --- a/module.json +++ b/module.json @@ -1,7 +1,7 @@ { "id": "dh-importer", "title": "Daggerheart Statblock Importer", - "version": "1.2.0", + "version": "1.2.1", "compatibility": { "minimum": "13", "verified": "13" @@ -34,5 +34,5 @@ "description": "Imports Adversaries and Environments from text blocks into the Daggerheart system.", "url": "https://github.com/cptn-cosmo/dh-importer", "manifest": "https://git.geeks.gay/cosmo/dh-importer/raw/branch/main/module.json", - "download": "https://git.geeks.gay/cosmo/dh-importer/releases/download/1.2.0/dh-importer.zip" + "download": "https://git.geeks.gay/cosmo/dh-importer/releases/download/1.2.1/dh-importer.zip" } \ No newline at end of file diff --git a/scripts/app.js b/scripts/app.js index 2d30b66..466ac48 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -47,7 +47,9 @@ export class DHImporterApp extends HandlebarsApplicationMixin(ApplicationV2) { adversary: "Adversary", environment: "Environment" }, - inputText: this.inputText + inputText: this.inputText, + folders: game.folders.filter(f => f.type === "Actor").sort((a, b) => a.name.localeCompare(b.name)), + packs: game.packs.filter(p => p.documentName === "Actor" && !p.locked) }; } @@ -152,7 +154,10 @@ export class DHImporterApp extends HandlebarsApplicationMixin(ApplicationV2) { } } - await DHImporter.createDocuments(this.parsedData, this.parsedDataType); + const importTarget = formData.importTarget || ""; + const sortTier = formData.sortTier || false; + + await DHImporter.createDocuments(this.parsedData, this.parsedDataType, { target: importTarget, sortTier }); ui.notifications.info(`Successfully imported ${this.parsedData.length} documents.`); this.close(); } catch (e) { diff --git a/scripts/importer.js b/scripts/importer.js index 1500f3c..a8ccaf9 100644 --- a/scripts/importer.js +++ b/scripts/importer.js @@ -544,19 +544,86 @@ export class DHImporter { return results; } - static async createDocuments(dataList, type) { + static async createDocuments(dataList, type, options = {}) { if (!dataList || dataList.length === 0) return; + const { target, sortTier } = options; const Actor = getDocumentClass("Actor"); + const Folder = getDocumentClass("Folder"); const actorsToCreate = []; + // Determine Target Context + let targetFolderId = null; + let targetPack = null; + + if (target) { + if (game.packs.has(target)) { + targetPack = game.packs.get(target); + } else { + targetFolderId = target; + } + } + + // Folder Cache for Tier Sorting + const folderCache = {}; + + const getTierFolder = async (tier) => { + const folderName = `Tier ${tier}`; + const cacheKey = `${targetPack ? targetPack.collection : "world"}-${targetFolderId || "root"}-${tier}`; + + if (folderCache[cacheKey]) return folderCache[cacheKey]; + + // Parent ID (for creating subfolder) + const parentId = targetFolderId; + + // Search for existing folder + let folder; + if (targetPack) { + // Search in compendium index (requires V11+ folders) + // We'll rely on pack.folders if available (V11) + if (targetPack.folders) { + folder = targetPack.folders.find(f => f.name === folderName && f.folder?.id === parentId); + } + } else { + // Search in World + folder = game.folders.find(f => f.type === "Actor" && f.name === folderName && f.folder?.id === parentId); + } + + if (folder) { + folderCache[cacheKey] = folder.id; + return folder.id; + } + + // Create Folder if not found + try { + const folderData = { + name: folderName, + type: "Actor", + folder: parentId, + sorting: "a" + }; + + if (targetPack) { + folderData.pack = targetPack.collection; + } + + const newFolder = await Folder.create(folderData, { pack: targetPack?.collection }); + if (newFolder) { + folderCache[cacheKey] = newFolder.id; + return newFolder.id; + } + } catch (e) { + console.warn("Could not create Tier folder:", e); + // Fallback to parent + return parentId; + } + }; + for (const data of dataList) { - // Process Items based on 'useCompendium' flags or similar set by the UI - // The UI should have modified data.items or we loop through and replace based on user choice + // Process Items const finalItems = []; for (const item of data.items) { if (data.useFeatures && data.useFeatures[item.name]) { - // User selected to use existing feature const uuid = data.useFeatures[item.name]; const original = await fromUuid(uuid); if (original) { @@ -570,21 +637,43 @@ export class DHImporter { } data.items = finalItems; + // Handle Sorting / Folder Assignment + if (sortTier) { + const tier = data.system.tier !== undefined ? data.system.tier : 0; + data.folder = await getTierFolder(tier); + } else if (targetFolderId) { + data.folder = targetFolderId; + } + // Clean up temporary flags const shouldOpen = data.openSheet; delete data.foundFeatures; delete data.useFeatures; delete data.openSheet; + // If finding an existing actor to update could be a future feature, but for now we create new. actorsToCreate.push({ data, shouldOpen }); } - const createdActors = await Actor.createDocuments(actorsToCreate.map(a => a.data)); + let createdActors = []; + if (targetPack) { + // Import to Compendium + // Note: createDocuments with pack option works in V10+ + const docs = actorsToCreate.map(a => a.data); + createdActors = await Actor.createDocuments(docs, { pack: targetPack.collection }); + } else { + // Import to World + createdActors = await Actor.createDocuments(actorsToCreate.map(a => a.data)); + } // Open sheets if (createdActors && createdActors.length > 0) { for (let i = 0; i < createdActors.length; i++) { - if (actorsToCreate[i].shouldOpen) { + // If we imported to compendium, we generally don't open sheets immediately as they are in the pack + // But if the user really wants to, we'd have to retrieve the sheet from the pack. + // Standard behavior for compendium import: don't open. + + if (!targetPack && actorsToCreate[i].shouldOpen) { createdActors[i].sheet.render(true); } } diff --git a/templates/preview.hbs b/templates/preview.hbs index cc25c33..3e7b8d1 100644 --- a/templates/preview.hbs +++ b/templates/preview.hbs @@ -76,6 +76,35 @@ {{/each}} +
+
+ + +
+
+ +
+
+