fix: guard against undefined pinnedProperties + lint fixes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Test
2026-03-25 10:32:11 +01:00
parent 6665d646fb
commit 660208a6fd
2 changed files with 40 additions and 21 deletions

View File

@@ -46,11 +46,16 @@ function PropertyPinMenu({ x, y, isPinned, onPin, onUnpin, onClose }: {
}, [onClose])
return (
<div ref={ref} className="fixed z-50 flex flex-col rounded-lg border border-border bg-popover shadow-lg" style={{ left: x, top: y, minWidth: 160, padding: 4 }} data-testid="property-context-menu">
<div
ref={ref}
className="fixed z-50 flex flex-col rounded-lg border border-border bg-popover shadow-lg"
style={{ left: x, top: y, minWidth: 160, padding: 4 }}
data-testid="property-context-menu"
>
<button
className="flex w-full items-center gap-2 rounded px-2.5 py-1.5 text-left text-[13px] text-foreground transition-colors hover:bg-accent"
style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}
onClick={() => { if (isPinned) onUnpin(); else onPin(); onClose() }}
onClick={() => { if (isPinned) { onUnpin() } else { onPin() } onClose() }}
>
<PushPin size={14} />
{isPinned ? 'Unpin from editor' : 'Pin to editor'}

View File

@@ -101,6 +101,37 @@ function noteItemStyle(isSelected: boolean, isMultiSelected: boolean, typeColor:
return base
}
function NoteItemTitle({ entry, noteStatus, isSelected }: { entry: VaultEntry; noteStatus: NoteStatus; isSelected: boolean }) {
return (
<div className="pr-5">
<div className={cn("truncate text-[13px] text-foreground", isSelected ? "font-semibold" : "font-medium")}>
{noteStatus !== 'clean' && <StatusDot noteStatus={noteStatus} />}
{entry.icon && isEmoji(entry.icon) && <span className="mr-1">{entry.icon}</span>}
{entry.title}
<StateBadge archived={entry.archived} trashed={entry.trashed} />
</div>
</div>
)
}
function NoteItemFooter({ entry, pinnedConfigs }: { entry: VaultEntry; pinnedConfigs: PinnedPropertyConfig[] }) {
return (
<>
{entry.snippet && (
<div className="mt-0.5 text-[12px] leading-[1.5] text-muted-foreground" data-testid="note-snippet" style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
{entry.snippet}
</div>
)}
{pinnedConfigs.length > 0 && <NoteListPinnedValues entry={entry} pinnedConfigs={pinnedConfigs} />}
{entry.trashed && entry.trashedAt
? <TrashDateLine entry={entry} />
: <div className="mt-0.5 text-[10px] text-muted-foreground">{relativeDate(getDisplayDate(entry))}</div>
}
</>
)
}
export function NoteItem({ entry, isSelected, isMultiSelected = false, isHighlighted = false, noteStatus = 'clean', typeEntryMap, onClickNote, onPrefetch }: {
entry: VaultEntry
isSelected: boolean
@@ -136,25 +167,8 @@ export function NoteItem({ entry, isSelected, isMultiSelected = false, isHighlig
>
{/* eslint-disable-next-line react-hooks/static-components -- icon lookup from static map, no internal state */}
<TypeIcon width={14} height={14} className="absolute right-3 top-2.5" style={{ color: typeColor }} data-testid="type-icon" />
<div className="pr-5">
<div className={cn("truncate text-[13px] text-foreground", isSelected ? "font-semibold" : "font-medium")}>
{noteStatus !== 'clean' && <StatusDot noteStatus={noteStatus} />}
{entry.icon && isEmoji(entry.icon) && <span className="mr-1">{entry.icon}</span>}
{entry.title}
<StateBadge archived={entry.archived} trashed={entry.trashed} />
</div>
</div>
{entry.snippet && (
<div className="mt-0.5 text-[12px] leading-[1.5] text-muted-foreground" data-testid="note-snippet" style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>
{entry.snippet}
</div>
)}
{pinnedConfigs.length > 0 && <NoteListPinnedValues entry={entry} pinnedConfigs={pinnedConfigs} />}
{pinnedConfigs.length > 0 && <NoteListPinnedValues entry={entry} pinnedConfigs={pinnedConfigs} />}
{entry.trashed && entry.trashedAt
? <TrashDateLine entry={entry} />
: <div className="mt-0.5 text-[10px] text-muted-foreground">{relativeDate(getDisplayDate(entry))}</div>
}
<NoteItemTitle entry={entry} noteStatus={noteStatus} isSelected={isSelected} />
<NoteItemFooter entry={entry} pinnedConfigs={pinnedConfigs} />
</div>
)
}