Phase 10L: Word Companion Structure Sync Preview
This commit is contained in:
parent
ffcbe99028
commit
cb1be6b6ba
@ -186,6 +186,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="word-companion-section word-companion-structure-preview" aria-label="Structure Sync Preview">
|
||||||
|
<div class="word-companion-section-header">
|
||||||
|
<span>Structure Sync Preview</span>
|
||||||
|
<button type="button" data-analyse-manuscript-structure disabled>Analyse Manuscript Structure</button>
|
||||||
|
</div>
|
||||||
|
<p class="word-companion-message" data-structure-preview-status>Select a project and book to analyse manuscript structure.</p>
|
||||||
|
<div class="word-companion-preview-groups" data-structure-preview-results>
|
||||||
|
<p>No preview generated.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<details class="word-companion-section word-companion-collapsible">
|
<details class="word-companion-section word-companion-collapsible">
|
||||||
<summary>Document Outline</summary>
|
<summary>Document Outline</summary>
|
||||||
<div class="word-companion-outline" data-document-outline>
|
<div class="word-companion-outline" data-document-outline>
|
||||||
|
|||||||
@ -343,6 +343,54 @@ body {
|
|||||||
border-color: rgba(47, 111, 99, 0.38);
|
border-color: rgba(47, 111, 99, 0.38);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.word-companion-structure-preview {
|
||||||
|
border-color: rgba(47, 111, 99, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-groups,
|
||||||
|
.word-companion-preview-group,
|
||||||
|
.word-companion-preview-item {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-group {
|
||||||
|
border-top: 1px solid var(--companion-line);
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-group:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-item {
|
||||||
|
border: 1px solid rgba(47, 111, 99, 0.18);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 7px;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-item span,
|
||||||
|
.word-companion-preview-matches li {
|
||||||
|
color: var(--companion-ink);
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-matches {
|
||||||
|
display: grid;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-companion-preview-matches ul {
|
||||||
|
display: grid;
|
||||||
|
gap: 3px;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.word-companion-dialog {
|
.word-companion-dialog {
|
||||||
width: min(360px, calc(100vw - 24px));
|
width: min(360px, calc(100vw - 24px));
|
||||||
border: 1px solid var(--companion-line);
|
border: 1px solid var(--companion-line);
|
||||||
|
|||||||
@ -22,6 +22,9 @@
|
|||||||
const documentMessage = document.querySelector("[data-document-message]");
|
const documentMessage = document.querySelector("[data-document-message]");
|
||||||
const syncNote = document.querySelector("[data-sync-note]");
|
const syncNote = document.querySelector("[data-sync-note]");
|
||||||
const documentOutline = document.querySelector("[data-document-outline]");
|
const documentOutline = document.querySelector("[data-document-outline]");
|
||||||
|
const analyseManuscriptStructureButton = document.querySelector("[data-analyse-manuscript-structure]");
|
||||||
|
const structurePreviewStatus = document.querySelector("[data-structure-preview-status]");
|
||||||
|
const structurePreviewResults = document.querySelector("[data-structure-preview-results]");
|
||||||
const refreshPlotDirectorSceneButton = document.querySelector("[data-refresh-plotdirector-scene]");
|
const refreshPlotDirectorSceneButton = document.querySelector("[data-refresh-plotdirector-scene]");
|
||||||
const plotDirectorSceneStatus = document.querySelector("[data-plotdirector-scene-status]");
|
const plotDirectorSceneStatus = document.querySelector("[data-plotdirector-scene-status]");
|
||||||
const anchorStatus = document.querySelector("[data-anchor-status]");
|
const anchorStatus = document.querySelector("[data-anchor-status]");
|
||||||
@ -133,6 +136,7 @@
|
|||||||
let linkDialogChapters = [];
|
let linkDialogChapters = [];
|
||||||
let selectedLinkChapterId = null;
|
let selectedLinkChapterId = null;
|
||||||
let pendingCreateChapterConfirmation = null;
|
let pendingCreateChapterConfirmation = null;
|
||||||
|
let structurePreviewModel = null;
|
||||||
let currentSceneLinks = {
|
let currentSceneLinks = {
|
||||||
characters: [],
|
characters: [],
|
||||||
assets: [],
|
assets: [],
|
||||||
@ -249,6 +253,16 @@
|
|||||||
setText(syncStatus, message);
|
setText(syncStatus, message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setStructurePreviewStatus = (message) => {
|
||||||
|
setText(structurePreviewStatus, message);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setAnalyseButtonEnabled = () => {
|
||||||
|
if (analyseManuscriptStructureButton) {
|
||||||
|
analyseManuscriptStructureButton.disabled = !selectedProject() || !selectedBook();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const setResolvedScene = (sceneId, chapterId = null, resolutionMethod = "") => {
|
const setResolvedScene = (sceneId, chapterId = null, resolutionMethod = "") => {
|
||||||
resolvedSceneId = Number.isInteger(sceneId) && sceneId > 0 ? sceneId : null;
|
resolvedSceneId = Number.isInteger(sceneId) && sceneId > 0 ? sceneId : null;
|
||||||
resolvedChapterId = Number.isInteger(chapterId) && chapterId > 0 ? chapterId : null;
|
resolvedChapterId = Number.isInteger(chapterId) && chapterId > 0 ? chapterId : null;
|
||||||
@ -780,6 +794,7 @@
|
|||||||
if (syncNote) {
|
if (syncNote) {
|
||||||
syncNote.textContent = book ? "" : "Select a PlotDirector book before refreshing.";
|
syncNote.textContent = book ? "" : "Select a PlotDirector book before refreshing.";
|
||||||
}
|
}
|
||||||
|
setAnalyseButtonEnabled();
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizedStyleName = (paragraph) => {
|
const normalizedStyleName = (paragraph) => {
|
||||||
@ -937,6 +952,308 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const previewGroups = [
|
||||||
|
{ key: "alreadyLinked", title: "Already Linked" },
|
||||||
|
{ key: "couldLink", title: "Could Link" },
|
||||||
|
{ key: "wouldCreateChapters", title: "Would Create Chapters" },
|
||||||
|
{ key: "wouldCreateScenes", title: "Would Create Scenes" },
|
||||||
|
{ key: "manualReview", title: "Manual Review Required" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const previewActionLabels = {
|
||||||
|
alreadyLinked: "Already Linked",
|
||||||
|
couldLink: "Could Link",
|
||||||
|
wouldCreateChapter: "Would Create Chapter",
|
||||||
|
wouldCreateScene: "Would Create Scene",
|
||||||
|
manualReview: "Manual Review Required"
|
||||||
|
};
|
||||||
|
|
||||||
|
const previewActionSymbols = {
|
||||||
|
alreadyLinked: "✓",
|
||||||
|
couldLink: "~",
|
||||||
|
wouldCreateChapter: "+",
|
||||||
|
wouldCreateScene: "+",
|
||||||
|
manualReview: "?"
|
||||||
|
};
|
||||||
|
|
||||||
|
const titleKey = (title, type) => normalizeTitleForResolve(title, type).toLocaleLowerCase();
|
||||||
|
|
||||||
|
const createPreviewItem = ({ category, action, type, wordTitle, match = "", anchorStatus = "None", matches = [], pdChapter = null }) => ({
|
||||||
|
category,
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
wordTitle,
|
||||||
|
match,
|
||||||
|
anchorStatus,
|
||||||
|
matches,
|
||||||
|
pdChapter
|
||||||
|
});
|
||||||
|
|
||||||
|
const addPreviewItem = (model, item) => {
|
||||||
|
if (Array.isArray(model[item.category])) {
|
||||||
|
model[item.category].push(item);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sceneRowsForChapter = (chapter) => Array.isArray(chapter?.scenes) ? chapter.scenes : [];
|
||||||
|
|
||||||
|
const findSceneById = (chapters, sceneId) => {
|
||||||
|
for (const chapter of chapters) {
|
||||||
|
const scene = sceneRowsForChapter(chapter).find((item) => item.sceneId === sceneId);
|
||||||
|
if (scene) {
|
||||||
|
return { chapter, scene };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const compareChapterForPreview = (wordChapter, plotDirectorChapters, model) => {
|
||||||
|
const anchorStatus = wordChapter.anchorId ? `PD-CHAPTER-${wordChapter.anchorId}` : "None";
|
||||||
|
if (wordChapter.anchorId) {
|
||||||
|
const anchoredChapter = plotDirectorChapters.find((chapter) => chapter.chapterId === wordChapter.anchorId);
|
||||||
|
if (anchoredChapter) {
|
||||||
|
const item = createPreviewItem({
|
||||||
|
category: "alreadyLinked",
|
||||||
|
action: "alreadyLinked",
|
||||||
|
type: "Chapter",
|
||||||
|
wordTitle: wordChapter.title,
|
||||||
|
match: `Chapter ${anchoredChapter.chapterId}: ${anchoredChapter.title}`,
|
||||||
|
anchorStatus,
|
||||||
|
pdChapter: anchoredChapter
|
||||||
|
});
|
||||||
|
addPreviewItem(model, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = createPreviewItem({
|
||||||
|
category: "manualReview",
|
||||||
|
action: "manualReview",
|
||||||
|
type: "Chapter",
|
||||||
|
wordTitle: wordChapter.title,
|
||||||
|
anchorStatus: `${anchorStatus} not found`,
|
||||||
|
matches: [],
|
||||||
|
pdChapter: null
|
||||||
|
});
|
||||||
|
addPreviewItem(model, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matches = plotDirectorChapters.filter((chapter) => titleKey(chapter.title, "chapter") === titleKey(wordChapter.title, "chapter"));
|
||||||
|
if (matches.length === 1) {
|
||||||
|
const item = createPreviewItem({
|
||||||
|
category: "couldLink",
|
||||||
|
action: "couldLink",
|
||||||
|
type: "Chapter",
|
||||||
|
wordTitle: wordChapter.title,
|
||||||
|
match: `Chapter ${matches[0].chapterId}: ${matches[0].title}`,
|
||||||
|
anchorStatus,
|
||||||
|
pdChapter: matches[0]
|
||||||
|
});
|
||||||
|
addPreviewItem(model, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches.length > 1) {
|
||||||
|
const item = createPreviewItem({
|
||||||
|
category: "manualReview",
|
||||||
|
action: "manualReview",
|
||||||
|
type: "Chapter",
|
||||||
|
wordTitle: wordChapter.title,
|
||||||
|
anchorStatus,
|
||||||
|
matches: matches.map((chapter) => `Chapter ${chapter.chapterId}: ${chapter.title}`),
|
||||||
|
pdChapter: null
|
||||||
|
});
|
||||||
|
addPreviewItem(model, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = createPreviewItem({
|
||||||
|
category: "wouldCreateChapters",
|
||||||
|
action: "wouldCreateChapter",
|
||||||
|
type: "Chapter",
|
||||||
|
wordTitle: wordChapter.title,
|
||||||
|
anchorStatus,
|
||||||
|
pdChapter: null
|
||||||
|
});
|
||||||
|
addPreviewItem(model, item);
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
const compareSceneForPreview = (wordScene, chapterPreview, plotDirectorChapters, model) => {
|
||||||
|
const anchorStatus = wordScene.anchorId ? `PD-SCENE-${wordScene.anchorId}` : "None";
|
||||||
|
if (wordScene.anchorId) {
|
||||||
|
const anchored = findSceneById(plotDirectorChapters, wordScene.anchorId);
|
||||||
|
if (anchored) {
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "alreadyLinked",
|
||||||
|
action: "alreadyLinked",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
match: `Scene ${anchored.scene.sceneId}: ${anchored.scene.title}`,
|
||||||
|
anchorStatus
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "manualReview",
|
||||||
|
action: "manualReview",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
anchorStatus: `${anchorStatus} not found`
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chapterPreview?.pdChapter && chapterPreview?.category === "manualReview") {
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "manualReview",
|
||||||
|
action: "manualReview",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
anchorStatus,
|
||||||
|
matches: ["Parent chapter requires manual review."]
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chapterPreview?.pdChapter) {
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "wouldCreateScenes",
|
||||||
|
action: "wouldCreateScene",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
anchorStatus
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matches = sceneRowsForChapter(chapterPreview.pdChapter)
|
||||||
|
.filter((scene) => titleKey(scene.title, "scene") === titleKey(wordScene.title, "scene"));
|
||||||
|
if (matches.length === 1) {
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "couldLink",
|
||||||
|
action: "couldLink",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
match: `Scene ${matches[0].sceneId}: ${matches[0].title}`,
|
||||||
|
anchorStatus
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches.length > 1) {
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "manualReview",
|
||||||
|
action: "manualReview",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
anchorStatus,
|
||||||
|
matches: matches.map((scene) => `Scene ${scene.sceneId}: ${scene.title}`)
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPreviewItem(model, createPreviewItem({
|
||||||
|
category: "wouldCreateScenes",
|
||||||
|
action: "wouldCreateScene",
|
||||||
|
type: "Scene",
|
||||||
|
wordTitle: wordScene.title,
|
||||||
|
anchorStatus
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildStructurePreviewModel = (wordStructure, plotDirectorStructure) => {
|
||||||
|
const model = {
|
||||||
|
alreadyLinked: [],
|
||||||
|
couldLink: [],
|
||||||
|
wouldCreateChapters: [],
|
||||||
|
wouldCreateScenes: [],
|
||||||
|
manualReview: []
|
||||||
|
};
|
||||||
|
const plotDirectorChapters = Array.isArray(plotDirectorStructure?.chapters) ? plotDirectorStructure.chapters : [];
|
||||||
|
|
||||||
|
for (const wordChapter of Array.isArray(wordStructure?.chapters) ? wordStructure.chapters : []) {
|
||||||
|
const chapterPreview = compareChapterForPreview(wordChapter, plotDirectorChapters, model);
|
||||||
|
for (const wordScene of sceneRowsForChapter(wordChapter)) {
|
||||||
|
compareSceneForPreview(wordScene, chapterPreview, plotDirectorChapters, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderPreviewItem = (item) => {
|
||||||
|
const row = document.createElement("article");
|
||||||
|
row.className = "word-companion-preview-item";
|
||||||
|
|
||||||
|
const title = document.createElement("strong");
|
||||||
|
title.textContent = `${previewActionSymbols[item.action] || ""} ${item.type}: ${item.wordTitle}`;
|
||||||
|
row.append(title);
|
||||||
|
|
||||||
|
const anchor = document.createElement("span");
|
||||||
|
anchor.textContent = `Anchor: ${item.anchorStatus || "None"}`;
|
||||||
|
row.append(anchor);
|
||||||
|
|
||||||
|
if (item.match) {
|
||||||
|
const match = document.createElement("span");
|
||||||
|
match.textContent = `Match: ${item.match}`;
|
||||||
|
row.append(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(item.matches) && item.matches.length > 0) {
|
||||||
|
const matches = document.createElement("div");
|
||||||
|
matches.className = "word-companion-preview-matches";
|
||||||
|
const label = document.createElement("span");
|
||||||
|
label.textContent = "Matches:";
|
||||||
|
matches.append(label);
|
||||||
|
const list = document.createElement("ul");
|
||||||
|
for (const matchText of item.matches) {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.textContent = matchText;
|
||||||
|
list.append(li);
|
||||||
|
}
|
||||||
|
matches.append(list);
|
||||||
|
row.append(matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = document.createElement("span");
|
||||||
|
action.textContent = `Action: ${previewActionLabels[item.action] || item.action}`;
|
||||||
|
row.append(action);
|
||||||
|
return row;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderStructurePreview = (model) => {
|
||||||
|
if (!structurePreviewResults) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
structurePreviewResults.innerHTML = "";
|
||||||
|
for (const group of previewGroups) {
|
||||||
|
const section = document.createElement("section");
|
||||||
|
section.className = "word-companion-preview-group";
|
||||||
|
|
||||||
|
const heading = document.createElement("strong");
|
||||||
|
heading.textContent = group.title;
|
||||||
|
section.append(heading);
|
||||||
|
|
||||||
|
const items = Array.isArray(model?.[group.key]) ? model[group.key] : [];
|
||||||
|
if (items.length === 0) {
|
||||||
|
const empty = document.createElement("p");
|
||||||
|
empty.className = "word-companion-empty-list";
|
||||||
|
empty.textContent = "None";
|
||||||
|
section.append(empty);
|
||||||
|
} else {
|
||||||
|
for (const item of items) {
|
||||||
|
section.append(renderPreviewItem(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
structurePreviewResults.append(section);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const readDocumentStructure = async (context) => {
|
const readDocumentStructure = async (context) => {
|
||||||
const bodyParagraphs = context.document.body.paragraphs;
|
const bodyParagraphs = context.document.body.paragraphs;
|
||||||
const selectionParagraphs = context.document.getSelection().paragraphs;
|
const selectionParagraphs = context.document.getSelection().paragraphs;
|
||||||
@ -1012,6 +1329,64 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const analyseManuscriptStructure = async () => {
|
||||||
|
const book = selectedBook();
|
||||||
|
if (!selectedProject() || !book) {
|
||||||
|
setStructurePreviewStatus("Select a project and book to analyse manuscript structure.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!officeReady || !wordHostAvailable || !window.Word || typeof window.Word.run !== "function") {
|
||||||
|
setStructurePreviewStatus("Word document access is unavailable.");
|
||||||
|
setDiagnostics({ lastScan: "Failure", lastError: "Word document access is unavailable." });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analyseManuscriptStructureButton) {
|
||||||
|
analyseManuscriptStructureButton.disabled = true;
|
||||||
|
analyseManuscriptStructureButton.textContent = "Analysing...";
|
||||||
|
}
|
||||||
|
setStructurePreviewStatus("Analysing manuscript structure...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const wordStructure = await window.Word.run(async (context) => {
|
||||||
|
return await readDocumentStructure(context);
|
||||||
|
});
|
||||||
|
const plotDirectorStructure = await fetchJson(`/api/word-companion/books/${book.bookId}/structure`);
|
||||||
|
|
||||||
|
setCurrentStructure(
|
||||||
|
wordStructure.currentChapter?.title,
|
||||||
|
wordStructure.currentScene?.title,
|
||||||
|
wordStructure.currentScene?.wordCount,
|
||||||
|
wordStructure.currentChapter?.anchorId,
|
||||||
|
wordStructure.currentScene?.anchorId,
|
||||||
|
wordStructure.currentChapter?.index
|
||||||
|
);
|
||||||
|
renderOutline(wordStructure);
|
||||||
|
structurePreviewModel = buildStructurePreviewModel(wordStructure, plotDirectorStructure);
|
||||||
|
renderStructurePreview(structurePreviewModel);
|
||||||
|
setStructurePreviewStatus("Preview generated. No changes have been applied.");
|
||||||
|
setDiagnostics({
|
||||||
|
lastScan: "Success",
|
||||||
|
lastError: "-",
|
||||||
|
paragraphs: String(wordStructure.paragraphCount),
|
||||||
|
heading1: String(wordStructure.heading1Count),
|
||||||
|
heading2: String(wordStructure.heading2Count)
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Unable to analyse manuscript structure.", error);
|
||||||
|
setStructurePreviewStatus("Unable to analyse manuscript structure.");
|
||||||
|
setDiagnostics({ lastScan: "Failure", lastError: errorText(error) });
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (analyseManuscriptStructureButton) {
|
||||||
|
analyseManuscriptStructureButton.textContent = "Analyse Manuscript Structure";
|
||||||
|
setAnalyseButtonEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const runDiagnostics = async () => {
|
const runDiagnostics = async () => {
|
||||||
if (runDiagnosticsButton) {
|
if (runDiagnosticsButton) {
|
||||||
runDiagnosticsButton.disabled = true;
|
runDiagnosticsButton.disabled = true;
|
||||||
@ -2153,6 +2528,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
refreshDocumentButton?.addEventListener("click", refreshDocumentStructure);
|
refreshDocumentButton?.addEventListener("click", refreshDocumentStructure);
|
||||||
|
analyseManuscriptStructureButton?.addEventListener("click", analyseManuscriptStructure);
|
||||||
refreshPlotDirectorSceneButton?.addEventListener("click", refreshPlotDirectorScene);
|
refreshPlotDirectorSceneButton?.addEventListener("click", refreshPlotDirectorScene);
|
||||||
refreshCurrentSceneButton?.addEventListener("click", refreshCurrentScene);
|
refreshCurrentSceneButton?.addEventListener("click", refreshCurrentScene);
|
||||||
syncSceneProgressButton?.addEventListener("click", syncSceneProgress);
|
syncSceneProgressButton?.addEventListener("click", syncSceneProgress);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user