PlotDirector Phase 17E - Writer Tools Editor Migration
This commit is contained in:
parent
be1c508df4
commit
0d72dc64d0
@ -142,6 +142,33 @@ public sealed class ScenesController(
|
||||
: PartialView("~/Views/Shared/SceneInspectorV2/_SceneAssetsEditor.cshtml", model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> SceneNotesEditor(int sceneId)
|
||||
{
|
||||
var model = await scenes.GetEditAsync(sceneId);
|
||||
return model is null
|
||||
? NotFound()
|
||||
: PartialView("~/Views/Shared/SceneInspectorV2/_SceneNotesEditor.cshtml", model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> SceneChecklistEditor(int sceneId)
|
||||
{
|
||||
var model = await scenes.GetEditAsync(sceneId);
|
||||
return model is null
|
||||
? NotFound()
|
||||
: PartialView("~/Views/Shared/SceneInspectorV2/_SceneChecklistEditor.cshtml", model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> SceneWorkflowEditor(int sceneId)
|
||||
{
|
||||
var model = await scenes.GetEditAsync(sceneId);
|
||||
return model is null
|
||||
? NotFound()
|
||||
: PartialView("~/Views/Shared/SceneInspectorV2/_SceneWorkflowEditor.cshtml", model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SaveSceneDetails(SceneDetailsSaveViewModel model)
|
||||
@ -502,6 +529,199 @@ public sealed class ScenesController(
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SaveSceneNotes(SceneNotesSaveViewModel model)
|
||||
{
|
||||
var current = await scenes.GetEditAsync(model.SceneID);
|
||||
if (current is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var existingRows = current.Notes.ToDictionary(x => x.SceneNoteID);
|
||||
var validNoteTypeIds = current.SceneNoteTypeOptions
|
||||
.Where(x => int.TryParse(x.Value, out _))
|
||||
.Select(x => int.Parse(x.Value))
|
||||
.ToHashSet();
|
||||
|
||||
foreach (var note in model.Notes)
|
||||
{
|
||||
if (!existingRows.ContainsKey(note.SceneNoteID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (note.Remove)
|
||||
{
|
||||
await writerWorkspace.DeleteNoteAsync(note.SceneNoteID);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(note.NoteText))
|
||||
{
|
||||
return BadRequest(new { success = false, message = "Enter note text before saving." });
|
||||
}
|
||||
|
||||
if (!validNoteTypeIds.Contains(note.SceneNoteTypeID))
|
||||
{
|
||||
return BadRequest(new { success = false, message = "Choose an existing note type." });
|
||||
}
|
||||
|
||||
note.SceneID = model.SceneID;
|
||||
await writerWorkspace.SaveNoteAsync(new SceneNoteEditViewModel
|
||||
{
|
||||
SceneNoteID = note.SceneNoteID,
|
||||
SceneID = note.SceneID,
|
||||
SceneNoteTypeID = note.SceneNoteTypeID,
|
||||
NoteTitle = note.NoteTitle,
|
||||
NoteText = note.NoteText,
|
||||
SortOrder = note.SortOrder,
|
||||
IsPinned = note.IsPinned,
|
||||
IsResolved = note.IsResolved
|
||||
});
|
||||
}
|
||||
|
||||
var hasNewNoteContent = !string.IsNullOrWhiteSpace(model.NewNote.NoteTitle)
|
||||
|| !string.IsNullOrWhiteSpace(model.NewNote.NoteText);
|
||||
if (hasNewNoteContent)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(model.NewNote.NoteText))
|
||||
{
|
||||
return BadRequest(new { success = false, message = "Enter note text before saving." });
|
||||
}
|
||||
|
||||
if (!validNoteTypeIds.Contains(model.NewNote.SceneNoteTypeID))
|
||||
{
|
||||
return BadRequest(new { success = false, message = "Choose an existing note type." });
|
||||
}
|
||||
|
||||
model.NewNote.SceneID = model.SceneID;
|
||||
await writerWorkspace.SaveNoteAsync(model.NewNote);
|
||||
}
|
||||
|
||||
var updated = await scenes.GetEditAsync(model.SceneID);
|
||||
if (updated is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Json(new
|
||||
{
|
||||
success = true,
|
||||
html = new
|
||||
{
|
||||
writer = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneWriterCard.cshtml", updated),
|
||||
health = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneInspectorHealthStrip.cshtml", updated)
|
||||
},
|
||||
scene = new
|
||||
{
|
||||
updated.SceneID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SaveSceneChecklist(SceneChecklistSaveViewModel model)
|
||||
{
|
||||
var current = await scenes.GetEditAsync(model.SceneID);
|
||||
if (current is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var existingRows = current.ChecklistItems.ToDictionary(x => x.SceneChecklistItemID);
|
||||
foreach (var item in model.ChecklistItems)
|
||||
{
|
||||
if (!existingRows.ContainsKey(item.SceneChecklistItemID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.Remove)
|
||||
{
|
||||
await writerWorkspace.DeleteChecklistItemAsync(item.SceneChecklistItemID);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(item.ItemText))
|
||||
{
|
||||
return BadRequest(new { success = false, message = "Enter checklist text before saving." });
|
||||
}
|
||||
|
||||
item.SceneID = model.SceneID;
|
||||
await writerWorkspace.SaveChecklistItemAsync(new SceneChecklistItemEditViewModel
|
||||
{
|
||||
SceneChecklistItemID = item.SceneChecklistItemID,
|
||||
SceneID = item.SceneID,
|
||||
ItemText = item.ItemText,
|
||||
IsCompleted = item.IsCompleted,
|
||||
SortOrder = item.SortOrder
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.NewChecklistItem.ItemText))
|
||||
{
|
||||
model.NewChecklistItem.SceneID = model.SceneID;
|
||||
await writerWorkspace.SaveChecklistItemAsync(model.NewChecklistItem);
|
||||
}
|
||||
|
||||
var updated = await scenes.GetEditAsync(model.SceneID);
|
||||
if (updated is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Json(new
|
||||
{
|
||||
success = true,
|
||||
html = new
|
||||
{
|
||||
writer = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneWriterCard.cshtml", updated),
|
||||
health = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneInspectorHealthStrip.cshtml", updated)
|
||||
},
|
||||
scene = new
|
||||
{
|
||||
updated.SceneID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SaveSceneWorkflow(SceneWorkflowEditViewModel model)
|
||||
{
|
||||
var current = await scenes.GetEditAsync(model.SceneID);
|
||||
if (current is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
await writerWorkspace.SaveSceneWorkflowAsync(model);
|
||||
|
||||
var updated = await scenes.GetEditAsync(model.SceneID);
|
||||
if (updated is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Json(new
|
||||
{
|
||||
success = true,
|
||||
html = new
|
||||
{
|
||||
writer = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneWriterCard.cshtml", updated),
|
||||
health = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneInspectorHealthStrip.cshtml", updated),
|
||||
overview = await RenderPartialViewToStringAsync("~/Views/Shared/SceneInspectorV2/_SceneOverviewCard.cshtml", updated)
|
||||
},
|
||||
scene = new
|
||||
{
|
||||
updated.SceneID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Archive(int id, int chapterId)
|
||||
|
||||
@ -505,6 +505,43 @@ public sealed class SceneAssetEventInputViewModel
|
||||
public bool Remove { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SceneNotesSaveViewModel
|
||||
{
|
||||
public int SceneID { get; set; }
|
||||
public List<SceneNoteInputViewModel> Notes { get; set; } = [];
|
||||
public SceneNoteEditViewModel NewNote { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class SceneNoteInputViewModel
|
||||
{
|
||||
public int SceneNoteID { get; set; }
|
||||
public int SceneID { get; set; }
|
||||
public int SceneNoteTypeID { get; set; }
|
||||
public string? NoteTitle { get; set; }
|
||||
public string NoteText { get; set; } = string.Empty;
|
||||
public int? SortOrder { get; set; }
|
||||
public bool IsPinned { get; set; }
|
||||
public bool IsResolved { get; set; }
|
||||
public bool Remove { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SceneChecklistSaveViewModel
|
||||
{
|
||||
public int SceneID { get; set; }
|
||||
public List<SceneChecklistItemInputViewModel> ChecklistItems { get; set; } = [];
|
||||
public SceneChecklistItemEditViewModel NewChecklistItem { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class SceneChecklistItemInputViewModel
|
||||
{
|
||||
public int SceneChecklistItemID { get; set; }
|
||||
public int SceneID { get; set; }
|
||||
public string ItemText { get; set; } = string.Empty;
|
||||
public bool IsCompleted { get; set; }
|
||||
public int? SortOrder { get; set; }
|
||||
public bool Remove { get; set; }
|
||||
}
|
||||
|
||||
public sealed class SceneCharacterParticipationInputViewModel
|
||||
{
|
||||
public int SceneCharacterID { get; set; }
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
@model SceneEditViewModel
|
||||
@{
|
||||
var completed = Model.ChecklistItems.Count(x => x.IsCompleted);
|
||||
}
|
||||
|
||||
<form asp-controller="Scenes" asp-action="SaveSceneChecklist" method="post" class="scene-inspector-editor-form" data-scene-editor-form>
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="hidden" asp-for="SceneID" />
|
||||
|
||||
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
|
||||
|
||||
<div class="scene-inspector-editor-fields">
|
||||
<section class="scene-writer-editor-section">
|
||||
<div class="scene-writer-editor-heading">
|
||||
<span>Current checklist</span>
|
||||
<strong>@completed / @Model.ChecklistItems.Count</strong>
|
||||
</div>
|
||||
|
||||
@if (!Model.ChecklistItems.Any())
|
||||
{
|
||||
<p class="muted">No checklist items yet.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="scene-writer-editor-list">
|
||||
@for (var index = 0; index < Model.ChecklistItems.Count; index++)
|
||||
{
|
||||
var item = Model.ChecklistItems[index];
|
||||
<article class="scene-writer-checklist-row">
|
||||
<input type="hidden" name="ChecklistItems[@index].SceneChecklistItemID" value="@item.SceneChecklistItemID" />
|
||||
<input type="hidden" name="ChecklistItems[@index].SceneID" value="@Model.SceneID" />
|
||||
<input type="hidden" name="ChecklistItems[@index].SortOrder" value="@item.SortOrder" />
|
||||
<label class="scene-writer-checklist-complete">
|
||||
<input type="checkbox" name="ChecklistItems[@index].IsCompleted" value="true" checked="@item.IsCompleted" />
|
||||
<input type="hidden" name="ChecklistItems[@index].IsCompleted" value="false" />
|
||||
<span>Done</span>
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label class="visually-hidden" for="ChecklistItems_@(index)__ItemText">Checklist item</label>
|
||||
<input class="form-control form-control-sm" id="ChecklistItems_@(index)__ItemText" name="ChecklistItems[@index].ItemText" value="@item.ItemText" />
|
||||
</div>
|
||||
<label class="scene-writer-remove">
|
||||
<input type="checkbox" name="ChecklistItems[@index].Remove" value="true" />
|
||||
<input type="hidden" name="ChecklistItems[@index].Remove" value="false" />
|
||||
<span>Remove</span>
|
||||
</label>
|
||||
</article>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
|
||||
<section class="scene-writer-editor-section">
|
||||
<div class="scene-writer-editor-heading">
|
||||
<span>Add checklist item</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="NewChecklistItem_ItemText">Item text</label>
|
||||
<input class="form-control form-control-sm" id="NewChecklistItem_ItemText" name="NewChecklistItem.ItemText" />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="scene-inspector-editor-footer">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" data-scene-editor-close>Cancel</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary" data-scene-editor-save>Save checklist</button>
|
||||
</div>
|
||||
</form>
|
||||
109
PlotLine/Views/Shared/SceneInspectorV2/_SceneNotesEditor.cshtml
Normal file
109
PlotLine/Views/Shared/SceneInspectorV2/_SceneNotesEditor.cshtml
Normal file
@ -0,0 +1,109 @@
|
||||
@model SceneEditViewModel
|
||||
|
||||
<form asp-controller="Scenes" asp-action="SaveSceneNotes" method="post" class="scene-inspector-editor-form" data-scene-editor-form>
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="hidden" asp-for="SceneID" />
|
||||
|
||||
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
|
||||
|
||||
<div class="scene-inspector-editor-fields">
|
||||
<section class="scene-writer-editor-section">
|
||||
<div class="scene-writer-editor-heading">
|
||||
<span>Current notes</span>
|
||||
<strong>@Model.Notes.Count</strong>
|
||||
</div>
|
||||
|
||||
@if (!Model.Notes.Any())
|
||||
{
|
||||
<p class="muted">No working notes yet.</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="scene-writer-editor-list">
|
||||
@for (var index = 0; index < Model.Notes.Count; index++)
|
||||
{
|
||||
var note = Model.Notes[index];
|
||||
<article class="scene-writer-editor-card">
|
||||
<input type="hidden" name="Notes[@index].SceneNoteID" value="@note.SceneNoteID" />
|
||||
<input type="hidden" name="Notes[@index].SceneID" value="@Model.SceneID" />
|
||||
<input type="hidden" name="Notes[@index].SortOrder" value="@note.SortOrder" />
|
||||
<div class="scene-writer-editor-card-header">
|
||||
<div>
|
||||
<h4>@(string.IsNullOrWhiteSpace(note.NoteTitle) ? note.TypeName : note.NoteTitle)</h4>
|
||||
<p>@note.TypeName</p>
|
||||
</div>
|
||||
<label class="scene-writer-remove">
|
||||
<input type="checkbox" name="Notes[@index].Remove" value="true" />
|
||||
<input type="hidden" name="Notes[@index].Remove" value="false" />
|
||||
<span>Remove</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Notes_@(index)__SceneNoteTypeID">Type</label>
|
||||
<select class="form-control form-control-sm" id="Notes_@(index)__SceneNoteTypeID" name="Notes[@index].SceneNoteTypeID">
|
||||
@foreach (var option in Model.SceneNoteTypeOptions)
|
||||
{
|
||||
<option value="@option.Value" selected="@(option.Value == note.SceneNoteTypeID.ToString())">@option.Text</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Notes_@(index)__NoteTitle">Title</label>
|
||||
<input class="form-control form-control-sm" id="Notes_@(index)__NoteTitle" name="Notes[@index].NoteTitle" value="@note.NoteTitle" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Notes_@(index)__NoteText">Note text</label>
|
||||
<textarea class="form-control form-control-sm" id="Notes_@(index)__NoteText" name="Notes[@index].NoteText" rows="3">@note.NoteText</textarea>
|
||||
</div>
|
||||
|
||||
<div class="scene-inspector-editor-checks">
|
||||
<label>
|
||||
<input type="checkbox" name="Notes[@index].IsPinned" value="true" checked="@note.IsPinned" />
|
||||
<input type="hidden" name="Notes[@index].IsPinned" value="false" />
|
||||
<span>Pinned</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="Notes[@index].IsResolved" value="true" checked="@note.IsResolved" />
|
||||
<input type="hidden" name="Notes[@index].IsResolved" value="false" />
|
||||
<span>Resolved</span>
|
||||
</label>
|
||||
</div>
|
||||
</article>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
|
||||
<section class="scene-writer-editor-section">
|
||||
<div class="scene-writer-editor-heading">
|
||||
<span>Add note</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="NewNote_SceneNoteTypeID">Type</label>
|
||||
<select class="form-control form-control-sm" id="NewNote_SceneNoteTypeID" name="NewNote.SceneNoteTypeID" asp-items="Model.SceneNoteTypeOptions"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="NewNote_NoteTitle">Title</label>
|
||||
<input class="form-control form-control-sm" id="NewNote_NoteTitle" name="NewNote.NoteTitle" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="NewNote_NoteText">Note text</label>
|
||||
<textarea class="form-control form-control-sm" id="NewNote_NoteText" name="NewNote.NoteText" rows="3"></textarea>
|
||||
</div>
|
||||
<label class="scene-writer-inline-check">
|
||||
<input type="checkbox" name="NewNote.IsPinned" value="true" />
|
||||
<input type="hidden" name="NewNote.IsPinned" value="false" />
|
||||
<span>Pinned</span>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="scene-inspector-editor-footer">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" data-scene-editor-close>Cancel</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary" data-scene-editor-save>Save notes</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,61 @@
|
||||
@model SceneEditViewModel
|
||||
|
||||
<form asp-controller="Scenes" asp-action="SaveSceneWorkflow" method="post" class="scene-inspector-editor-form" data-scene-editor-form>
|
||||
@Html.AntiForgeryToken()
|
||||
<input type="hidden" asp-for="SceneID" />
|
||||
|
||||
<div class="scene-inspector-editor-error" data-scene-editor-error hidden></div>
|
||||
|
||||
<div class="scene-inspector-editor-fields">
|
||||
<section class="scene-writer-editor-section">
|
||||
<div class="scene-writer-editor-heading">
|
||||
<span>Workflow</span>
|
||||
</div>
|
||||
|
||||
<div class="scene-writer-editor-card">
|
||||
<div class="form-group">
|
||||
<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="scene-inspector-editor-grid">
|
||||
<div class="form-group">
|
||||
<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="form-group">
|
||||
<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>
|
||||
|
||||
<div class="scene-inspector-editor-grid">
|
||||
<div class="form-group">
|
||||
<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="form-group">
|
||||
<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>
|
||||
|
||||
<label class="scene-writer-inline-check">
|
||||
<input type="checkbox" name="IsBlocked" value="true" checked="@Model.Workflow.IsBlocked" />
|
||||
<input type="hidden" name="IsBlocked" value="false" />
|
||||
<span>Blocked</span>
|
||||
</label>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="BlockedReason">Blocked reason</label>
|
||||
<input class="form-control form-control-sm" id="BlockedReason" name="BlockedReason" value="@Model.Workflow.BlockedReason" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="scene-inspector-editor-footer">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" data-scene-editor-close>Cancel</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary" data-scene-editor-save>Save workflow</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -5,7 +5,7 @@
|
||||
var checklistLabel = total == 0 ? "No checklist yet" : $"{completed} of {total} complete";
|
||||
}
|
||||
|
||||
<article class="scene-inspector-v2-card">
|
||||
<article class="scene-inspector-v2-card" data-scene-summary-part="writer">
|
||||
<div class="scene-inspector-v2-card-header">
|
||||
<div>
|
||||
<p class="eyebrow">Writer</p>
|
||||
@ -37,8 +37,9 @@
|
||||
}
|
||||
|
||||
<div class="scene-inspector-v2-actions">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="notes" data-scene-id="@Model.SceneID">Manage notes</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="checklist" data-scene-id="@Model.SceneID">Manage checklist</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="notes" data-scene-id="@Model.SceneID" data-scene-editor-url="@Url.Action("SceneNotesEditor", "Scenes", new { sceneId = Model.SceneID })">Manage notes</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="checklist" data-scene-id="@Model.SceneID" data-scene-editor-url="@Url.Action("SceneChecklistEditor", "Scenes", new { sceneId = Model.SceneID })">Manage checklist</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="workflow" data-scene-id="@Model.SceneID" data-scene-editor-url="@Url.Action("SceneWorkflowEditor", "Scenes", new { sceneId = Model.SceneID })">Manage workflow</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-scene-editor="attachments" data-scene-id="@Model.SceneID">Manage attachments</button>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@ -5234,6 +5234,80 @@ body.scene-inspector-editor-resizing {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scene-writer-editor-section {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.scene-writer-editor-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
color: var(--plotline-muted);
|
||||
font-size: 0.76rem;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.scene-writer-editor-heading strong {
|
||||
border-radius: 999px;
|
||||
background: rgba(47, 111, 99, 0.1);
|
||||
padding: 2px 8px;
|
||||
color: var(--plotline-accent-dark);
|
||||
}
|
||||
|
||||
.scene-writer-editor-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.scene-writer-editor-card,
|
||||
.scene-writer-checklist-row {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
border: 1px solid var(--plotline-line);
|
||||
border-radius: 8px;
|
||||
background: rgba(47, 111, 99, 0.04);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.scene-writer-editor-card-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.scene-writer-editor-card-header h4 {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.scene-writer-editor-card-header p {
|
||||
margin: 2px 0 0;
|
||||
color: var(--plotline-muted);
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
.scene-writer-checklist-row {
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.scene-writer-remove,
|
||||
.scene-writer-checklist-complete,
|
||||
.scene-writer-inline-check {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: 0;
|
||||
color: var(--plotline-muted);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scene-inspector-v2-timeline .scene-inspector-v2-health {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@ -5282,6 +5356,11 @@ body.scene-inspector-editor-resizing {
|
||||
.scene-inspector-editor-checks {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.scene-writer-checklist-row {
|
||||
grid-template-columns: 1fr;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.floor-plan-toolbar-floor-group {
|
||||
|
||||
2
PlotLine/wwwroot/css/site.min.css
vendored
2
PlotLine/wwwroot/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
@ -12,6 +12,7 @@
|
||||
custody: "Manage custody",
|
||||
notes: "Manage notes",
|
||||
checklist: "Manage checklist",
|
||||
workflow: "Manage workflow",
|
||||
attachments: "Manage attachments",
|
||||
warnings: "Review warnings"
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user