Add explicit Word save confirmation for import
This commit is contained in:
parent
e0c3171329
commit
f76e5bc388
@ -1926,10 +1926,14 @@ static void WordSyncRequiresSaveAcknowledgement()
|
||||
var root = Path.Combine(AppContext.BaseDirectory, "../../../../PlotLine");
|
||||
var companion = File.ReadAllText(Path.Combine(root, "wwwroot/js/word-companion-host.js"));
|
||||
var hub = File.ReadAllText(Path.Combine(root, "Hubs/WordCompanionFollowHub.cs"));
|
||||
var models = File.ReadAllText(Path.Combine(root, "Models/ManuscriptScanModels.cs"));
|
||||
var presence = File.ReadAllText(Path.Combine(root, "wwwroot/js/word-companion-presence.js"));
|
||||
var onboardingView = File.ReadAllText(Path.Combine(root, "Views/Onboarding/Index.cshtml"));
|
||||
var wordHostView = File.ReadAllText(Path.Combine(root, "Views/WordCompanionHost/Index.cshtml"));
|
||||
var migration = File.ReadAllText(Path.Combine(root, "Sql/158_Phase25C_OnboardingMarkerSaveStates.sql"));
|
||||
|
||||
Assert(companion.Contains("saveWordDocumentIfAvailable", StringComparison.Ordinal), "Companion should save Word before acknowledging marker sync.");
|
||||
Assert(!companion.Contains("window.confirm(`${manualMessage}", StringComparison.Ordinal), "Companion should not use a blocking browser confirmation for manual Word saves.");
|
||||
Assert(companion.Contains("setOnboardingManualSavePrompt", StringComparison.Ordinal), "Companion should show an explicit manual-save prompt after adding markers.");
|
||||
Assert(companion.Contains("markersChanged", StringComparison.Ordinal), "Companion should distinguish marker insertion from an idempotent no-change retry.");
|
||||
Assert(companion.Contains("SaveNotRequired", StringComparison.Ordinal), "Companion should acknowledge marker sync when no Word save is required.");
|
||||
Assert(companion.Contains("UserConfirmedSave", StringComparison.Ordinal), "Companion should support an explicit manual save acknowledgement.");
|
||||
@ -1940,7 +1944,14 @@ static void WordSyncRequiresSaveAcknowledgement()
|
||||
Assert(hub.Contains("MarkerSyncClientResult", StringComparison.Ordinal), "Server should accept marker sync diagnostics.");
|
||||
Assert(hub.Contains("MarkMarkerSyncCompletedAsync", StringComparison.Ordinal), "Server should persist completed marker sync.");
|
||||
Assert(hub.Contains("MarkMarkerSyncUserSaveRequiredAsync", StringComparison.Ordinal), "Server should persist manual-save-required marker sync.");
|
||||
Assert(hub.Contains("OnboardingBuildManualSaveRequired", StringComparison.Ordinal), "Server should notify the browser when Word needs a manual save.");
|
||||
Assert(models.Contains("public int? BuildID", StringComparison.Ordinal), "Build progress should identify the build awaiting manual save.");
|
||||
Assert(models.Contains("public string? MarkerStatus", StringComparison.Ordinal), "Build progress should carry marker sync state to the browser.");
|
||||
Assert(presence.Contains("OnboardingBuildMarkerSyncCompleted", StringComparison.Ordinal), "Browser should wait for marker sync completion before redirecting.");
|
||||
Assert(presence.Contains("OnboardingBuildManualSaveRequired", StringComparison.Ordinal), "Browser should render manual-save-required progress events.");
|
||||
Assert(presence.Contains("CompleteOnboardingBuildMarkerSync\", pendingManualSaveBuildId", StringComparison.Ordinal), "Browser should confirm manual Word saves back to the server.");
|
||||
Assert(onboardingView.Contains("data-onboarding-build-save-confirm", StringComparison.Ordinal), "Onboarding page should expose a manual Word save confirmation action.");
|
||||
Assert(wordHostView.Contains("data-onboarding-manual-save-confirm", StringComparison.Ordinal), "Word Companion should expose a manual Word save confirmation action.");
|
||||
Assert(migration.Contains("MarkerSyncCompletedUtc", StringComparison.Ordinal), "Database should persist marker sync completion time.");
|
||||
Assert(migration.Contains("UserSaveRequired", StringComparison.Ordinal), "Database should persist manual-save-required marker sync state.");
|
||||
Assert(migration.Contains("SaveNotRequired", StringComparison.Ordinal), "Database should persist no-change marker sync state.");
|
||||
|
||||
@ -294,9 +294,12 @@ public sealed class WordCompanionFollowHub(
|
||||
{
|
||||
Status = "Complete",
|
||||
Message = "Manuscript structure has been created and saved. Word may now be closed; keep this browser workflow open to review characters.",
|
||||
PercentComplete = 100
|
||||
PercentComplete = 100,
|
||||
PreviewID = result?.PreviewID,
|
||||
BuildID = buildId,
|
||||
MarkerStatus = markerStatus
|
||||
});
|
||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildMarkerSyncCompleted", new { buildId, markerStatus });
|
||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildMarkerSyncCompleted", new { buildId, markerStatus, previewID = result?.PreviewID });
|
||||
}
|
||||
|
||||
public async Task RequireOnboardingBuildManualSave(int buildId, string message, MarkerSyncClientResult? result = null)
|
||||
@ -310,14 +313,19 @@ public sealed class WordCompanionFollowHub(
|
||||
SerialiseMarkerDiagnostics(result));
|
||||
|
||||
await onboardingBuilds.MarkMarkerSyncUserSaveRequiredAsync(buildId, message);
|
||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildProgress", new OnboardingBuildProgress
|
||||
var progress = new OnboardingBuildProgress
|
||||
{
|
||||
Status = "Running",
|
||||
Message = string.IsNullOrWhiteSpace(message)
|
||||
? "Scene markers have been added. Save the document in Word, then continue the import again."
|
||||
: message,
|
||||
PercentComplete = 90
|
||||
});
|
||||
PercentComplete = 90,
|
||||
PreviewID = result?.PreviewID,
|
||||
BuildID = buildId,
|
||||
MarkerStatus = "UserSaveRequired"
|
||||
};
|
||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildProgress", progress);
|
||||
await Clients.Group(PresenceGroup(userId)).SendAsync("OnboardingBuildManualSaveRequired", progress);
|
||||
}
|
||||
|
||||
public async Task FailOnboardingBuildMarkerSync(int buildId, string message, MarkerSyncClientResult? result = null)
|
||||
@ -337,7 +345,9 @@ public sealed class WordCompanionFollowHub(
|
||||
Message = string.IsNullOrWhiteSpace(message)
|
||||
? "Word marker sync failed. Keep Word open and try again."
|
||||
: message,
|
||||
PercentComplete = 90
|
||||
PercentComplete = 90,
|
||||
BuildID = buildId,
|
||||
MarkerStatus = "Failed"
|
||||
});
|
||||
}
|
||||
|
||||
@ -427,6 +437,7 @@ public sealed class WordCompanionFollowHub(
|
||||
|
||||
public sealed class MarkerSyncClientResult
|
||||
{
|
||||
public Guid? PreviewID { get; init; }
|
||||
public string? MarkerStatus { get; init; }
|
||||
public string? Message { get; init; }
|
||||
public bool? MarkersChanged { get; init; }
|
||||
|
||||
@ -262,4 +262,6 @@ public sealed class OnboardingBuildProgress
|
||||
public int CharactersCreated { get; init; }
|
||||
public int SceneAppearancesCreated { get; init; }
|
||||
public Guid? PreviewID { get; init; }
|
||||
public int? BuildID { get; init; }
|
||||
public string? MarkerStatus { get; init; }
|
||||
}
|
||||
|
||||
@ -395,7 +395,11 @@ public sealed class OnboardingService(
|
||||
}
|
||||
|
||||
public async Task<OnboardingManuscriptBuildResult?> GetBuildResultAsync(Guid previewId)
|
||||
=> await scanPreviews.GetBuildResultAsync(RequireUserId(), previewId);
|
||||
{
|
||||
var userId = RequireUserId();
|
||||
return await scanPreviews.GetBuildResultAsync(userId, previewId)
|
||||
?? await builds.GetByPreviewAsync(userId, previewId);
|
||||
}
|
||||
|
||||
public async Task<OnboardingManuscriptBuildResult?> FinaliseCharacterReviewAsync(ManuscriptScanReviewForm form)
|
||||
{
|
||||
|
||||
@ -317,6 +317,11 @@
|
||||
<div class="onboarding-scan-progress onboarding-build-progress" aria-hidden="true">
|
||||
<span data-onboarding-build-progress></span>
|
||||
</div>
|
||||
<div class="onboarding-manual-save-actions" data-onboarding-manual-save-actions hidden>
|
||||
<button class="btn btn-primary btn-sm" type="button" data-onboarding-build-save-confirm disabled>
|
||||
I've saved the Word document
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
@ -339,6 +344,7 @@
|
||||
<button class="btn btn-primary"
|
||||
type="button"
|
||||
data-onboarding-build-start
|
||||
data-onboarding-build-action
|
||||
data-preview-id="@Model.ScanState.PreviewID">
|
||||
Detect Scenes
|
||||
</button>
|
||||
|
||||
@ -102,6 +102,16 @@
|
||||
<p>Linked to PlotDirector</p>
|
||||
</section>
|
||||
|
||||
<section class="word-companion-section word-companion-manual-save" data-onboarding-manual-save hidden aria-label="Save Word document">
|
||||
<div class="word-companion-section-header">
|
||||
<span>Save Required</span>
|
||||
</div>
|
||||
<p class="word-companion-message" data-onboarding-manual-save-message>Scene markers have been added. Save this Word document to continue.</p>
|
||||
<div class="word-companion-actions">
|
||||
<button type="button" class="word-companion-primary-action" data-onboarding-manual-save-confirm disabled>I've saved it</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="word-companion-section word-companion-writing-workspace" aria-label="Writing workspace">
|
||||
<div class="word-companion-section-header">
|
||||
<span>Writing Workspace</span>
|
||||
|
||||
@ -454,6 +454,19 @@
|
||||
border-color: rgba(47, 111, 99, .34);
|
||||
}
|
||||
|
||||
.onboarding-build-panel.is-manual-save {
|
||||
border-color: rgba(182, 138, 70, .5);
|
||||
background: rgba(182, 138, 70, .12);
|
||||
}
|
||||
|
||||
.onboarding-manual-save-actions {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .5rem;
|
||||
margin-top: .2rem;
|
||||
}
|
||||
|
||||
.onboarding-review-panel {
|
||||
width: min(1120px, 100%);
|
||||
}
|
||||
|
||||
@ -308,6 +308,15 @@ body {
|
||||
box-shadow: 0 1px 2px rgba(74, 50, 31, 0.05);
|
||||
}
|
||||
|
||||
.word-companion-manual-save {
|
||||
border-color: rgba(182, 138, 70, .55);
|
||||
background: #fff7e6;
|
||||
}
|
||||
|
||||
.word-companion-manual-save .word-companion-section-header span {
|
||||
color: var(--companion-accent-dark);
|
||||
}
|
||||
|
||||
.word-companion-section span,
|
||||
.word-companion-section label,
|
||||
.word-companion-summary span {
|
||||
|
||||
@ -19,6 +19,9 @@
|
||||
const linkedManuscriptCard = document.querySelector("[data-linked-manuscript-card]");
|
||||
const linkedProjectTitle = document.querySelector("[data-linked-project-title]");
|
||||
const linkedBookTitle = document.querySelector("[data-linked-book-title]");
|
||||
const onboardingManualSavePanel = document.querySelector("[data-onboarding-manual-save]");
|
||||
const onboardingManualSaveMessage = document.querySelector("[data-onboarding-manual-save-message]");
|
||||
const onboardingManualSaveConfirmButton = document.querySelector("[data-onboarding-manual-save-confirm]");
|
||||
const firstRunWizard = document.querySelector("[data-first-run-wizard]");
|
||||
const firstRunProjectSelect = document.querySelector("[data-first-run-project-select]");
|
||||
const firstRunBookSelect = document.querySelector("[data-first-run-book-select]");
|
||||
@ -215,6 +218,7 @@
|
||||
let firstRunImportStructure = null;
|
||||
let firstRunCharacterCandidatesModel = [];
|
||||
let lastOnboardingScanPreview = null;
|
||||
let pendingOnboardingManualSave = null;
|
||||
let firstRunStructureImported = false;
|
||||
let firstRunCharacterStepActive = false;
|
||||
let firstRunCharacterStepActivatedAt = 0;
|
||||
@ -1840,10 +1844,68 @@
|
||||
message,
|
||||
...diagnostics
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn("Unable to report onboarding marker sync completion.", error);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const setOnboardingManualSavePrompt = (buildId, message, diagnostics = {}) => {
|
||||
pendingOnboardingManualSave = { buildId, diagnostics };
|
||||
setHidden(onboardingManualSavePanel, false);
|
||||
setText(onboardingManualSaveMessage, message);
|
||||
if (onboardingManualSaveConfirmButton) {
|
||||
onboardingManualSaveConfirmButton.disabled = false;
|
||||
onboardingManualSaveConfirmButton.textContent = "I've saved it";
|
||||
}
|
||||
setDocumentMessage(message);
|
||||
};
|
||||
|
||||
const clearOnboardingManualSavePrompt = () => {
|
||||
pendingOnboardingManualSave = null;
|
||||
setHidden(onboardingManualSavePanel, true);
|
||||
if (onboardingManualSaveConfirmButton) {
|
||||
onboardingManualSaveConfirmButton.disabled = true;
|
||||
onboardingManualSaveConfirmButton.textContent = "I've saved it";
|
||||
}
|
||||
};
|
||||
|
||||
const confirmOnboardingManualSave = async () => {
|
||||
if (!pendingOnboardingManualSave?.buildId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (onboardingManualSaveConfirmButton) {
|
||||
onboardingManualSaveConfirmButton.disabled = true;
|
||||
onboardingManualSaveConfirmButton.textContent = "Confirming...";
|
||||
}
|
||||
|
||||
const completed = await invokeMarkerSyncCompleted(
|
||||
pendingOnboardingManualSave.buildId,
|
||||
"UserConfirmedSave",
|
||||
"Scene markers added; user confirmed the Word document was saved.",
|
||||
{
|
||||
...pendingOnboardingManualSave.diagnostics,
|
||||
markersChanged: true,
|
||||
saveState: "UserConfirmedSave",
|
||||
saveApi: pendingOnboardingManualSave.diagnostics?.saveApi || "manual-companion",
|
||||
...officeRuntimeDiagnostics()
|
||||
});
|
||||
|
||||
if (!completed) {
|
||||
setDocumentMessage("PlotDirector could not confirm the save yet. Keep Word open and try again.");
|
||||
if (onboardingManualSaveConfirmButton) {
|
||||
onboardingManualSaveConfirmButton.disabled = false;
|
||||
onboardingManualSaveConfirmButton.textContent = "I've saved it";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
clearOnboardingManualSavePrompt();
|
||||
setDocumentMessage("Scene markers added and save confirmed. Word may now be closed.");
|
||||
setDiagnostics({ lastError: "-" });
|
||||
};
|
||||
|
||||
const ensureDocumentGuid = () => {
|
||||
@ -2496,6 +2558,7 @@
|
||||
|
||||
await inspectPlotDirectorMarkers().catch(() => null);
|
||||
if (!markersChanged) {
|
||||
clearOnboardingManualSavePrompt();
|
||||
const diagnostics = {
|
||||
markersChanged: false,
|
||||
saveState: "NotRequired",
|
||||
@ -2513,41 +2576,20 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const saveResult = await saveWordDocumentIfAvailable();
|
||||
const saveDiagnostics = {
|
||||
previewID: result?.previewID || result?.PreviewID || null,
|
||||
markersChanged: true,
|
||||
...saveResult
|
||||
saveState: "UserSaveRequired",
|
||||
saveApi: "manual-companion",
|
||||
...officeRuntimeDiagnostics()
|
||||
};
|
||||
console.info("Onboarding marker sync Word save result.", saveDiagnostics);
|
||||
if (saveResult.saveState === "Saved") {
|
||||
await invokeMarkerSyncCompleted(
|
||||
buildId,
|
||||
"Completed",
|
||||
"Scene markers added and document saved.",
|
||||
saveDiagnostics);
|
||||
setDocumentMessage("Scene markers added and document saved. Word may now be closed.");
|
||||
setDiagnostics({ lastError: "-" });
|
||||
return;
|
||||
}
|
||||
|
||||
const manualMessage = "Scene markers have been added. Save the document in Word now, then click OK to continue.";
|
||||
setDocumentMessage(manualMessage);
|
||||
setDiagnostics({ lastError: saveResult.errorMessage || "Word document save requires manual confirmation." });
|
||||
const userConfirmedSave = window.confirm(`${manualMessage}\n\nClick Cancel if the document was not saved.`);
|
||||
if (userConfirmedSave) {
|
||||
await invokeMarkerSyncCompleted(
|
||||
buildId,
|
||||
"UserConfirmedSave",
|
||||
"Scene markers added; user confirmed the Word document was saved.",
|
||||
saveDiagnostics);
|
||||
setDocumentMessage("Scene markers added and save confirmed. Word may now be closed.");
|
||||
setDiagnostics({ lastError: "-" });
|
||||
return;
|
||||
}
|
||||
|
||||
const manualMessage = "Scene markers have been added. Save this document in Word, then click I've saved it in PlotDirector or the Companion.";
|
||||
console.info("Onboarding marker sync requires manual Word save confirmation.", saveDiagnostics);
|
||||
setOnboardingManualSavePrompt(buildId, manualMessage, saveDiagnostics);
|
||||
setDiagnostics({ lastError: "Waiting for manual Word save confirmation." });
|
||||
await invokeMarkerSyncManualSaveRequired(
|
||||
buildId,
|
||||
"Scene markers were added, but Word save still needs confirmation. Save the document in Word, then continue the import again.",
|
||||
manualMessage,
|
||||
saveDiagnostics);
|
||||
} catch (error) {
|
||||
console.error("Unable to update onboarding Word markers.", error);
|
||||
@ -6236,6 +6278,7 @@
|
||||
firstRunContinueButton?.addEventListener("click", () => finishFirstRunOnboarding());
|
||||
firstRunCancelButton?.addEventListener("click", () => setFirstRunMode(false));
|
||||
firstRunImportCancelButton?.addEventListener("click", () => resetFirstRunPreview("Import cancelled."));
|
||||
onboardingManualSaveConfirmButton?.addEventListener("click", confirmOnboardingManualSave);
|
||||
|
||||
refreshDocumentButton?.addEventListener("click", refreshDocumentStructure);
|
||||
analyseManuscriptStructureButton?.addEventListener("click", analyseManuscriptStructure);
|
||||
|
||||
@ -160,6 +160,106 @@
|
||||
.withAutomaticReconnect()
|
||||
.build();
|
||||
let pendingBuildPreviewId = "";
|
||||
let pendingManualSaveBuildId = 0;
|
||||
let pendingManualSavePreviewId = "";
|
||||
|
||||
const setBuildActionState = (text, disabled, mode = "") => {
|
||||
document.querySelectorAll("[data-onboarding-build-action]").forEach((button) => {
|
||||
button.textContent = text;
|
||||
button.disabled = disabled;
|
||||
if (mode) {
|
||||
button.dataset.buildMode = mode;
|
||||
} else {
|
||||
delete button.dataset.buildMode;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const setManualSaveRequired = (state) => {
|
||||
const buildId = Number.parseInt(
|
||||
field(state, "buildID", "BuildID")
|
||||
?? field(state, "buildId", "BuildId")
|
||||
?? "0",
|
||||
10);
|
||||
const previewId = field(state, "previewID", "PreviewID")
|
||||
|| field(state, "previewId", "PreviewId")
|
||||
|| pendingBuildPreviewId;
|
||||
const message = field(state, "message", "Message")
|
||||
|| "Scene markers have been added. Save the document in Word, then confirm here.";
|
||||
|
||||
pendingManualSaveBuildId = Number.isInteger(buildId) ? buildId : 0;
|
||||
pendingManualSavePreviewId = previewId || pendingBuildPreviewId;
|
||||
pendingBuildPreviewId = pendingManualSavePreviewId || pendingBuildPreviewId;
|
||||
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.add("is-running", "is-manual-save");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = message;
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-percent]").forEach((node) => {
|
||||
node.textContent = "90%";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-progress]").forEach((node) => {
|
||||
node.style.width = "90%";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-manual-save-actions]").forEach((node) => {
|
||||
node.hidden = false;
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-save-confirm]").forEach((button) => {
|
||||
button.disabled = !pendingManualSaveBuildId;
|
||||
button.textContent = "I've saved the Word document";
|
||||
});
|
||||
setBuildActionState("I've saved the Word document", !pendingManualSaveBuildId, "confirm-save");
|
||||
};
|
||||
|
||||
const clearManualSaveRequired = () => {
|
||||
pendingManualSaveBuildId = 0;
|
||||
pendingManualSavePreviewId = "";
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.remove("is-manual-save");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-manual-save-actions]").forEach((node) => {
|
||||
node.hidden = true;
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-save-confirm]").forEach((button) => {
|
||||
button.disabled = true;
|
||||
button.textContent = "I've saved the Word document";
|
||||
});
|
||||
setBuildActionState("Detect Scenes", false);
|
||||
};
|
||||
|
||||
const confirmManualSaveFromWeb = async () => {
|
||||
if (!pendingManualSaveBuildId) {
|
||||
return;
|
||||
}
|
||||
|
||||
setBuildActionState("Confirming...", true, "confirm-save");
|
||||
document.querySelectorAll("[data-onboarding-build-save-confirm]").forEach((button) => {
|
||||
button.disabled = true;
|
||||
button.textContent = "Confirming...";
|
||||
});
|
||||
|
||||
try {
|
||||
await connection.invoke("CompleteOnboardingBuildMarkerSync", pendingManualSaveBuildId, {
|
||||
previewID: pendingManualSavePreviewId || pendingBuildPreviewId || null,
|
||||
markerStatus: "UserConfirmedSave",
|
||||
message: "Scene markers added; user confirmed the Word document was saved.",
|
||||
markersChanged: true,
|
||||
saveState: "UserConfirmedSave",
|
||||
saveApi: "manual-web"
|
||||
});
|
||||
} catch (error) {
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = error?.message || "PlotDirector could not confirm the save yet. Keep Word open and try again.";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-save-confirm]").forEach((button) => {
|
||||
button.disabled = false;
|
||||
button.textContent = "I've saved the Word document";
|
||||
});
|
||||
setBuildActionState("I've saved the Word document", false, "confirm-save");
|
||||
}
|
||||
};
|
||||
|
||||
connection.on("WordCompanionPresenceChanged", applyStatus);
|
||||
connection.on("OnboardingScanStateChanged", applyScanState);
|
||||
@ -170,8 +270,14 @@
|
||||
const message = field(state, "message", "Message") || "Preparing chapters...";
|
||||
const percent = field(state, "percentComplete", "PercentComplete");
|
||||
const safePercent = Math.max(0, Math.min(100, Number.parseInt(percent || "0", 10) || 0));
|
||||
const markerStatus = field(state, "markerStatus", "MarkerStatus");
|
||||
if (markerStatus === "UserSaveRequired") {
|
||||
setManualSaveRequired(state);
|
||||
return;
|
||||
}
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.add("is-running");
|
||||
node.classList.remove("is-manual-save");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = message;
|
||||
@ -189,7 +295,11 @@
|
||||
window.location.href = `/onboarding/build-complete?previewId=${encodeURIComponent(previewId)}`;
|
||||
}
|
||||
});
|
||||
connection.on("OnboardingBuildMarkerSyncCompleted", () => {
|
||||
connection.on("OnboardingBuildManualSaveRequired", setManualSaveRequired);
|
||||
connection.on("OnboardingBuildMarkerSyncCompleted", (result) => {
|
||||
const previewId = field(result, "previewID", "PreviewID") || field(result, "previewId", "PreviewId");
|
||||
pendingBuildPreviewId = previewId || pendingBuildPreviewId || pendingManualSavePreviewId;
|
||||
clearManualSaveRequired();
|
||||
if (pendingBuildPreviewId) {
|
||||
window.location.href = `/onboarding/build-complete?previewId=${encodeURIComponent(pendingBuildPreviewId)}`;
|
||||
}
|
||||
@ -221,11 +331,17 @@
|
||||
|
||||
document.querySelectorAll("[data-onboarding-build-start]").forEach((button) => {
|
||||
button.addEventListener("click", async () => {
|
||||
if (button.dataset.buildMode === "confirm-save" || pendingManualSaveBuildId) {
|
||||
await confirmManualSaveFromWeb();
|
||||
return;
|
||||
}
|
||||
|
||||
const previewId = button.dataset.previewId;
|
||||
if (!previewId) {
|
||||
return;
|
||||
}
|
||||
pendingBuildPreviewId = previewId;
|
||||
clearManualSaveRequired();
|
||||
button.disabled = true;
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.add("is-running");
|
||||
@ -243,7 +359,7 @@
|
||||
const result = await connection.invoke("StartOnboardingProjectBuild", previewId);
|
||||
pendingBuildPreviewId = field(result, "previewID", "PreviewID") || previewId;
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = "Updating Word document with scene markers. Keep Word open while the document is saved.";
|
||||
node.textContent = "Updating Word document with scene markers. Keep Word open, then save the document when prompted.";
|
||||
});
|
||||
} catch (error) {
|
||||
button.disabled = false;
|
||||
@ -259,4 +375,8 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("[data-onboarding-build-save-confirm]").forEach((button) => {
|
||||
button.addEventListener("click", confirmManualSaveFromWeb);
|
||||
});
|
||||
})();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user