Phase 20G – Onboarding Experience Polish.
This commit is contained in:
parent
6cd452018c
commit
e3eb5d3528
@ -5,10 +5,22 @@
|
||||
|
||||
<section class="onboarding-shell" aria-labelledby="build-complete-title">
|
||||
<div class="onboarding-panel onboarding-review-panel">
|
||||
<ol class="onboarding-stepper onboarding-stepper--complete" aria-label="Story setup journey">
|
||||
@foreach (var label in new[] { "Welcome", "Writing Preferences", "Project", "Book", "Connect Word", "Scan", "Review", "Build Project", "Complete" })
|
||||
{
|
||||
<li class="is-complete">
|
||||
<span></span>
|
||||
<strong>@label</strong>
|
||||
</li>
|
||||
}
|
||||
</ol>
|
||||
<div class="onboarding-copy">
|
||||
<p class="eyebrow">Build Project</p>
|
||||
<h1 id="build-complete-title">Your project structure has been created.</h1>
|
||||
<p>@(Model.AlreadyBuilt ? "This manuscript has already been built into PlotDirector." : "PlotDirector has created the approved chapters, scenes and characters.")</p>
|
||||
<div class="onboarding-success-heading">
|
||||
<span aria-hidden="true">✓</span>
|
||||
<h1 id="build-complete-title">Your project structure has been created.</h1>
|
||||
</div>
|
||||
<p>@(Model.AlreadyBuilt ? "This manuscript has already been built into PlotDirector, so nothing was duplicated." : "PlotDirector created the approved chapters, scenes, characters and scene appearances.")</p>
|
||||
@if (!string.IsNullOrWhiteSpace(Model.MarkerWarning))
|
||||
{
|
||||
<p class="text-warning">@Model.MarkerWarning</p>
|
||||
@ -34,6 +46,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="onboarding-complete-next">
|
||||
<h2>Ready for your next pass</h2>
|
||||
<p>Your project now has a working story map. Open the overview to inspect the structure, or head straight into the writer workspace to keep drafting.</p>
|
||||
</section>
|
||||
|
||||
<div class="onboarding-actions">
|
||||
<a class="btn btn-primary" asp-controller="Projects" asp-action="Details" asp-route-id="@Model.ProjectID">Open Project Overview</a>
|
||||
<a class="btn btn-outline-primary" asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.ProjectID">Open Writer Workspace</a>
|
||||
|
||||
@ -2,6 +2,19 @@
|
||||
@using PlotLine.Models
|
||||
@{
|
||||
ViewData["Title"] = "Set up PlotDirector";
|
||||
var currentJourneyOrder = CurrentJourneyOrder(Model);
|
||||
var journeySteps = new[]
|
||||
{
|
||||
new { Label = "Welcome", Order = 1 },
|
||||
new { Label = "Writing Preferences", Order = 2 },
|
||||
new { Label = "Project", Order = 3 },
|
||||
new { Label = "Book", Order = 4 },
|
||||
new { Label = "Connect Word", Order = 5 },
|
||||
new { Label = "Scan", Order = 6 },
|
||||
new { Label = "Review", Order = 7 },
|
||||
new { Label = "Build Project", Order = 8 },
|
||||
new { Label = "Complete", Order = 9 }
|
||||
};
|
||||
}
|
||||
|
||||
<section class="onboarding-shell" aria-labelledby="onboarding-title">
|
||||
@ -12,6 +25,15 @@
|
||||
<span style="width:@((Model.StepNumber * 100) / Model.TotalSteps)%"></span>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="onboarding-stepper" aria-label="Story setup journey">
|
||||
@foreach (var step in journeySteps)
|
||||
{
|
||||
<li class="@JourneyStepClass(step.Order, currentJourneyOrder)">
|
||||
<span>@step.Order</span>
|
||||
<strong>@step.Label</strong>
|
||||
</li>
|
||||
}
|
||||
</ol>
|
||||
|
||||
@if (Model.CurrentStep == OnboardingSteps.Welcome)
|
||||
{
|
||||
@ -237,7 +259,7 @@
|
||||
@if (Model.IsMicrosoftWordPath)
|
||||
{
|
||||
<h1 id="onboarding-title">Connect your Word Companion</h1>
|
||||
<p>Open Microsoft Word, open your manuscript, start the PlotDirector Word Companion, and sign in using your PlotDirector account.</p>
|
||||
<p>Open Microsoft Word, open your manuscript, start the PlotDirector Word Companion, and sign in using your PlotDirector account. PlotDirector will stay on this page with you while the scan and build run.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -315,14 +337,22 @@
|
||||
</div>
|
||||
@if (string.Equals(Model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal))
|
||||
{
|
||||
<p class="onboarding-scan-next">Next: build project structure.</p>
|
||||
<div class="onboarding-build-panel" data-onboarding-build-panel>
|
||||
<div>
|
||||
<p class="onboarding-scan-next">Review saved. PlotDirector can now create the approved structure.</p>
|
||||
<p class="onboarding-build-message" data-onboarding-build-message>Ready to build chapters, scenes, characters and scene appearances.</p>
|
||||
</div>
|
||||
<strong data-onboarding-build-percent></strong>
|
||||
<div class="onboarding-scan-progress onboarding-build-progress" aria-hidden="true">
|
||||
<span data-onboarding-build-progress></span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-success"
|
||||
type="button"
|
||||
data-onboarding-build-start
|
||||
data-preview-id="@Model.ScanState.PreviewID">
|
||||
Build Project
|
||||
</button>
|
||||
<p class="onboarding-scan-next" data-onboarding-build-message></p>
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
@ -437,4 +467,33 @@
|
||||
|
||||
private static string ScanPercent(ManuscriptScanStateViewModel scan)
|
||||
=> scan.PercentComplete.HasValue ? $"{scan.PercentComplete.Value}%" : string.Empty;
|
||||
|
||||
private static int CurrentJourneyOrder(OnboardingWizardViewModel model)
|
||||
{
|
||||
return model.CurrentStep switch
|
||||
{
|
||||
OnboardingSteps.Welcome => 1,
|
||||
OnboardingSteps.WritingJourney or OnboardingSteps.WritingSoftware => 2,
|
||||
OnboardingSteps.Project => 3,
|
||||
OnboardingSteps.Book => 4,
|
||||
OnboardingSteps.NextPathPreview when !model.IsMicrosoftWordPath => 9,
|
||||
OnboardingSteps.NextPathPreview when string.Equals(model.ScanState.ReviewStatus, ManuscriptScanReviewStatuses.ReadyToImport, StringComparison.Ordinal) => 8,
|
||||
OnboardingSteps.NextPathPreview when model.ScanState.IsComplete => 7,
|
||||
OnboardingSteps.NextPathPreview when model.ScanState.IsRunning || model.ScanState.IsFailed || model.ScanState.PercentComplete.HasValue => 6,
|
||||
OnboardingSteps.NextPathPreview when model.CompanionPresence.IsConnected => 6,
|
||||
OnboardingSteps.NextPathPreview => 5,
|
||||
OnboardingSteps.Complete => 9,
|
||||
_ => 1
|
||||
};
|
||||
}
|
||||
|
||||
private static string JourneyStepClass(int order, int currentOrder)
|
||||
{
|
||||
if (order < currentOrder)
|
||||
{
|
||||
return "is-complete";
|
||||
}
|
||||
|
||||
return order == currentOrder ? "is-current" : "is-upcoming";
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
<div class="onboarding-copy">
|
||||
<p class="eyebrow">@Model.SelectedBookTitle</p>
|
||||
<h1 id="scan-review-title">Review manuscript scan</h1>
|
||||
<p>Nothing has been added to your project yet. Review the detected structure, then continue when you're happy.</p>
|
||||
<p>You can tidy this up now, or import the structure and refine it later.</p>
|
||||
<p>Nothing has been added to your project yet. Choose the chapters, scenes and character candidates that should become your first PlotDirector structure.</p>
|
||||
<p>You can keep this light now and refine everything later inside the project.</p>
|
||||
</div>
|
||||
|
||||
@if (TempData["OnboardingReviewMessage"] is string reviewMessage)
|
||||
@ -145,11 +145,16 @@
|
||||
<h2>Character candidates</h2>
|
||||
@if (!probableCharacters.Any() && !possibleCharacters.Any() && !relationshipTitles.Any())
|
||||
{
|
||||
<p>No repeated character names were found yet.</p>
|
||||
<p>No repeated character names were found yet. You can still build the project structure and add characters later.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
var characterIndex = 0;
|
||||
<label class="onboarding-character-filter">
|
||||
Find a candidate
|
||||
<input class="form-control" type="search" placeholder="Search names or notes" data-character-filter />
|
||||
</label>
|
||||
<p class="onboarding-empty-state" data-character-empty hidden>No matching candidates.</p>
|
||||
<div class="onboarding-character-groups">
|
||||
@foreach (var group in new[]
|
||||
{
|
||||
@ -168,7 +173,7 @@
|
||||
<ul class="onboarding-character-candidates">
|
||||
@foreach (var candidate in group.Candidates)
|
||||
{
|
||||
<li>
|
||||
<li data-character-name="@candidate.ReviewName" data-character-reason="@candidate.Reason">
|
||||
<input type="hidden" name="Characters[@characterIndex].TemporaryCharacterKey" value="@candidate.TemporaryCharacterKey" />
|
||||
<input type="hidden" name="Characters[@characterIndex].Category" value="@candidate.Category" />
|
||||
<label class="onboarding-review-toggle">
|
||||
@ -214,7 +219,7 @@
|
||||
<ul class="onboarding-character-candidates">
|
||||
@foreach (var candidate in excludedCharacters)
|
||||
{
|
||||
<li>
|
||||
<li data-character-name="@candidate.ReviewName" data-character-reason="@candidate.Reason">
|
||||
<input type="hidden" name="Characters[@characterIndex].TemporaryCharacterKey" value="@candidate.TemporaryCharacterKey" />
|
||||
<input type="hidden" name="Characters[@characterIndex].Category" value="@candidate.Category" />
|
||||
<label class="onboarding-review-toggle">
|
||||
@ -262,7 +267,8 @@
|
||||
</section>
|
||||
|
||||
<script>
|
||||
document.querySelector("[data-review-tools]")?.addEventListener("click", (event) => {
|
||||
const reviewTools = document.querySelector("[data-review-tools]");
|
||||
reviewTools?.addEventListener("click", (event) => {
|
||||
const button = event.target.closest("[data-bulk-target]");
|
||||
if (!button) {
|
||||
return;
|
||||
@ -274,4 +280,28 @@
|
||||
checkbox.checked = checked;
|
||||
});
|
||||
});
|
||||
|
||||
const characterFilter = document.querySelector("[data-character-filter]");
|
||||
characterFilter?.addEventListener("input", () => {
|
||||
const query = characterFilter.value.trim().toLowerCase();
|
||||
let visibleCount = 0;
|
||||
document.querySelectorAll("[data-character-name]").forEach((item) => {
|
||||
const text = `${item.dataset.characterName || ""} ${item.dataset.characterReason || ""}`.toLowerCase();
|
||||
const isVisible = query.length === 0 || text.includes(query);
|
||||
item.hidden = !isVisible;
|
||||
if (isVisible) {
|
||||
visibleCount++;
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll(".onboarding-character-groups section").forEach((section) => {
|
||||
const hasVisibleItems = [...section.querySelectorAll("[data-character-name]")].some((item) => !item.hidden);
|
||||
section.hidden = !hasVisibleItems;
|
||||
});
|
||||
|
||||
const emptyState = document.querySelector("[data-character-empty]");
|
||||
if (emptyState) {
|
||||
emptyState.hidden = visibleCount > 0;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -36,6 +36,98 @@
|
||||
background: var(--bs-primary);
|
||||
}
|
||||
|
||||
.onboarding-stepper {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(9, minmax(0, 1fr));
|
||||
gap: .45rem;
|
||||
margin: 0 0 2rem;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.onboarding-stepper li {
|
||||
position: relative;
|
||||
display: grid;
|
||||
gap: .35rem;
|
||||
min-width: 0;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
.onboarding-stepper li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: .7rem;
|
||||
left: calc(-50% + .7rem);
|
||||
width: calc(100% - .45rem);
|
||||
height: 2px;
|
||||
background: rgba(31, 42, 68, .14);
|
||||
}
|
||||
|
||||
.onboarding-stepper li:first-child::before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.onboarding-stepper span {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 1.45rem;
|
||||
aspect-ratio: 1;
|
||||
border: 1px solid rgba(31, 42, 68, .18);
|
||||
border-radius: 50%;
|
||||
background: var(--bs-body-bg);
|
||||
color: var(--bs-secondary-color);
|
||||
font-size: .72rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.onboarding-stepper strong {
|
||||
overflow-wrap: anywhere;
|
||||
font-size: .72rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-complete,
|
||||
.onboarding-stepper .is-current {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-complete::before,
|
||||
.onboarding-stepper .is-current::before {
|
||||
background: rgba(47, 111, 99, .38);
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-complete span {
|
||||
border-color: #2f6f63;
|
||||
background: #2f6f63;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-complete span::before {
|
||||
content: "";
|
||||
width: .45rem;
|
||||
height: .7rem;
|
||||
border: solid currentColor;
|
||||
border-width: 0 2px 2px 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-complete span {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.onboarding-stepper .is-current span {
|
||||
border-color: #b68a46;
|
||||
box-shadow: 0 0 0 .22rem rgba(182, 138, 70, .18);
|
||||
color: #755624;
|
||||
}
|
||||
|
||||
.onboarding-stepper--complete .is-complete:last-child span {
|
||||
border-color: #b68a46;
|
||||
background: #b68a46;
|
||||
}
|
||||
|
||||
.onboarding-copy {
|
||||
max-width: 680px;
|
||||
margin-bottom: 1.5rem;
|
||||
@ -315,6 +407,35 @@
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.onboarding-build-panel {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: .55rem .85rem;
|
||||
align-items: center;
|
||||
padding: .85rem;
|
||||
border: 1px solid rgba(47, 111, 99, .18);
|
||||
border-radius: 8px;
|
||||
background: rgba(47, 111, 99, .07);
|
||||
}
|
||||
|
||||
.onboarding-build-panel .onboarding-scan-progress {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.onboarding-build-message {
|
||||
margin: .2rem 0 0;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
.onboarding-build-panel > strong {
|
||||
color: #2f6f63;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.onboarding-build-panel.is-running {
|
||||
border-color: rgba(47, 111, 99, .34);
|
||||
}
|
||||
|
||||
.onboarding-review-panel {
|
||||
width: min(1120px, 100%);
|
||||
}
|
||||
@ -323,6 +444,13 @@
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.onboarding-review-panel .onboarding-review-counts {
|
||||
position: sticky;
|
||||
top: .75rem;
|
||||
z-index: 2;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.onboarding-review-tools {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -347,6 +475,22 @@
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.onboarding-character-filter {
|
||||
display: grid;
|
||||
gap: .35rem;
|
||||
color: var(--bs-secondary-color);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.onboarding-empty-state {
|
||||
margin: 0;
|
||||
padding: .8rem;
|
||||
border: 1px dashed rgba(31, 42, 68, .2);
|
||||
border-radius: 8px;
|
||||
color: var(--bs-secondary-color);
|
||||
background: rgba(255, 255, 255, .55);
|
||||
}
|
||||
|
||||
.onboarding-review-chapters {
|
||||
display: grid;
|
||||
gap: .85rem;
|
||||
@ -464,6 +608,48 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.onboarding-success-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .9rem;
|
||||
}
|
||||
|
||||
.onboarding-success-heading span {
|
||||
flex: 0 0 auto;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 3rem;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 50%;
|
||||
background: #2f6f63;
|
||||
color: #fff;
|
||||
font-size: 1.55rem;
|
||||
font-weight: 800;
|
||||
box-shadow: 0 0 0 .38rem rgba(47, 111, 99, .12);
|
||||
}
|
||||
|
||||
.onboarding-success-heading h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.onboarding-complete-next {
|
||||
margin-top: 1.25rem;
|
||||
padding: 1rem;
|
||||
border: 1px solid rgba(31, 42, 68, .12);
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, .58);
|
||||
}
|
||||
|
||||
.onboarding-complete-next h2 {
|
||||
margin: 0 0 .35rem;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.onboarding-complete-next p {
|
||||
margin: 0;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
.onboarding-dashboard-nudge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -533,6 +719,28 @@
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.onboarding-shell {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.onboarding-stepper {
|
||||
display: flex;
|
||||
gap: .75rem;
|
||||
overflow-x: auto;
|
||||
padding-bottom: .35rem;
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
|
||||
.onboarding-stepper li {
|
||||
flex: 0 0 7.2rem;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.onboarding-stepper li::before {
|
||||
width: 6rem;
|
||||
left: -6.35rem;
|
||||
}
|
||||
|
||||
.onboarding-dashboard-nudge,
|
||||
.onboarding-companion-card,
|
||||
.onboarding-review-grid,
|
||||
@ -549,4 +757,18 @@
|
||||
.onboarding-scan-counts {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.onboarding-review-panel .onboarding-review-counts {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.onboarding-build-panel,
|
||||
.onboarding-success-heading {
|
||||
grid-template-columns: 1fr;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.onboarding-success-heading {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,9 +54,9 @@
|
||||
} else if (!documentOpen) {
|
||||
node.textContent = "Open your manuscript in Word, then the scan button will appear.";
|
||||
} else if (currentScanStatus === "Complete") {
|
||||
node.textContent = "Scan complete. Review the structure before anything is imported.";
|
||||
node.textContent = "Your scan is ready. Review what PlotDirector found before anything is imported.";
|
||||
} else if (currentScanStatus === "Running") {
|
||||
node.textContent = "The Companion is scanning your manuscript now.";
|
||||
node.textContent = "The Companion is reading your manuscript and sending structure back to PlotDirector.";
|
||||
} else {
|
||||
node.textContent = "Your Companion is connected. Scan your manuscript when you are ready.";
|
||||
}
|
||||
@ -97,7 +97,7 @@
|
||||
|
||||
const status = field(state, "status", "Status") || "NotStarted";
|
||||
currentScanStatus = status;
|
||||
const message = field(state, "message", "Message") || (status === "Complete" ? "We found:" : "Ready to scan");
|
||||
const message = field(state, "message", "Message") || (status === "Complete" ? "Scan complete. Review what PlotDirector found." : "Ready to scan");
|
||||
const percent = field(state, "percentComplete", "PercentComplete");
|
||||
const previewId = field(state, "previewID", "PreviewID") || field(state, "previewId", "PreviewId");
|
||||
const panel = document.querySelector("[data-onboarding-scan-panel]");
|
||||
@ -150,9 +150,19 @@
|
||||
connection.on("OnboardingScanFailed", applyScanState);
|
||||
connection.on("OnboardingBuildProgress", (state) => {
|
||||
const message = field(state, "message", "Message") || "Building project structure...";
|
||||
const percent = field(state, "percentComplete", "PercentComplete");
|
||||
const safePercent = Math.max(0, Math.min(100, Number.parseInt(percent || "0", 10) || 0));
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.add("is-running");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
const percent = field(state, "percentComplete", "PercentComplete");
|
||||
node.textContent = percent === null || percent === undefined ? message : `${message} ${percent}%`;
|
||||
node.textContent = message;
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-percent]").forEach((node) => {
|
||||
node.textContent = percent === null || percent === undefined ? "" : `${percent}%`;
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-progress]").forEach((node) => {
|
||||
node.style.width = `${safePercent}%`;
|
||||
});
|
||||
});
|
||||
connection.on("OnboardingBuildCompleted", (result) => {
|
||||
@ -193,8 +203,17 @@
|
||||
return;
|
||||
}
|
||||
button.disabled = true;
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.add("is-running");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = "Creating chapters...";
|
||||
node.textContent = "Creating the approved project structure...";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-percent]").forEach((node) => {
|
||||
node.textContent = "0%";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-progress]").forEach((node) => {
|
||||
node.style.width = "0%";
|
||||
});
|
||||
try {
|
||||
const result = await connection.invoke("StartOnboardingProjectBuild", previewId);
|
||||
@ -202,9 +221,15 @@
|
||||
window.location.href = `/onboarding/build-complete?previewId=${encodeURIComponent(returnedPreviewId)}`;
|
||||
} catch (error) {
|
||||
button.disabled = false;
|
||||
document.querySelectorAll("[data-onboarding-build-panel]").forEach((node) => {
|
||||
node.classList.remove("is-running");
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-message]").forEach((node) => {
|
||||
node.textContent = error?.message || "The project structure could not be built. Check the review and try again.";
|
||||
});
|
||||
document.querySelectorAll("[data-onboarding-build-percent]").forEach((node) => {
|
||||
node.textContent = "";
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user