@model ImportIndexViewModel
@{
ViewData["Title"] = "JSON Import";
var preview = Model.Preview;
}
Tools
JSON Import
Paste or upload a Phase 1E package, preview it, confirm the summary, then import a new project.
@if (!string.IsNullOrWhiteSpace(Model.StatusMessage))
{
Import paused
@Model.StatusMessage
@if (preview is { Package: not null, HasDuplicateProjectTitle: true })
{
Duplicate imports will be renamed to @preview.DuplicateImportProjectTitle.
}
@if (!string.IsNullOrWhiteSpace(Model.TechnicalDetail))
{
Technical detail
@Model.TechnicalDetail
}
}
Preview
@(preview.Package?.Project.Title ?? "Import package")
@preview.BookCount books
@preview.ChapterCount chapters
@preview.SceneCount scenes
@preview.CharacterCount characters
@preview.LocationCount locations
@preview.SceneCharacterAppearanceCount appearances
@preview.PlotLineCount plot lines
@preview.PlotThreadCount threads
@preview.ResolvedThreadEventCount events
@preview.StoryAssetCount assets
@preview.ResolvedAssetStateCount asset states
@preview.ResolvedAssetEventCount asset events
@preview.ResolvedAssetCustodyCount custody links
@if (preview.Validation.Errors.Any())
{
Errors block import
@foreach (var error in preview.Validation.Errors)
{
- @error
}
}
@if (preview.Validation.Warnings.Any())
{
Warnings require confirmation
@foreach (var warning in preview.Validation.Warnings)
{
- @warning
}
}
@if (preview.Package is not null)
{
@if (preview.UnmatchedPovNames.Any() || preview.UnmatchedLocationNames.Any() || preview.UnmatchedSceneCharacterNames.Any() || preview.UnresolvedThreadEventReferences.Any() || preview.UnresolvedAssetReferences.Any() || preview.UnmatchedAssetOwnerNames.Any() || preview.UnmatchedAssetLocationNames.Any())
{
@if (preview.UnmatchedPovNames.Any())
{
Unmatched POV: @string.Join(", ", preview.UnmatchedPovNames)
}
@if (preview.UnmatchedLocationNames.Any())
{
Unmatched locations: @string.Join(", ", preview.UnmatchedLocationNames)
}
@if (preview.UnmatchedSceneCharacterNames.Any())
{
Unmatched scene characters: @string.Join(", ", preview.UnmatchedSceneCharacterNames)
}
@if (preview.UnresolvedThreadEventReferences.Any())
{
Unresolved thread events: @string.Join(", ", preview.UnresolvedThreadEventReferences)
}
@if (preview.UnresolvedAssetReferences.Any())
{
Unresolved asset references: @string.Join(", ", preview.UnresolvedAssetReferences)
}
@if (preview.UnmatchedAssetOwnerNames.Any())
{
Unmatched asset owners/events: @string.Join(", ", preview.UnmatchedAssetOwnerNames)
}
@if (preview.UnmatchedAssetLocationNames.Any())
{
Unmatched asset locations: @string.Join(", ", preview.UnmatchedAssetLocationNames)
}
}
@foreach (var bookPreview in preview.BookPreviews)
{
var book = bookPreview.Book;
Book @book.SeriesOrder: @(string.IsNullOrWhiteSpace(book.Subtitle) ? book.Title : $"{book.Title}: {book.Subtitle}")
@bookPreview.ChapterCount chapters / @bookPreview.SceneCount scenes
@foreach (var chapterPreview in bookPreview.ChapterPreviews)
{
var chapter = chapterPreview.Chapter;
Chapter @chapter.ChapterNumber: @chapter.Title
@chapterPreview.SceneCount scenes
@foreach (var scene in chapter.Scenes.OrderBy(x => x.Order))
{
-
Scene @scene.SceneNumber: @scene.Title
POV: @(scene.PovCharacterName ?? "Not set") /
Location: @(scene.LocationName ?? "Not set") /
Characters: @scene.SceneCharacters.Count
}
}
}
@if (preview.Package.PlotLines.Any())
{
@foreach (var plotLine in preview.Package.PlotLines)
{
Plot line: @(string.IsNullOrWhiteSpace(plotLine.DisplayName) ? plotLine.Name : plotLine.DisplayName)
@plotLine.Threads.Count threads / @plotLine.Threads.Sum(x => x.Events.Count) events
@foreach (var thread in plotLine.Threads)
{
@(string.IsNullOrWhiteSpace(thread.DisplayName) ? thread.Name : thread.DisplayName)
@thread.Events.Count events
}
}
}
@if (preview.Package.StoryAssets.Any())
{
@foreach (var asset in preview.Package.StoryAssets)
{
Asset: @(string.IsNullOrWhiteSpace(asset.DisplayName) ? asset.Name : asset.DisplayName)
@asset.States.Count states / @asset.Events.Count events
- Type: @(asset.Type ?? "Not set") / Initial owner: @(asset.InitialOwnerCharacterName ?? "Not set") / Initial location: @(asset.InitialLocationName ?? "Not set")
}
}
Confirm import
This will create @preview.Package.Project.Title with @preview.BookCount books, @preview.ChapterCount chapters, @preview.SceneCount scenes, @preview.CharacterCount characters, @preview.LocationCount locations, @preview.SceneCharacterAppearanceCount scene character appearances, @preview.PlotLineCount plot lines, @preview.PlotThreadCount plot threads, @preview.ResolvedThreadEventCount resolved thread events, @preview.StoryAssetCount story assets, @preview.ResolvedAssetStateCount resolved asset states, @preview.ResolvedAssetEventCount resolved asset events, and @preview.ResolvedAssetCustodyCount custody links.
@if (preview.HasDuplicateProjectTitle)
{
Because this title already exists, the created project will be named @preview.DuplicateImportProjectTitle if you continue.
}
}
}
@section Scripts {
}