1300 lines
78 KiB
Plaintext
1300 lines
78 KiB
Plaintext
@model SceneEditViewModel
|
|
@{
|
|
var revisionStatus = Model.RevisionStatuses.FirstOrDefault(x => x.Value == Model.RevisionStatusID.ToString())?.Text ?? "Not set";
|
|
var primaryLocation = Model.LocationOptions.FirstOrDefault(x => x.Value == Model.PrimaryLocationID?.ToString())?.Text ?? "No primary location";
|
|
var povCharacter = Model.SceneCharacters.FirstOrDefault(x => x.RoleInSceneTypeName?.Contains("POV", StringComparison.OrdinalIgnoreCase) == true)?.CharacterName
|
|
?? Model.SceneCharacters.FirstOrDefault()?.CharacterName
|
|
?? "No POV";
|
|
var timeLabel = !string.IsNullOrWhiteSpace(Model.RelativeTimeText)
|
|
? Model.RelativeTimeText
|
|
: Model.StartDateTime?.ToString("dd MMM yyyy HH:mm")
|
|
?? Model.StartDateTime?.ToString("dd MMM yyyy")
|
|
?? "Time not set";
|
|
var selectedPurposeLabels = Model.ScenePurposeTypes
|
|
.Where(x => Model.SelectedPurposeTypeIds.Contains(x.ScenePurposeTypeID))
|
|
.Select(x => x.PurposeName)
|
|
.ToList();
|
|
var dependencyCount = Model.DependenciesThisSceneNeeds.Count + Model.DependenciesNeedingThisScene.Count;
|
|
}
|
|
|
|
<div class="scene-inspector-root">
|
|
<section class="inspector-section scene-overview-card" data-section-title="Overview" data-section-id="inspector-overview" data-inspector-search-text="@($"{Model.SceneTitle} {povCharacter} {primaryLocation} {timeLabel} {revisionStatus} {string.Join(' ', selectedPurposeLabels)}")">
|
|
<div>
|
|
<p class="eyebrow">Working context</p>
|
|
<h3>@(string.IsNullOrWhiteSpace(Model.SceneTitle) ? "Untitled scene" : Model.SceneTitle)</h3>
|
|
<p class="muted">
|
|
@if (Model.Chapter is not null)
|
|
{
|
|
<span>Chapter @Model.Chapter.ChapterNumber</span>
|
|
}
|
|
<span>Scene @Model.SceneNumber</span>
|
|
<span>@povCharacter</span>
|
|
<span>@primaryLocation</span>
|
|
</p>
|
|
</div>
|
|
<div class="overview-chip-grid">
|
|
<span class="overview-chip">@revisionStatus</span>
|
|
<span class="overview-chip">@timeLabel</span>
|
|
<span class="overview-chip @(Model.Warnings.Any() ? "attention" : "")">@Model.Warnings.Count warning@(Model.Warnings.Count == 1 ? "" : "s")</span>
|
|
<span class="overview-chip">@Model.SceneCharacters.Count character@(Model.SceneCharacters.Count == 1 ? "" : "s")</span>
|
|
<span class="overview-chip">@Model.AssetEvents.Count asset event@(Model.AssetEvents.Count == 1 ? "" : "s")</span>
|
|
<span class="overview-chip">@Model.ThreadEvents.Count thread event@(Model.ThreadEvents.Count == 1 ? "" : "s")</span>
|
|
<span class="overview-chip">@dependencyCount dependenc@(dependencyCount == 1 ? "y" : "ies")</span>
|
|
</div>
|
|
@if (selectedPurposeLabels.Any())
|
|
{
|
|
<div class="purpose-chip-row">
|
|
@foreach (var purpose in selectedPurposeLabels)
|
|
{
|
|
<span class="purpose-chip">@purpose</span>
|
|
}
|
|
</div>
|
|
}
|
|
@if (!string.IsNullOrWhiteSpace(Model.SceneOutcomeNotes))
|
|
{
|
|
<p class="overview-outcome">@Model.SceneOutcomeNotes</p>
|
|
}
|
|
</section>
|
|
|
|
<div class="inspector-quick-nav" data-inspector-nav>
|
|
<input class="form-control form-control-sm inspector-search" type="search" placeholder="Find in scene..." data-inspector-search />
|
|
<div class="inspector-nav-links">
|
|
<a href="#inspector-overview">Overview</a>
|
|
<a href="#inspector-timing">Time</a>
|
|
<a href="#inspector-purpose">Purpose</a>
|
|
<a href="#inspector-metrics">Metrics</a>
|
|
<a href="#inspector-writer">Writer</a>
|
|
<a href="#inspector-notes">Notes</a>
|
|
<a href="#inspector-checklist">Checklist</a>
|
|
<a href="#inspector-attachments">Attachments</a>
|
|
<a href="#inspector-warnings">Warnings</a>
|
|
<a href="#inspector-dependencies">Dependencies</a>
|
|
<a href="#inspector-move">Move</a>
|
|
<a href="#inspector-thread-events">Threads</a>
|
|
<a href="#inspector-asset-events">Assets</a>
|
|
<a href="#inspector-asset-locations">Locations</a>
|
|
<a href="#inspector-asset-custody">Custody</a>
|
|
<a href="#inspector-characters">Characters</a>
|
|
<a href="#inspector-character-attributes">Attributes</a>
|
|
<a href="#inspector-character-knowledge">Knowledge</a>
|
|
<a href="#inspector-relationships">Relationships</a>
|
|
</div>
|
|
</div>
|
|
|
|
<form asp-controller="Scenes" asp-action="Save" method="post" class="scene-inspector-form">
|
|
<input asp-for="SceneID" type="hidden" />
|
|
<input asp-for="ChapterID" type="hidden" />
|
|
<input asp-for="ReturnProjectID" type="hidden" />
|
|
<input asp-for="ReturnBookID" type="hidden" />
|
|
<input asp-for="ReturnToTimeline" type="hidden" />
|
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
|
|
|
<div class="inspector-section" data-section-title="Timing & Structure" data-section-id="inspector-timing">
|
|
<h3>Timing & Structure</h3>
|
|
<div class="row g-2">
|
|
<div class="col-4">
|
|
<label asp-for="SceneNumber" class="form-label"></label>
|
|
<input asp-for="SceneNumber" class="form-control form-control-sm" />
|
|
</div>
|
|
<div class="col-8">
|
|
<label asp-for="RevisionStatusID" class="form-label"></label>
|
|
<select asp-for="RevisionStatusID" asp-items="Model.RevisionStatuses" class="form-select form-select-sm"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label asp-for="SceneTitle" class="form-label"></label>
|
|
<input asp-for="SceneTitle" class="form-control" />
|
|
<span asp-validation-for="SceneTitle" class="text-danger"></span>
|
|
</div>
|
|
<div class="col-12">
|
|
<label asp-for="Summary" class="form-label"></label>
|
|
<textarea asp-for="Summary" class="form-control" rows="4"></textarea>
|
|
</div>
|
|
<div class="col-12">
|
|
<label asp-for="PrimaryLocationID" class="form-label"></label>
|
|
<select asp-for="PrimaryLocationID" asp-items="Model.LocationOptions" class="form-select form-select-sm">
|
|
<option value="">No primary location</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
@if (Model.LocationConsistencyMessages.Any())
|
|
{
|
|
<div class="location-helper mt-2">
|
|
<h3>Location checks</h3>
|
|
<ul class="location-warning-list">
|
|
@foreach (var message in Model.LocationConsistencyMessages)
|
|
{
|
|
<li>@message</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
}
|
|
|
|
<h4 class="inspector-subheading">Time</h4>
|
|
<div class="row g-2">
|
|
<div class="col-sm-6">
|
|
<label asp-for="TimeModeID" class="form-label"></label>
|
|
<select asp-for="TimeModeID" asp-items="Model.TimeModes" class="form-select form-select-sm"></select>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label asp-for="TimeConfidenceID" class="form-label"></label>
|
|
<select asp-for="TimeConfidenceID" asp-items="Model.TimeConfidences" class="form-select form-select-sm"></select>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label asp-for="StartDateTime" class="form-label"></label>
|
|
<input asp-for="StartDateTime" class="form-control form-control-sm" />
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label asp-for="EndDateTime" class="form-label"></label>
|
|
<input asp-for="EndDateTime" class="form-control form-control-sm" />
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<label asp-for="DurationAmount" class="form-label"></label>
|
|
<input asp-for="DurationAmount" class="form-control form-control-sm" />
|
|
</div>
|
|
<div class="col-sm-8">
|
|
<label asp-for="DurationUnitID" class="form-label"></label>
|
|
<select asp-for="DurationUnitID" asp-items="Model.DurationUnits" class="form-select form-select-sm">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label asp-for="RelativeTimeText" class="form-label"></label>
|
|
<input asp-for="RelativeTimeText" class="form-control form-control-sm" placeholder="e.g. Two days later" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="inspector-section" data-section-title="Scene Purpose & Outcome" data-section-id="inspector-purpose">
|
|
<h3>Purposes</h3>
|
|
<div class="purpose-list inspector-purpose-list">
|
|
@foreach (var purpose in Model.ScenePurposeTypes)
|
|
{
|
|
<label class="purpose-check">
|
|
@if (Model.SelectedPurposeTypeIds.Contains(purpose.ScenePurposeTypeID))
|
|
{
|
|
<input type="checkbox" name="SelectedPurposeTypeIds" value="@purpose.ScenePurposeTypeID" checked />
|
|
}
|
|
else
|
|
{
|
|
<input type="checkbox" name="SelectedPurposeTypeIds" value="@purpose.ScenePurposeTypeID" />
|
|
}
|
|
<span>@purpose.PurposeName</span>
|
|
</label>
|
|
}
|
|
</div>
|
|
|
|
<div class="purpose-notes-block mt-2">
|
|
<h3>Notes</h3>
|
|
<label asp-for="ScenePurposeNotes" class="form-label"></label>
|
|
<textarea asp-for="ScenePurposeNotes" class="form-control mb-2" rows="4"></textarea>
|
|
<label asp-for="SceneOutcomeNotes" class="form-label"></label>
|
|
<textarea asp-for="SceneOutcomeNotes" class="form-control" rows="4"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="inspector-section" data-section-title="Scene Metrics" data-section-id="inspector-metrics">
|
|
<h3>Scene Metrics</h3>
|
|
@if (!Model.Metrics.Any())
|
|
{
|
|
<div class="empty-panel compact">
|
|
<p>This project has no scene metrics yet.</p>
|
|
@if (Model.ReturnProjectID.HasValue)
|
|
{
|
|
<a class="btn btn-outline-primary btn-sm" asp-controller="ProjectMetrics" asp-action="Index" asp-route-projectId="@Model.ReturnProjectID">Add default metrics</a>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="metric-slider-stack">
|
|
@for (var index = 0; index < Model.Metrics.Count; index++)
|
|
{
|
|
<div class="metric-slider">
|
|
<input asp-for="Metrics[index].MetricTypeID" type="hidden" />
|
|
<input asp-for="Metrics[index].MetricName" type="hidden" />
|
|
<input asp-for="Metrics[index].Description" type="hidden" />
|
|
<input asp-for="Metrics[index].MinValue" type="hidden" />
|
|
<input asp-for="Metrics[index].MaxValue" type="hidden" />
|
|
<div class="metric-slider-label">
|
|
<label asp-for="Metrics[index].Value">@Model.Metrics[index].MetricName</label>
|
|
<output>@Model.Metrics[index].Value</output>
|
|
</div>
|
|
<input asp-for="Metrics[index].Value" type="range" min="@Model.Metrics[index].MinValue" max="@Model.Metrics[index].MaxValue" class="form-range" oninput="this.previousElementSibling.querySelector('output').value = this.value" />
|
|
<input asp-for="Metrics[index].Notes" class="form-control form-control-sm" placeholder="Metric note" />
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<div class="inspector-actions">
|
|
<button class="btn btn-primary" type="submit">Save scene</button>
|
|
@if (!Model.ReturnToTimeline)
|
|
{
|
|
<a class="btn btn-outline-secondary" asp-controller="Chapters" asp-action="Details" asp-route-id="@Model.ChapterID">Back to chapter</a>
|
|
}
|
|
</div>
|
|
</form>
|
|
|
|
@if (Model.SceneID > 0)
|
|
{
|
|
<form asp-controller="Scenes" asp-action="Archive" method="post" class="inspector-archive-form archive-button-form mt-2" data-confirm-message="Archive this scene? This will hide it from active lists and timelines, but the data will be kept and can be restored later.">
|
|
<input type="hidden" name="id" value="@Model.SceneID" />
|
|
<input type="hidden" name="chapterId" value="@Model.ChapterID" />
|
|
<button class="btn btn-outline-danger btn-sm" type="submit">Archive Scene</button>
|
|
</form>
|
|
}
|
|
|
|
@if (TempData["WriterWorkspaceError"] is string writerWorkspaceError)
|
|
{
|
|
<div class="alert alert-warning">@writerWorkspaceError</div>
|
|
}
|
|
|
|
<section class="inspector-section writer-workspace-section" data-section-title="Writer Workspace" data-section-id="inspector-writer">
|
|
<div class="inspector-section-heading">
|
|
<h3>Writer Workspace</h3>
|
|
<a class="btn btn-outline-secondary btn-sm" asp-controller="Writer" asp-action="Chapter" asp-route-id="@Model.ChapterID">Chapter workflow</a>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="SaveWorkflow" method="post" class="writer-workspace-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="DraftStatus">Draft status</label>
|
|
<select class="form-select form-select-sm" id="DraftStatus" name="DraftStatus" asp-items="Model.DraftStatusOptions"></select>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="Priority">Priority</label>
|
|
<input class="form-control form-control-sm" id="Priority" name="Priority" type="number" min="1" max="10" value="@Model.Workflow.Priority" />
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="EstimatedWordCount">Estimated words</label>
|
|
<input class="form-control form-control-sm" id="EstimatedWordCount" name="EstimatedWordCount" type="number" min="0" value="@Model.Workflow.EstimatedWordCount" />
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="ActualWordCount">Actual words</label>
|
|
<input class="form-control form-control-sm" id="ActualWordCount" name="ActualWordCount" type="number" min="0" value="@Model.Workflow.ActualWordCount" />
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="DraftedDate">Drafted date</label>
|
|
<input class="form-control form-control-sm" id="DraftedDate" name="DraftedDate" type="date" value="@Model.Workflow.DraftedDate?.ToString("yyyy-MM-dd")" />
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label class="form-label" for="LastWorkedOn">Last worked on</label>
|
|
<input class="form-control form-control-sm" id="LastWorkedOn" name="LastWorkedOn" type="date" value="@Model.Workflow.LastWorkedOn?.ToString("yyyy-MM-dd")" />
|
|
</div>
|
|
<div class="col-12 writer-checkbox-grid">
|
|
<label><input type="checkbox" name="ReadyForDraft" value="true" checked="@Model.Workflow.ReadyForDraft" /> Ready for draft</label>
|
|
<label><input type="checkbox" name="ReadyForRevision" value="true" checked="@Model.Workflow.ReadyForRevision" /> Ready for revision</label>
|
|
<label><input type="checkbox" name="ReadyForPolish" value="true" checked="@Model.Workflow.ReadyForPolish" /> Ready for polish</label>
|
|
<label><input type="checkbox" name="IsBlocked" value="true" checked="@Model.Workflow.IsBlocked" /> Blocked</label>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="BlockedReason">Blocked reason</label>
|
|
<input class="form-control form-control-sm" id="BlockedReason" name="BlockedReason" value="@Model.Workflow.BlockedReason" />
|
|
</div>
|
|
</div>
|
|
<div class="button-row compact-buttons mt-2">
|
|
<button class="btn btn-primary btn-sm" type="submit">Save workflow</button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section writer-notes-section" data-section-title="Scene Notes" data-section-id="inspector-notes">
|
|
<h3>Scene Notes</h3>
|
|
@if (!Model.Notes.Any())
|
|
{
|
|
<p class="muted">No working notes yet. Capture drafting thoughts, research reminders, or revision questions as they come up.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="writer-note-list">
|
|
@foreach (var note in Model.Notes)
|
|
{
|
|
<details class="writer-mini-card" @(note.IsPinned ? "open" : "")>
|
|
<summary>
|
|
<span class="status-pill">@note.TypeName</span>
|
|
<strong>@(string.IsNullOrWhiteSpace(note.NoteTitle) ? note.NoteText : note.NoteTitle)</strong>
|
|
@if (note.IsPinned) { <span class="badge text-bg-light">Pinned</span> }
|
|
@if (note.IsResolved) { <span class="badge text-bg-success">Resolved</span> }
|
|
</summary>
|
|
<form asp-controller="Scenes" asp-action="SaveNote" method="post" class="writer-edit-form">
|
|
<input type="hidden" name="SceneNoteID" value="@note.SceneNoteID" />
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<select class="form-select form-select-sm" name="SceneNoteTypeID">
|
|
@foreach (var option in Model.SceneNoteTypeOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == note.SceneNoteTypeID.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
<input class="form-control form-control-sm" name="NoteTitle" value="@note.NoteTitle" placeholder="Title" />
|
|
<textarea class="form-control form-control-sm" name="NoteText" rows="3">@note.NoteText</textarea>
|
|
<div class="writer-checkbox-grid">
|
|
<label><input type="checkbox" name="IsPinned" value="true" checked="@note.IsPinned" /> Pinned</label>
|
|
<label><input type="checkbox" name="IsResolved" value="true" checked="@note.IsResolved" /> Resolved</label>
|
|
</div>
|
|
<div class="button-row compact-buttons">
|
|
<button class="btn btn-primary btn-sm" type="submit">Save note</button>
|
|
</div>
|
|
</form>
|
|
<form asp-controller="Scenes" asp-action="DeleteNote" method="post" class="mt-1">
|
|
<input type="hidden" name="id" value="@note.SceneNoteID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-danger btn-sm" type="submit">Remove note</button>
|
|
</form>
|
|
</details>
|
|
}
|
|
</div>
|
|
}
|
|
<form asp-controller="Scenes" asp-action="SaveNote" method="post" class="writer-add-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<select class="form-select form-select-sm" name="SceneNoteTypeID" asp-items="Model.SceneNoteTypeOptions"></select>
|
|
<input class="form-control form-control-sm" name="NoteTitle" placeholder="Optional title" />
|
|
<textarea class="form-control form-control-sm" name="NoteText" rows="3" placeholder="Add a drafting, revision, research, or TODO note"></textarea>
|
|
<div class="writer-checkbox-grid">
|
|
<label><input type="checkbox" name="IsPinned" value="true" /> Pin note</label>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Add note</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section writer-checklist-section" data-section-title="Scene Checklist" data-section-id="inspector-checklist">
|
|
<h3>Scene Checklist</h3>
|
|
<div class="writer-checklist">
|
|
@foreach (var item in Model.ChecklistItems)
|
|
{
|
|
<form asp-controller="Scenes" asp-action="SaveChecklistItem" method="post" class="writer-checklist-row">
|
|
<input type="hidden" name="SceneChecklistItemID" value="@item.SceneChecklistItemID" />
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<input type="checkbox" name="IsCompleted" value="true" checked="@item.IsCompleted" />
|
|
<input class="form-control form-control-sm" name="ItemText" value="@item.ItemText" />
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Save</button>
|
|
</form>
|
|
<form asp-controller="Scenes" asp-action="DeleteChecklistItem" method="post" class="writer-remove-inline">
|
|
<input type="hidden" name="id" value="@item.SceneChecklistItemID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-danger btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
}
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="SaveChecklistItem" method="post" class="writer-add-form writer-add-inline">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<input class="form-control form-control-sm" name="ItemText" placeholder="Add checklist item" />
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Add item</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section writer-attachments-section" data-section-title="Attachments / Research" data-section-id="inspector-attachments">
|
|
<h3>Attachments / Research</h3>
|
|
@if (!Model.Attachments.Any())
|
|
{
|
|
<p class="muted">No scene references yet. Add images, links, floorplans, research notes, or files that help you write this scene.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="attachment-card-list">
|
|
@foreach (var attachment in Model.Attachments)
|
|
{
|
|
var hasFile = !string.IsNullOrWhiteSpace(attachment.FilePath);
|
|
var fileHref = hasFile && attachment.FilePath!.StartsWith("http", StringComparison.OrdinalIgnoreCase)
|
|
? attachment.FilePath
|
|
: hasFile && attachment.FilePath!.StartsWith("/")
|
|
? attachment.FilePath
|
|
: hasFile && !System.IO.Path.IsPathRooted(attachment.FilePath!)
|
|
? "/" + attachment.FilePath!.TrimStart('/', '\\')
|
|
: null;
|
|
var fileExtension = hasFile ? System.IO.Path.GetExtension(attachment.FilePath!) : string.Empty;
|
|
var isImageAttachment = !string.IsNullOrWhiteSpace(fileHref)
|
|
&& new[] { ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp" }.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);
|
|
<details class="writer-mini-card attachment-card">
|
|
<summary class="attachment-summary">
|
|
<span class="attachment-kind">@(hasFile ? "File" : "Link")</span>
|
|
<span class="status-pill">@attachment.TypeName</span>
|
|
<strong>@attachment.Title</strong>
|
|
</summary>
|
|
<div class="attachment-card-body">
|
|
<div class="attachment-preview-row">
|
|
@if (isImageAttachment)
|
|
{
|
|
<a class="attachment-thumb" href="@fileHref" target="_blank" rel="noopener" aria-label="Open @attachment.Title image">
|
|
<img src="@fileHref" alt="@attachment.Title preview" loading="lazy" />
|
|
</a>
|
|
}
|
|
else
|
|
{
|
|
<div class="attachment-thumb attachment-thumb-fallback" aria-hidden="true">
|
|
<span>@(hasFile ? "File" : "Link")</span>
|
|
</div>
|
|
}
|
|
<div class="attachment-preview-copy">
|
|
@if (!string.IsNullOrWhiteSpace(attachment.Notes))
|
|
{
|
|
<p>@attachment.Notes</p>
|
|
}
|
|
@if (hasFile)
|
|
{
|
|
<p class="muted">@System.IO.Path.GetFileName(attachment.FilePath)</p>
|
|
}
|
|
<div class="button-row compact-buttons">
|
|
@if (!string.IsNullOrWhiteSpace(fileHref))
|
|
{
|
|
<a class="btn btn-outline-secondary btn-sm" href="@fileHref" target="_blank" rel="noopener">Open</a>
|
|
<a class="btn btn-outline-secondary btn-sm" href="@fileHref" download>Download</a>
|
|
}
|
|
@if (!string.IsNullOrWhiteSpace(attachment.ExternalUrl))
|
|
{
|
|
<a class="btn btn-outline-secondary btn-sm" href="@attachment.ExternalUrl" target="_blank" rel="noopener">Open link</a>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="SaveAttachment" method="post" enctype="multipart/form-data" class="writer-edit-form">
|
|
<input type="hidden" name="SceneAttachmentID" value="@attachment.SceneAttachmentID" />
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="FilePath" value="@attachment.FilePath" />
|
|
<select class="form-select form-select-sm" name="SceneAttachmentTypeID">
|
|
@foreach (var option in Model.SceneAttachmentTypeOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == attachment.SceneAttachmentTypeID.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
<input class="form-control form-control-sm" name="Title" value="@attachment.Title" />
|
|
<label class="form-label mb-0">Replace file</label>
|
|
<input class="form-control form-control-sm" name="UploadedFile" type="file" />
|
|
<input class="form-control form-control-sm" name="ExternalUrl" value="@attachment.ExternalUrl" placeholder="Or external URL" />
|
|
<textarea class="form-control form-control-sm" name="Notes" rows="2">@attachment.Notes</textarea>
|
|
<button class="btn btn-primary btn-sm" type="submit">Save attachment</button>
|
|
</form>
|
|
<form asp-controller="Scenes" asp-action="DeleteAttachment" method="post" class="mt-1">
|
|
<input type="hidden" name="id" value="@attachment.SceneAttachmentID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="filePath" value="@attachment.FilePath" />
|
|
<button class="btn btn-outline-danger btn-sm" type="submit">Remove attachment</button>
|
|
</form>
|
|
</details>
|
|
}
|
|
</div>
|
|
}
|
|
<details class="writer-mini-card attachment-add-card">
|
|
<summary><strong>+ Add Attachment</strong></summary>
|
|
<form asp-controller="Scenes" asp-action="SaveAttachment" method="post" enctype="multipart/form-data" class="writer-add-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<label class="form-label mb-0">Attachment type</label>
|
|
<select class="form-select form-select-sm" name="SceneAttachmentTypeID" asp-items="Model.SceneAttachmentTypeOptions"></select>
|
|
<label class="form-label mb-0">Title</label>
|
|
<input class="form-control form-control-sm" name="Title" placeholder="Reference title" />
|
|
<label class="form-label mb-0">Choose file</label>
|
|
<input class="form-control form-control-sm" name="UploadedFile" type="file" />
|
|
<label class="form-label mb-0">Or external URL</label>
|
|
<input class="form-control form-control-sm" name="ExternalUrl" placeholder="https://..." />
|
|
<textarea class="form-control form-control-sm" name="Notes" rows="2" placeholder="Why this reference matters"></textarea>
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Add attachment</button>
|
|
</form>
|
|
</details>
|
|
</section>
|
|
|
|
<section class="inspector-section warning-inspector-section" data-section-title="Continuity Warnings" data-section-id="inspector-warnings">
|
|
<div class="inspector-section-heading">
|
|
<h3>Continuity Warnings</h3>
|
|
@if (Model.SceneID > 0 && Model.ReturnProjectID.HasValue)
|
|
{
|
|
<form asp-controller="Warnings" asp-action="ValidateScene" method="post">
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="returnToTimeline" value="@Model.ReturnToTimeline.ToString().ToLowerInvariant()" />
|
|
<button class="btn btn-outline-primary btn-sm" type="submit">Validate scene</button>
|
|
</form>
|
|
}
|
|
</div>
|
|
@if (!Model.Warnings.Any())
|
|
{
|
|
<p class="muted">No active warnings for this scene. Run validation again after major story changes.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="warning-mini-list">
|
|
@foreach (var warning in Model.Warnings)
|
|
{
|
|
<div class="warning-mini-card">
|
|
<span class="severity-pill @warning.SeverityName.ToLowerInvariant()">@warning.SeverityName</span>
|
|
<strong>@warning.WarningTypeName</strong>
|
|
<p>@warning.Message</p>
|
|
<div class="button-row compact-buttons">
|
|
<form asp-controller="Warnings" asp-action="Dismiss" method="post">
|
|
<input type="hidden" name="id" value="@warning.ContinuityWarningID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="returnToTimeline" value="@Model.ReturnToTimeline.ToString().ToLowerInvariant()" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Dismiss</button>
|
|
</form>
|
|
<form asp-controller="Warnings" asp-action="MarkIntentional" method="post">
|
|
<input type="hidden" name="id" value="@warning.ContinuityWarningID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="returnToTimeline" value="@Model.ReturnToTimeline.ToString().ToLowerInvariant()" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Intentional</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</section>
|
|
|
|
<section class="inspector-section scene-dependency-section" data-section-title="Scene Dependencies" data-section-id="inspector-dependencies">
|
|
<h3>Scene Dependencies</h3>
|
|
<div class="dependency-columns">
|
|
<div>
|
|
<p class="eyebrow">This scene depends on</p>
|
|
@if (!Model.DependenciesThisSceneNeeds.Any())
|
|
{
|
|
<p class="muted">No dependencies yet. Add one when this scene needs another moment to happen first.</p>
|
|
}
|
|
else
|
|
{
|
|
@foreach (var dependency in Model.DependenciesThisSceneNeeds)
|
|
{
|
|
<div class="dependency-card">
|
|
<strong>Ch @dependency.SourceChapterNumber, Scene @dependency.SourceSceneNumber</strong>
|
|
<span>@dependency.SourceSceneTitle</span>
|
|
<span class="muted">@dependency.SceneDependencyTypeName @(dependency.IsHardDependency ? "/ hard" : "/ soft")</span>
|
|
<form asp-controller="Scenes" asp-action="DeleteSceneDependency" method="post">
|
|
<input type="hidden" name="id" value="@dependency.SceneDependencyID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
<div>
|
|
<p class="eyebrow">Scenes depending on this</p>
|
|
@if (!Model.DependenciesNeedingThisScene.Any())
|
|
{
|
|
<p class="muted">No dependent scenes yet. Later scenes that rely on this one will appear here.</p>
|
|
}
|
|
else
|
|
{
|
|
@foreach (var dependency in Model.DependenciesNeedingThisScene)
|
|
{
|
|
<div class="dependency-card">
|
|
<strong>Ch @dependency.TargetChapterNumber, Scene @dependency.TargetSceneNumber</strong>
|
|
<span>@dependency.TargetSceneTitle</span>
|
|
<span class="muted">@dependency.SceneDependencyTypeName @(dependency.IsHardDependency ? "/ hard" : "/ soft")</span>
|
|
<form asp-controller="Scenes" asp-action="DeleteSceneDependency" method="post">
|
|
<input type="hidden" name="id" value="@dependency.SceneDependencyID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<form asp-controller="Scenes" asp-action="AddSceneDependency" method="post" class="asset-create-form mt-2">
|
|
<input type="hidden" name="ProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="CurrentSceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="DependencyDirection">Plain English</label>
|
|
<select class="form-select form-select-sm" id="DependencyDirection" name="Direction">
|
|
<option value="CurrentDependsOnRelated">This scene depends on another scene</option>
|
|
<option value="RelatedDependsOnCurrent">Another scene depends on this scene</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="RelatedSceneID">Related scene</label>
|
|
<select class="form-select form-select-sm" id="RelatedSceneID" name="RelatedSceneID" asp-items="Model.SceneOptions"></select>
|
|
</div>
|
|
<div class="col-8">
|
|
<label class="form-label" for="SceneDependencyTypeID">Dependency type</label>
|
|
<select class="form-select form-select-sm" id="SceneDependencyTypeID" name="SceneDependencyTypeID" asp-items="Model.SceneDependencyTypeOptions"></select>
|
|
</div>
|
|
<div class="col-4 d-flex align-items-end">
|
|
<label class="form-check mb-2">
|
|
<input class="form-check-input" name="IsHardDependency" type="checkbox" value="true" />
|
|
<span class="form-check-label">Hard</span>
|
|
</label>
|
|
</div>
|
|
<div class="col-12">
|
|
<textarea class="form-control form-control-sm" name="Description" rows="2" placeholder="Why this order matters"></textarea>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add dependency</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section scene-move-section" data-section-title="Move / Reorder" data-section-id="inspector-move">
|
|
<h3>Move / Reorder</h3>
|
|
<form asp-controller="Scenes" asp-action="PreviewMove" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="TargetChapterID">Move to chapter</label>
|
|
<select class="form-select form-select-sm" id="TargetChapterID" name="TargetChapterID" asp-items="Model.ChapterOptions"></select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="MovePosition">Position</label>
|
|
<select class="form-select form-select-sm" id="MovePosition" name="Position">
|
|
<option value="End">End of chapter</option>
|
|
<option value="Start">Start of chapter</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6 d-flex align-items-end">
|
|
<label class="form-check mb-2">
|
|
<input class="form-check-input" name="RenumberScenes" type="checkbox" value="true" />
|
|
<span class="form-check-label">Renumber scenes</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Preview move</button>
|
|
</form>
|
|
<form asp-controller="Scenes" asp-action="RenumberChapter" method="post" class="mt-2">
|
|
<input type="hidden" name="chapterId" value="@Model.ChapterID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Renumber this chapter</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section thread-events-section" data-section-title="Plot Thread Events" data-section-id="inspector-thread-events">
|
|
<h3>Plot Thread Events</h3>
|
|
@if (!Model.ThreadEvents.Any())
|
|
{
|
|
<p class="muted">No plot thread events attached to this scene yet. Add clues, reveals, promises, payoffs, or reversals when the scene touches a thread.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="thread-event-list">
|
|
@foreach (var threadEvent in Model.ThreadEvents)
|
|
{
|
|
<div class="thread-event-item" style="--plot-colour:@threadEvent.Colour">
|
|
<div>
|
|
<span class="thread-event-marker">@threadEvent.MarkerText</span>
|
|
<strong>@threadEvent.EventTitle</strong>
|
|
<span class="muted">@threadEvent.PlotLineName / @threadEvent.ThreadTitle</span>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteThreadEvent" method="post">
|
|
<input type="hidden" name="id" value="@threadEvent.ThreadEventID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<form asp-controller="Scenes" asp-action="AddThreadEvent" method="post" class="thread-event-create">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<p class="form-text mb-2">Choose an existing thread, or choose a plot line to create one from the event title.</p>
|
|
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="PlotLineID">Plot line</label>
|
|
<select class="form-select form-select-sm" id="PlotLineID" name="PlotLineID" asp-items="Model.PlotLineOptions">
|
|
<option value="">Choose plot line</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="PlotThreadID">Existing plot thread</label>
|
|
<select class="form-select form-select-sm" id="PlotThreadID" name="PlotThreadID" asp-items="Model.PlotThreadOptions">
|
|
<option value="">Create or choose a thread</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-8">
|
|
<label class="form-label" for="NewThreadTitle">New thread title</label>
|
|
<input class="form-control form-control-sm" id="NewThreadTitle" name="NewThreadTitle" placeholder="Optional" />
|
|
</div>
|
|
<div class="col-4">
|
|
<label class="form-label" for="NewThreadTypeID">Thread type</label>
|
|
<select class="form-select form-select-sm" id="NewThreadTypeID" name="NewThreadTypeID" asp-items="Model.ThreadTypeOptions">
|
|
<option value="">Default</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="EventTypeID">Event type</label>
|
|
<select class="form-select form-select-sm" id="EventTypeID" name="EventTypeID" asp-items="Model.ThreadEventTypeOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="EventTitle">Event title</label>
|
|
<input class="form-control form-control-sm" id="EventTitle" name="EventTitle" placeholder="Defaults to event type if blank" />
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="EventDescription">Description</label>
|
|
<textarea class="form-control form-control-sm" id="EventDescription" name="EventDescription" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add thread event</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section asset-events-section" data-section-title="Story Assets" data-section-id="inspector-asset-events">
|
|
<h3>Story Assets</h3>
|
|
@if (!Model.AssetEvents.Any())
|
|
{
|
|
<p class="muted">No asset events attached to this scene yet. Add one when an object, clue, secret, or important item changes here.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var assetEvent in Model.AssetEvents)
|
|
{
|
|
<div class="asset-event-item">
|
|
<div>
|
|
<span class="asset-event-marker">@assetEvent.MarkerText</span>
|
|
<strong>@assetEvent.EventTitle</strong>
|
|
<span class="muted">@assetEvent.AssetName / @assetEvent.AssetEventTypeName</span>
|
|
@if (!string.IsNullOrWhiteSpace(assetEvent.ToStateName))
|
|
{
|
|
<span class="muted">State: @(assetEvent.FromStateName ?? "Any") -> @assetEvent.ToStateName</span>
|
|
}
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteAssetEvent" method="post">
|
|
<input type="hidden" name="id" value="@assetEvent.AssetEventID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<form asp-controller="Scenes" asp-action="AddAssetEvent" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<p class="form-text mb-2">Choose an existing asset, or enter a new asset name to create it from this scene.</p>
|
|
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="StoryAssetID">Asset</label>
|
|
<select class="form-select form-select-sm" id="StoryAssetID" name="StoryAssetID" asp-items="Model.AssetOptions">
|
|
<option value="">Create or choose an asset</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-8">
|
|
<label class="form-label" for="NewAssetName">New asset name</label>
|
|
<input class="form-control form-control-sm" id="NewAssetName" name="NewAssetName" placeholder="Optional" />
|
|
</div>
|
|
<div class="col-4">
|
|
<label class="form-label" for="NewAssetKindID">Kind</label>
|
|
<select class="form-select form-select-sm" id="NewAssetKindID" name="NewAssetKindID" asp-items="Model.AssetKindOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="AssetEventTypeID">Event type</label>
|
|
<select class="form-select form-select-sm" id="AssetEventTypeID" name="AssetEventTypeID" asp-items="Model.AssetEventTypeOptions"></select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="FromStateID">From state</label>
|
|
<select class="form-select form-select-sm" id="FromStateID" name="FromStateID" asp-items="Model.AssetStateOptions">
|
|
<option value="">Any</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="ToStateID">To state</label>
|
|
<select class="form-select form-select-sm" id="ToStateID" name="ToStateID" asp-items="Model.AssetStateOptions">
|
|
<option value="">No change</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="AssetEventTitle">Event title</label>
|
|
<input class="form-control form-control-sm" id="AssetEventTitle" name="EventTitle" placeholder="Defaults to event type if blank" />
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="AssetEventDescription">Description</label>
|
|
<textarea class="form-control form-control-sm" id="AssetEventDescription" name="EventDescription" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add asset event</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section asset-events-section" data-section-title="Asset Locations" data-section-id="inspector-asset-locations">
|
|
<h3>Asset Locations</h3>
|
|
@if (!Model.SceneAssetLocations.Any())
|
|
{
|
|
<p class="muted">No assets have been placed in a location for this scene yet.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var assetLocation in Model.SceneAssetLocations)
|
|
{
|
|
<div class="asset-event-item">
|
|
<div>
|
|
<strong>@assetLocation.AssetName</strong>
|
|
<span class="muted" title="@assetLocation.LocationPath">@assetLocation.LocationName</span>
|
|
<span class="muted">@assetLocation.Description</span>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteSceneAssetLocation" method="post">
|
|
<input type="hidden" name="id" value="@assetLocation.SceneAssetLocationID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<form asp-controller="Scenes" asp-action="AddSceneAssetLocation" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="SceneAssetStoryAssetID">Asset</label>
|
|
<select class="form-select form-select-sm" id="SceneAssetStoryAssetID" name="StoryAssetID" asp-items="Model.AssetOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="SceneAssetLocationID">Location</label>
|
|
<select class="form-select form-select-sm" id="SceneAssetLocationID" name="LocationID" asp-items="Model.LocationOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<input class="form-control form-control-sm" name="Description" placeholder="e.g. desk drawer, Beth's handbag" />
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-check">
|
|
<input class="form-check-input" name="UpdateCurrentLocation" type="checkbox" value="true" checked />
|
|
<span class="form-check-label">Update asset's current location</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Place asset</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section asset-events-section" data-section-title="Asset Custody" data-section-id="inspector-asset-custody">
|
|
<h3>Asset Custody</h3>
|
|
@if (!Model.AssetCustodyEvents.Any())
|
|
{
|
|
<p class="muted">No custody entries attached to this scene yet.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var custody in Model.AssetCustodyEvents)
|
|
{
|
|
<div class="asset-event-item custody">
|
|
<div>
|
|
<strong>@custody.CustodyEventTypeName</strong>
|
|
<span class="muted">@custody.AssetName</span>
|
|
<span class="muted">@custody.CustodianSummary</span>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteAssetCustodyEvent" method="post">
|
|
<input type="hidden" name="id" value="@custody.AssetCustodyEventID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<form asp-controller="Scenes" asp-action="AddAssetCustodyEvent" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="CustodyStoryAssetID">Asset</label>
|
|
<select class="form-select form-select-sm" id="CustodyStoryAssetID" name="StoryAssetID" asp-items="Model.AssetOptions"></select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="AssetCustodyEventTypeID">Custody event</label>
|
|
<select class="form-select form-select-sm" id="AssetCustodyEventTypeID" name="AssetCustodyEventTypeID" asp-items="Model.AssetCustodyEventTypeOptions"></select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="CustodyRoleID">Role</label>
|
|
<select class="form-select form-select-sm" id="CustodyRoleID" name="CustodyRoleID" asp-items="Model.CustodyRoleOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="CustodianCharacterIds">Existing custodians</label>
|
|
<select class="form-select form-select-sm" id="CustodianCharacterIds" name="CustodianCharacterIds" asp-items="Model.CharacterOptions" multiple></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="CustodianNames">Custodian names</label>
|
|
<input class="form-control form-control-sm" id="CustodianNames" name="CustodianNames" placeholder="Beth, Maggie" />
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="CustodyDescription">Description</label>
|
|
<textarea class="form-control form-control-sm" id="CustodyDescription" name="Description" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add custody</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section character-section" data-section-title="Characters" data-section-id="inspector-characters">
|
|
<h3>Characters</h3>
|
|
@if (!Model.SceneCharacters.Any())
|
|
{
|
|
<p class="muted">No characters attached to this scene yet. Add the people who appear, are mentioned, or meaningfully affect the scene.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var character in Model.SceneCharacters)
|
|
{
|
|
var editId = $"scene-character-edit-{character.SceneCharacterID}";
|
|
<article class="character-appearance-card">
|
|
<div class="character-appearance-summary">
|
|
<div>
|
|
<strong>@character.CharacterName</strong>
|
|
<span class="muted">@((character.RoleInSceneTypeName ?? "Role not set")) • @((character.PresenceTypeName ?? "Presence not set"))</span>
|
|
<span class="muted" title="@character.LocationPath">Location: @(character.LocationName ?? "Not set")</span>
|
|
<span class="muted">Entry: @(character.EntryLocationName ?? "Not set")</span>
|
|
<span class="muted">Exit: @(character.ExitLocationName ?? "Not set")</span>
|
|
@if (!string.IsNullOrWhiteSpace(character.OutfitDescription) || !string.IsNullOrWhiteSpace(character.PhysicalCondition) || !string.IsNullOrWhiteSpace(character.EmotionalState))
|
|
{
|
|
<span class="muted">@character.OutfitDescription @character.PhysicalCondition @character.EmotionalState</span>
|
|
}
|
|
</div>
|
|
<div class="character-appearance-actions">
|
|
<button class="btn btn-outline-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#@editId" aria-expanded="false" aria-controls="@editId">Edit</button>
|
|
<form asp-controller="Scenes" asp-action="DeleteSceneCharacter" method="post">
|
|
<input type="hidden" name="id" value="@character.SceneCharacterID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="collapse character-appearance-edit" id="@editId">
|
|
<form asp-controller="Scenes" asp-action="UpdateSceneCharacter" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneCharacterID" value="@character.SceneCharacterID" />
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="CharacterID" value="@character.CharacterID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-6">
|
|
<label class="form-label" for="RoleInSceneTypeID-@character.SceneCharacterID">Role</label>
|
|
<select class="form-select form-select-sm" id="RoleInSceneTypeID-@character.SceneCharacterID" name="RoleInSceneTypeID">
|
|
<option value="">Not set</option>
|
|
@foreach (var option in Model.CharacterRoleOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == character.RoleInSceneTypeID?.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="PresenceTypeID-@character.SceneCharacterID">Presence</label>
|
|
<select class="form-select form-select-sm" id="PresenceTypeID-@character.SceneCharacterID" name="PresenceTypeID">
|
|
<option value="">Not set</option>
|
|
@foreach (var option in Model.PresenceTypeOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == character.PresenceTypeID?.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="CharacterLocationID-@character.SceneCharacterID">Current location</label>
|
|
<select class="form-select form-select-sm" id="CharacterLocationID-@character.SceneCharacterID" name="LocationID">
|
|
<option value="">Not set</option>
|
|
@foreach (var option in Model.LocationOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == character.LocationID?.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="EntryLocationID-@character.SceneCharacterID">Enters from</label>
|
|
<select class="form-select form-select-sm" id="EntryLocationID-@character.SceneCharacterID" name="EntryLocationID">
|
|
<option value="">Not set</option>
|
|
@foreach (var option in Model.LocationOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == character.EntryLocationID?.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="ExitLocationID-@character.SceneCharacterID">Exits to</label>
|
|
<select class="form-select form-select-sm" id="ExitLocationID-@character.SceneCharacterID" name="ExitLocationID">
|
|
<option value="">Not set</option>
|
|
@foreach (var option in Model.LocationOptions)
|
|
{
|
|
<option value="@option.Value" selected="@(option.Value == character.ExitLocationID?.ToString())">@option.Text</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="AppearanceNotes-@character.SceneCharacterID">Appearance notes</label>
|
|
<textarea class="form-control form-control-sm" id="AppearanceNotes-@character.SceneCharacterID" name="AppearanceNotes" rows="2">@character.AppearanceNotes</textarea>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="OutfitDescription-@character.SceneCharacterID">Outfit description</label>
|
|
<input class="form-control form-control-sm" id="OutfitDescription-@character.SceneCharacterID" name="OutfitDescription" value="@character.OutfitDescription" />
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="PhysicalCondition-@character.SceneCharacterID">Physical condition</label>
|
|
<input class="form-control form-control-sm" id="PhysicalCondition-@character.SceneCharacterID" name="PhysicalCondition" value="@character.PhysicalCondition" />
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="EmotionalState-@character.SceneCharacterID">Emotional state</label>
|
|
<input class="form-control form-control-sm" id="EmotionalState-@character.SceneCharacterID" name="EmotionalState" value="@character.EmotionalState" />
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="KnowledgeNotes-@character.SceneCharacterID">Knowledge notes</label>
|
|
<textarea class="form-control form-control-sm" id="KnowledgeNotes-@character.SceneCharacterID" name="KnowledgeNotes" rows="2">@character.KnowledgeNotes</textarea>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Save character</button>
|
|
</form>
|
|
</div>
|
|
</article>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<form asp-controller="Scenes" asp-action="AddSceneCharacter" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<h4 class="inspector-subheading">Add character to scene</h4>
|
|
@if (TempData["SceneCharacterAddError"] is string addCharacterError)
|
|
{
|
|
<p class="text-danger form-helper-message">@addCharacterError</p>
|
|
}
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<label class="form-label" for="CharacterID">Character</label>
|
|
<select class="form-select form-select-sm" id="CharacterID" name="CharacterID" asp-items="Model.CharacterOptions">
|
|
<option value="">Create or choose a character</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="NewCharacterName">New character name</label>
|
|
<input class="form-control form-control-sm" id="NewCharacterName" name="NewCharacterName" placeholder="Optional" />
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="RoleInSceneTypeID">Role</label>
|
|
<select class="form-select form-select-sm" id="RoleInSceneTypeID" name="RoleInSceneTypeID" asp-items="Model.CharacterRoleOptions">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="PresenceTypeID">Presence</label>
|
|
<select class="form-select form-select-sm" id="PresenceTypeID" name="PresenceTypeID" asp-items="Model.PresenceTypeOptions">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="CharacterLocationID">Current location</label>
|
|
<select class="form-select form-select-sm" id="CharacterLocationID" name="LocationID" asp-items="Model.LocationOptions">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="EntryLocationID">Enters from</label>
|
|
<select class="form-select form-select-sm" id="EntryLocationID" name="EntryLocationID" asp-items="Model.LocationOptions">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6">
|
|
<label class="form-label" for="ExitLocationID">Exits to</label>
|
|
<select class="form-select form-select-sm" id="ExitLocationID" name="ExitLocationID" asp-items="Model.LocationOptions">
|
|
<option value="">Not set</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12"><input class="form-control form-control-sm" name="AppearanceNotes" placeholder="Appearance notes" /></div>
|
|
<div class="col-12"><input class="form-control form-control-sm" name="OutfitDescription" placeholder="Outfit description" /></div>
|
|
<div class="col-6"><input class="form-control form-control-sm" name="PhysicalCondition" placeholder="Physical condition" /></div>
|
|
<div class="col-6"><input class="form-control form-control-sm" name="EmotionalState" placeholder="Emotional state" /></div>
|
|
<div class="col-12"><textarea class="form-control form-control-sm" name="KnowledgeNotes" rows="2" placeholder="Knowledge notes"></textarea></div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add character to scene</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section character-section" data-section-title="Character Attributes" data-section-id="inspector-character-attributes">
|
|
<h3>Character Attributes</h3>
|
|
@if (Model.CharacterAttributeEvents.Any())
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var item in Model.CharacterAttributeEvents)
|
|
{
|
|
<div class="asset-event-item character-item">
|
|
<div>
|
|
<strong>@item.CharacterName: @item.AttributeName</strong>
|
|
<span class="muted">@item.AttributeValue</span>
|
|
<span class="muted">@item.Description</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<p class="muted">Character attribute history for this scene will appear here when available.</p>
|
|
}
|
|
<form asp-controller="Scenes" asp-action="AddCharacterAttributeEvent" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<select class="form-select form-select-sm" name="CharacterID" asp-items="Model.CharacterOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<select class="form-select form-select-sm" name="CharacterAttributeTypeID" asp-items="Model.CharacterAttributeTypeOptions"></select>
|
|
</div>
|
|
<div class="col-12">
|
|
<input class="form-control form-control-sm" name="AttributeValue" placeholder="Value, e.g. Bruised ribs" />
|
|
</div>
|
|
<div class="col-12">
|
|
<textarea class="form-control form-control-sm" name="Description" rows="2" placeholder="Description"></textarea>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add attribute</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section character-section" data-section-title="Character Knowledge" data-section-id="inspector-character-knowledge">
|
|
<h3>Character Knowledge</h3>
|
|
@if (Model.CharacterKnowledge.Any())
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var item in Model.CharacterKnowledge)
|
|
{
|
|
<div class="asset-event-item character-item">
|
|
<div>
|
|
<strong>@item.CharacterName @item.KnowledgeStateName</strong>
|
|
<span class="muted">@(item.AssetName ?? item.ThreadTitle)</span>
|
|
<span class="muted">@item.Description</span>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteCharacterKnowledge" method="post">
|
|
<input type="hidden" name="id" value="@item.CharacterKnowledgeID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
<form asp-controller="Scenes" asp-action="AddCharacterKnowledge" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12"><select class="form-select form-select-sm" name="CharacterID" asp-items="Model.CharacterOptions"></select></div>
|
|
<div class="col-12">
|
|
<select class="form-select form-select-sm" name="StoryAssetID" asp-items="Model.AssetOptions">
|
|
<option value="">No asset</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12">
|
|
<select class="form-select form-select-sm" name="PlotThreadID" asp-items="Model.PlotThreadOptions">
|
|
<option value="">No plot thread</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-12"><select class="form-select form-select-sm" name="KnowledgeStateID" asp-items="Model.KnowledgeStateOptions"></select></div>
|
|
<div class="col-12"><textarea class="form-control form-control-sm" name="Description" rows="2" placeholder="Description"></textarea></div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add knowledge</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="inspector-section character-section" data-section-title="Relationship Events" data-section-id="inspector-relationships">
|
|
<h3>Relationship Events</h3>
|
|
@if (Model.RelationshipEvents.Any())
|
|
{
|
|
<div class="asset-event-list">
|
|
@foreach (var item in Model.RelationshipEvents)
|
|
{
|
|
<div class="asset-event-item character-item">
|
|
<div>
|
|
<strong>@item.CharacterAName -> @item.CharacterBName</strong>
|
|
<span class="muted">@item.RelationshipStateName / intensity @item.Intensity</span>
|
|
<span class="muted">@item.Description</span>
|
|
</div>
|
|
<form asp-controller="Scenes" asp-action="DeleteRelationshipEvent" method="post">
|
|
<input type="hidden" name="id" value="@item.RelationshipEventID" />
|
|
<input type="hidden" name="sceneId" value="@Model.SceneID" />
|
|
<input type="hidden" name="projectId" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="bookId" value="@Model.ReturnBookID" />
|
|
<button class="btn btn-outline-secondary btn-sm" type="submit">Remove</button>
|
|
</form>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
<form asp-controller="Scenes" asp-action="AddRelationshipEvent" method="post" class="asset-create-form">
|
|
<input type="hidden" name="SceneID" value="@Model.SceneID" />
|
|
<input type="hidden" name="ReturnProjectID" value="@Model.ReturnProjectID" />
|
|
<input type="hidden" name="ReturnBookID" value="@Model.ReturnBookID" />
|
|
<div class="row g-2">
|
|
<div class="col-12">
|
|
<select class="form-select form-select-sm" name="CharacterRelationshipID" asp-items="Model.RelationshipOptions">
|
|
<option value="">Create or choose relationship</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-6"><select class="form-select form-select-sm" name="CharacterAID" asp-items="Model.CharacterOptions"><option value="">Character A</option></select></div>
|
|
<div class="col-6"><select class="form-select form-select-sm" name="CharacterBID" asp-items="Model.CharacterOptions"><option value="">Character B</option></select></div>
|
|
<div class="col-12"><select class="form-select form-select-sm" name="RelationshipTypeID" asp-items="Model.RelationshipTypeOptions"><option value="">Relationship type</option></select></div>
|
|
<div class="col-8"><select class="form-select form-select-sm" name="RelationshipStateID" asp-items="Model.RelationshipStateOptions"></select></div>
|
|
<div class="col-4"><input class="form-control form-control-sm" name="Intensity" type="number" min="1" max="10" placeholder="1-10" /></div>
|
|
<div class="col-12">
|
|
<label class="form-check">
|
|
<input class="form-check-input" name="IsKnownToOtherCharacter" type="checkbox" value="true" />
|
|
<span class="form-check-label">Other character knows</span>
|
|
</label>
|
|
</div>
|
|
<div class="col-12"><textarea class="form-control form-control-sm" name="Description" rows="2" placeholder="Description"></textarea></div>
|
|
</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" type="submit">Add relationship event</button>
|
|
</form>
|
|
</section>
|
|
|
|
</div>
|