Adding checkboxes to brief

This commit is contained in:
2026-08-23 23:16:54 +02:00
parent d53b183508
commit 0c4e0db118
2 changed files with 4 additions and 4 deletions
+1 -1
View File
@@ -1281,7 +1281,7 @@ function BriefPanel({ levelId, brief, goals, parties, recentlyCreatedExhibitId,
const checklist = brief.checklist || [] const checklist = brief.checklist || []
return <aside className={`brief-panel ${minimized ? 'minimized' : ''}`}><header onDoubleClick={() => setMinimized(value => !value)}><div><small>LEVEL BRIEF · {pending ? `${pending} OBJECTIVE${pending === 1 ? '' : 'S'} OPEN` : unresolved ? `${unresolved} UNRESOLVED` : 'READY'}</small><b>{heading}</b></div><span/><button type="button" aria-label={minimized ? 'Restore brief' : 'Minimize brief'} title={minimized ? 'Restore' : 'Minimize'} onDoubleClick={event => event.stopPropagation()} onClick={() => setMinimized(value => !value)}>{minimized ? <Plus size={14}/> : <Minus size={14}/>}</button><button type="button" aria-label="Close brief" title="Close" onDoubleClick={event => event.stopPropagation()} onClick={onClose}><X size={14}/></button></header> return <aside className={`brief-panel ${minimized ? 'minimized' : ''}`}><header onDoubleClick={() => setMinimized(value => !value)}><div><small>LEVEL BRIEF · {pending ? `${pending} OBJECTIVE${pending === 1 ? '' : 'S'} OPEN` : unresolved ? `${unresolved} UNRESOLVED` : 'READY'}</small><b>{heading}</b></div><span/><button type="button" aria-label={minimized ? 'Restore brief' : 'Minimize brief'} title={minimized ? 'Restore' : 'Minimize'} onDoubleClick={event => event.stopPropagation()} onClick={() => setMinimized(value => !value)}>{minimized ? <Plus size={14}/> : <Minus size={14}/>}</button><button type="button" aria-label="Close brief" title="Close" onDoubleClick={event => event.stopPropagation()} onClick={onClose}><X size={14}/></button></header>
<p>{assignment}</p> <p>{assignment}</p>
{checklist.length > 0 && <section className="brief-checklist"><h3><ClipboardCheck size={16}/> CHECKLIST</h3><ol>{checklist.map(item => { const done = checked.has(item.id); return <li key={item.id}><button type="button" className={done ? 'done' : ''} aria-pressed={done} onClick={() => toggleChecked(item.id)}><i>{done ? '☑' : '☐'}</i><span>{item.text}</span></button></li> })}</ol></section>} {checklist.length > 0 && <section className="brief-checklist"><h3><ClipboardCheck size={16}/> CHECKLIST</h3><ol>{checklist.map(item => { const done = checked.has(item.id); return <li key={item.id}><button type="button" className={done ? 'done' : ''} aria-pressed={done} onClick={() => toggleChecked(item.id)}><i>{done && <Check size={12} strokeWidth={3}/>}</i><span>{item.text}</span></button></li> })}</ol></section>}
{goals.length > 0 && <div className="brief-goals">{goals.map((goal, index) => <section className={goal.status} key={goal.key}><i>{goal.status === 'complete' ? '✓' : index + 1}</i><div><b>{goal.title}</b><span>{goal.instructions}</span></div><em>{goal.status === 'complete' ? 'VERIFIED' : 'OPEN'}</em></section>)}</div>} {goals.length > 0 && <div className="brief-goals">{goals.map((goal, index) => <section className={goal.status} key={goal.key}><i>{goal.status === 'complete' ? '✓' : index + 1}</i><div><b>{goal.title}</b><span>{goal.instructions}</span></div><em>{goal.status === 'complete' ? 'VERIFIED' : 'OPEN'}</em></section>)}</div>}
{brief.concepts.length > 0 && <><div className="brief-concepts">{brief.concepts.map(concept => { const resolved = concept.resolvedPartyExhibitId ? partyById.get(concept.resolvedPartyExhibitId) : undefined; return <section className={`${resolved ? 'resolved' : ''} ${resolved?.id === recentlyCreatedExhibitId ? 'just-resolved' : ''}`} key={concept.id}><div><b>{concept.label}</b><span>{concept.context}</span></div>{resolved ? <div className="resolved-actions"><span>{resolved.partyKind === 'person' ? <UserRound size={14}/> : <Building2 size={14}/>} {resolved.partyKind?.toUpperCase()}</span><button onClick={() => onLocate(resolved.id)}>LOCATE</button><button onClick={() => onEditParty(resolved.id)}>EDIT DOSSIER</button></div> : <div className="classify-actions"><button onClick={() => onClassify(concept.id, 'person')}><UserRound size={14}/> PERSON</button><button onClick={() => onClassify(concept.id, 'organization')}><Building2 size={14}/> ORGANIZATION</button></div>}</section> })}</div> {brief.concepts.length > 0 && <><div className="brief-concepts">{brief.concepts.map(concept => { const resolved = concept.resolvedPartyExhibitId ? partyById.get(concept.resolvedPartyExhibitId) : undefined; return <section className={`${resolved ? 'resolved' : ''} ${resolved?.id === recentlyCreatedExhibitId ? 'just-resolved' : ''}`} key={concept.id}><div><b>{concept.label}</b><span>{concept.context}</span></div>{resolved ? <div className="resolved-actions"><span>{resolved.partyKind === 'person' ? <UserRound size={14}/> : <Building2 size={14}/>} {resolved.partyKind?.toUpperCase()}</span><button onClick={() => onLocate(resolved.id)}>LOCATE</button><button onClick={() => onEditParty(resolved.id)}>EDIT DOSSIER</button></div> : <div className="classify-actions"><button onClick={() => onClassify(concept.id, 'person')}><UserRound size={14}/> PERSON</button><button onClick={() => onClassify(concept.id, 'organization')}><Building2 size={14}/> ORGANIZATION</button></div>}</section> })}</div>
<button className="new-party-from-brief" onClick={onNewParty}><Plus size={13}/> CREATE PARTY NOT LISTED ABOVE</button></>} <button className="new-party-from-brief" onClick={onNewParty}><Plus size={13}/> CREATE PARTY NOT LISTED ABOVE</button></>}
+3 -3
View File
@@ -260,10 +260,10 @@ button:focus-visible { outline: 2px solid #e99a44; outline-offset: 2px; }
.brief-checklist { margin: 0 16px 18px; padding: 14px 15px 15px; background: #d8d8cd; border: 1px solid #929991; } .brief-checklist { margin: 0 16px 18px; padding: 14px 15px 15px; background: #d8d8cd; border: 1px solid #929991; }
.brief-checklist h3 { margin: 0 0 11px; display: flex; align-items: center; gap: 7px; color: #59442f; font: 600 9px IBM Plex Mono; letter-spacing: .1em; } .brief-checklist h3 { margin: 0 0 11px; display: flex; align-items: center; gap: 7px; color: #59442f; font: 600 9px IBM Plex Mono; letter-spacing: .1em; }
.brief-checklist ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; } .brief-checklist ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.brief-checklist button { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 9px; align-items: start; width: 100%; padding: 5px 6px; text-align: left; cursor: pointer; background: transparent; border: 0; color: #2c3834; font: 12px/1.45 Special Elite; } .brief-checklist button { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; align-items: start; width: 100%; padding: 5px 6px; text-align: left; cursor: pointer; background: transparent; border: 0; color: #2c3834; font: 12px/1.45 Special Elite; }
.brief-checklist button:hover { background: #e4e3d6; } .brief-checklist button:hover { background: #e4e3d6; }
.brief-checklist button > i { justify-self: center; font-style: normal; font-size: 16px; line-height: 1.25; color: #8a6747; } .brief-checklist button > i { margin-top: 1px; width: 17px; height: 17px; display: grid; place-items: center; border: 1.5px solid #8a6747; background: #e5e0d2; color: #f1f1e7; }
.brief-checklist button.done > i { color: #437558; } .brief-checklist button.done > i { border-color: #437558; background: #4d7f60; }
.brief-checklist button.done > span { color: #5b6862; text-decoration: line-through; } .brief-checklist button.done > span { color: #5b6862; text-decoration: line-through; }
.brief-goals { margin: 0 16px 16px; display: grid; gap: 7px; }.brief-goals section { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 9px; align-items: center; padding: 10px; border: 1px solid #89928b; background: #d5d5ca; }.brief-goals section > i { width: 25px; height: 25px; display: grid; place-items: center; border: 1px solid #9b6232; border-radius: 50%; color: #854d25; font: 600 10px IBM Plex Mono; font-style: normal; }.brief-goals section > div { display: grid; gap: 4px; }.brief-goals b { color: #293b35; font: 600 9px IBM Plex Mono; }.brief-goals span { color: #5b6862; font: 10px/1.4 Special Elite; }.brief-goals em { color: #9a5f2e; font: 600 7px IBM Plex Mono; font-style: normal; letter-spacing: .08em; }.brief-goals section.complete { background: #cbd9cc; border-color: #78927d; }.brief-goals section.complete > i { border-color: #437558; background: #4d7f60; color: #f1f1e7; }.brief-goals section.complete em { color: #34644a; } .brief-goals { margin: 0 16px 16px; display: grid; gap: 7px; }.brief-goals section { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 9px; align-items: center; padding: 10px; border: 1px solid #89928b; background: #d5d5ca; }.brief-goals section > i { width: 25px; height: 25px; display: grid; place-items: center; border: 1px solid #9b6232; border-radius: 50%; color: #854d25; font: 600 10px IBM Plex Mono; font-style: normal; }.brief-goals section > div { display: grid; gap: 4px; }.brief-goals b { color: #293b35; font: 600 9px IBM Plex Mono; }.brief-goals span { color: #5b6862; font: 10px/1.4 Special Elite; }.brief-goals em { color: #9a5f2e; font: 600 7px IBM Plex Mono; font-style: normal; letter-spacing: .08em; }.brief-goals section.complete { background: #cbd9cc; border-color: #78927d; }.brief-goals section.complete > i { border-color: #437558; background: #4d7f60; color: #f1f1e7; }.brief-goals section.complete em { color: #34644a; }
.brief-concepts { border-top: 1px solid #8c958e; }.brief-concepts section { padding: 12px 15px; border-bottom: 1px solid #959c95; }.brief-concepts section.resolved { background: #d5ddcf; }.brief-concepts section.just-resolved { animation: concept-resolved 1.15s ease-out; }.brief-concepts section > div:first-child { display: grid; gap: 4px; }.brief-concepts b { font: 600 10px IBM Plex Mono; }.brief-concepts span { color: #616d67; font: 9px Special Elite; } .brief-concepts { border-top: 1px solid #8c958e; }.brief-concepts section { padding: 12px 15px; border-bottom: 1px solid #959c95; }.brief-concepts section.resolved { background: #d5ddcf; }.brief-concepts section.just-resolved { animation: concept-resolved 1.15s ease-out; }.brief-concepts section > div:first-child { display: grid; gap: 4px; }.brief-concepts b { font: 600 10px IBM Plex Mono; }.brief-concepts span { color: #616d67; font: 9px Special Elite; }