fix: pin Writing toolbar and Entities header, fix Entities form alignment and red hint text, and make Settings category bar horizontal
This commit is contained in:
@@ -127,138 +127,144 @@ export function EntitiesView() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ps-entities-view" style={{ padding: "20px 24px", overflowY: "auto" }}>
|
||||
<div className="ps-entity-toolbar">
|
||||
<div className="ps-entity-tabs">
|
||||
{TABS.map((t) => (
|
||||
<div key={t.id} className={"ps-entity-tab-wrap" + (t.id === tab ? " active" : "")}>
|
||||
<button
|
||||
type="button"
|
||||
className={"ps-entity-tab" + (t.id === tab ? " active" : "")}
|
||||
onClick={() => setTab(t.id)}
|
||||
>
|
||||
{t.label}
|
||||
</button>
|
||||
{t.createKind && (
|
||||
<div className="ps-entities-view">
|
||||
<div className="ps-entities-pinned-header">
|
||||
<div className="ps-entity-toolbar">
|
||||
<div className="ps-entity-tabs">
|
||||
{TABS.map((t) => (
|
||||
<div key={t.id} className={"ps-entity-tab-wrap" + (t.id === tab ? " active" : "")}>
|
||||
<button
|
||||
type="button"
|
||||
className="ps-entity-tab-add"
|
||||
title={t.createLabel ?? `Add to ${t.label}`}
|
||||
aria-label={t.createLabel ?? `Add to ${t.label}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
void handleCreateKind(t.createKind!, t.id);
|
||||
}}
|
||||
className={"ps-entity-tab" + (t.id === tab ? " active" : "")}
|
||||
onClick={() => setTab(t.id)}
|
||||
>
|
||||
+
|
||||
{t.label}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="ps-entity-new-group">
|
||||
{activeTabDef.createKind ? (
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind(activeTabDef.createKind!)}
|
||||
>
|
||||
{activeTabDef.createLabel}
|
||||
</Button>
|
||||
) : tab === "all" ? (
|
||||
<>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("character", "people")}
|
||||
>
|
||||
+ Person
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("world", "places")}
|
||||
>
|
||||
+ World Item
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("note", "notes")}
|
||||
>
|
||||
+ Note
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ps-entity-search">
|
||||
<Input
|
||||
className="ps-entity-search-input"
|
||||
placeholder="Search people, places, world items, and notes…"
|
||||
value={query}
|
||||
onChange={(ev) => setQuery(ev.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{tab === "consistency" ? (
|
||||
<ConsistencyPanel
|
||||
issues={issues}
|
||||
onOpenEntity={(id) => {
|
||||
const e = entities.find((x) => x.id === id);
|
||||
if (e) {
|
||||
setDraft(e);
|
||||
setOpen(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : visible.length === 0 ? (
|
||||
<div className="ps-emptystate">
|
||||
<div className="ps-emptystate-title">No entities in this view yet</div>
|
||||
<p className="ps-muted">
|
||||
{activeTabDef.createKind
|
||||
? `Click "${activeTabDef.createLabel}" or the + button on the tab to create one.`
|
||||
: "Use the + buttons on the People, Places & World, or Notes tabs to add story entities."}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="ps-entity-grid">
|
||||
{visible.map((e) => (
|
||||
<button
|
||||
key={e.id}
|
||||
type="button"
|
||||
className="ps-entity-card"
|
||||
onClick={() => openEntity(e)}
|
||||
>
|
||||
<div className="ps-entity-card-top">
|
||||
<span className="ps-entity-type-badge">{badgeFor(e)}</span>
|
||||
{t.createKind && (
|
||||
<button
|
||||
type="button"
|
||||
className="ps-entity-tab-add"
|
||||
title={t.createLabel ?? `Add to ${t.label}`}
|
||||
aria-label={t.createLabel ?? `Add to ${t.label}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
void handleCreateKind(t.createKind!, t.id);
|
||||
}}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="ps-entity-card-name">{entityLabel(e)}</div>
|
||||
<div className="ps-entity-card-sub">{subFor(e)}</div>
|
||||
{tagsFor(e).length > 0 && (
|
||||
<div className="ps-entity-card-tags">
|
||||
{tagsFor(e).slice(0, 4).map((t) => (
|
||||
<span key={t} className="ps-entity-tag">
|
||||
{t}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
|
||||
<EntityEditor
|
||||
entity={draft}
|
||||
entities={entities}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
onSave={save}
|
||||
onDelete={remove}
|
||||
/>
|
||||
<div className="ps-entity-new-group">
|
||||
{activeTabDef.createKind ? (
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind(activeTabDef.createKind!)}
|
||||
>
|
||||
{activeTabDef.createLabel}
|
||||
</Button>
|
||||
) : tab === "all" ? (
|
||||
<>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("character", "people")}
|
||||
>
|
||||
+ Person
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("world", "places")}
|
||||
>
|
||||
+ World Item
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => void handleCreateKind("note", "notes")}
|
||||
>
|
||||
+ Note
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ps-entity-search">
|
||||
<Input
|
||||
className="ps-entity-search-input"
|
||||
placeholder="Search people, places, world items, and notes…"
|
||||
value={query}
|
||||
onChange={(ev) => setQuery(ev.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ps-entities-body">
|
||||
<div className="ps-entities-main">
|
||||
{tab === "consistency" ? (
|
||||
<ConsistencyPanel
|
||||
issues={issues}
|
||||
onOpenEntity={(id) => {
|
||||
const e = entities.find((x) => x.id === id);
|
||||
if (e) {
|
||||
setDraft(e);
|
||||
setOpen(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : visible.length === 0 ? (
|
||||
<div className="ps-emptystate">
|
||||
<div className="ps-emptystate-title">No entities in this view yet</div>
|
||||
<p className="ps-muted">
|
||||
{activeTabDef.createKind
|
||||
? `Click "${activeTabDef.createLabel}" or the + button on the tab to create one.`
|
||||
: "Use the + buttons on the People, Places & World, or Notes tabs to add story entities."}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="ps-entity-grid">
|
||||
{visible.map((e) => (
|
||||
<button
|
||||
key={e.id}
|
||||
type="button"
|
||||
className={`ps-entity-card${open && draft?.id === e.id ? " is-selected" : ""}`}
|
||||
onClick={() => openEntity(e)}
|
||||
>
|
||||
<div className="ps-entity-card-top">
|
||||
<span className="ps-entity-type-badge">{badgeFor(e)}</span>
|
||||
</div>
|
||||
<div className="ps-entity-card-name">{entityLabel(e)}</div>
|
||||
<div className="ps-entity-card-sub">{subFor(e)}</div>
|
||||
{tagsFor(e).length > 0 && (
|
||||
<div className="ps-entity-card-tags">
|
||||
{tagsFor(e).slice(0, 4).map((t) => (
|
||||
<span key={t} className="ps-entity-tag">
|
||||
{t}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<EntityEditor
|
||||
entity={draft}
|
||||
entities={entities}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
onSave={save}
|
||||
onDelete={remove}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user