ui(sidebar): split editable vs read-only between Edit and Metadata
The Metadata collapsible was hosting two editable widgets (TagsEditor and TakenAtEditor) buried inside the readonly sub-sections — Tags as its own Section, taken-at wedged into Basic Info between size/dims and the filepath. With both top-level collapsibles in place, the clearer split is editable up top, readonly below. Moved into the Edit collapsible (in identification → description → categorization order): Filename, Title, Date Taken, Notes, Tags, Rating, Color, Flag Metadata now holds only readonly sub-sections: Basic Info (size, dims, path), Camera, Location Dropped the now-empty Tags Section from Metadata and the 'tags' key from the default-expanded set. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -143,7 +143,7 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
|
|||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
const [expandedSections, setExpandedSections] = useState<Set<string>>(
|
const [expandedSections, setExpandedSections] = useState<Set<string>>(
|
||||||
new Set(['edit', 'metadata', 'basic', 'camera', 'location', 'tags'])
|
new Set(['edit', 'metadata', 'basic', 'camera', 'location'])
|
||||||
)
|
)
|
||||||
const toggleSection = (section: string) => {
|
const toggleSection = (section: string) => {
|
||||||
const next = new Set(expandedSections)
|
const next = new Set(expandedSections)
|
||||||
@@ -447,6 +447,14 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<TakenAtEditor
|
||||||
|
photo={photo}
|
||||||
|
draft={takenAtDraft}
|
||||||
|
onDraftChange={setTakenAtDraft}
|
||||||
|
onCommit={commitTakenAt}
|
||||||
|
darkTheme={darkTheme}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-1 block text-xs text-text-muted">Notes</label>
|
<label className="mb-1 block text-xs text-text-muted">Notes</label>
|
||||||
<Textarea
|
<Textarea
|
||||||
@@ -459,6 +467,22 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="mb-1 block text-xs text-text-muted">Tags</label>
|
||||||
|
<TagsEditor
|
||||||
|
photoTags={photo.tags ?? []}
|
||||||
|
allTags={allTags}
|
||||||
|
tagInput={tagInput}
|
||||||
|
onTagInputChange={setTagInput}
|
||||||
|
onAttachExisting={(id) => attachExistingTagMutation.mutate(id)}
|
||||||
|
onCreateAndAttach={(name) => {
|
||||||
|
addTagMutation.mutate(name)
|
||||||
|
setTagInput('')
|
||||||
|
}}
|
||||||
|
onRemove={(id) => removeTagMutation.mutate(id)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Rating */}
|
{/* Rating */}
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-1 block text-xs text-text-muted">Rating</label>
|
<label className="mb-1 block text-xs text-text-muted">Rating</label>
|
||||||
@@ -581,25 +605,6 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
|
|||||||
)}
|
)}
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
<CollapsibleContent>
|
<CollapsibleContent>
|
||||||
<Section
|
|
||||||
title="Tags"
|
|
||||||
expanded={expandedSections.has('tags')}
|
|
||||||
onToggle={() => toggleSection('tags')}
|
|
||||||
>
|
|
||||||
<TagsEditor
|
|
||||||
photoTags={photo.tags ?? []}
|
|
||||||
allTags={allTags}
|
|
||||||
tagInput={tagInput}
|
|
||||||
onTagInputChange={setTagInput}
|
|
||||||
onAttachExisting={(id) => attachExistingTagMutation.mutate(id)}
|
|
||||||
onCreateAndAttach={(name) => {
|
|
||||||
addTagMutation.mutate(name)
|
|
||||||
setTagInput('')
|
|
||||||
}}
|
|
||||||
onRemove={(id) => removeTagMutation.mutate(id)}
|
|
||||||
/>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<Section
|
<Section
|
||||||
title="Basic Info"
|
title="Basic Info"
|
||||||
expanded={expandedSections.has('basic')}
|
expanded={expandedSections.has('basic')}
|
||||||
@@ -616,13 +621,6 @@ export function PhotoInfoPanel({ photoId, darkTheme = false }: PhotoInfoPanelPro
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<TakenAtEditor
|
|
||||||
photo={photo}
|
|
||||||
draft={takenAtDraft}
|
|
||||||
onDraftChange={setTakenAtDraft}
|
|
||||||
onCommit={commitTakenAt}
|
|
||||||
darkTheme={darkTheme}
|
|
||||||
/>
|
|
||||||
{/* Filepath spans the full sidebar width — most paths are long
|
{/* Filepath spans the full sidebar width — most paths are long
|
||||||
* enough that the two-column grid above wraps them painfully.
|
* enough that the two-column grid above wraps them painfully.
|
||||||
* Mono so each character lines up under the next, break-all
|
* Mono so each character lines up under the next, break-all
|
||||||
|
|||||||
Reference in New Issue
Block a user