Files
tolaria/src/components/TypeCustomizePopover.tsx

258 lines
7.7 KiB
TypeScript
Raw Normal View History

feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
import { useState, useMemo, useCallback, useRef, useEffect } from 'react'
import { MagnifyingGlass } from '@phosphor-icons/react'
import { ICON_OPTIONS, type IconEntry } from '../utils/iconRegistry'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { translate, type AppLocale } from '../lib/i18n'
2026-05-11 16:37:06 +02:00
import { AccentColorPicker } from './AccentColorPicker'
function filterIcons(icons: IconEntry[], query: string): IconEntry[] {
if (!query) return icons
const lower = query.toLowerCase()
return icons.filter((o) => o.name.includes(lower))
}
interface TypeCustomizePopoverProps {
currentIcon: string | null
currentColor: string | null
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
currentTemplate: string | null
onChangeIcon: (icon: string) => void
onChangeColor: (color: string) => void
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
onChangeTemplate: (template: string) => void
onClose: () => void
showTemplate?: boolean
showDone?: boolean
surface?: 'popover' | 'inline'
locale?: AppLocale
}
interface ColorSectionProps {
selectedColor: string | null
locale: AppLocale
onSelectColor: (key: string) => void
}
interface IconSectionProps {
selectedIcon: string | null
search: string
filteredIcons: IconEntry[]
locale: AppLocale
onSearchChange: (query: string) => void
onSelectIcon: (name: string) => void
}
interface TemplateSectionProps {
templateText: string
locale: AppLocale
onTemplateChange: (value: string) => void
}
2026-05-02 10:02:57 +02:00
const ICON_PICKER_ICON_SIZE = 18
const ICON_PICKER_ICON_CLASS_NAME = 'size-[18px]'
2026-05-17 19:15:55 +02:00
interface DebouncedCallback {
flush: () => void
run: (value: string) => void
}
/** Debounce a callback by `delay` ms. Pending work is flushed on unmount. */
function useDebouncedCallback(fn: (v: string) => void, delay: number): DebouncedCallback {
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
2026-05-17 19:15:55 +02:00
const pendingValueRef = useRef<string | null>(null)
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
const fnRef = useRef(fn)
useEffect(() => { fnRef.current = fn })
2026-05-17 19:15:55 +02:00
const flush = useCallback(() => {
clearTimeout(timerRef.current)
timerRef.current = undefined
if (pendingValueRef.current === null) return
const value = pendingValueRef.current
pendingValueRef.current = null
fnRef.current(value)
}, [])
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
2026-05-17 19:15:55 +02:00
const run = useCallback((value: string) => {
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
clearTimeout(timerRef.current)
2026-05-17 19:15:55 +02:00
pendingValueRef.current = value
timerRef.current = setTimeout(flush, delay)
}, [delay, flush])
useEffect(() => () => { flush() }, [flush])
return useMemo(() => ({ flush, run }), [flush, run])
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
}
function ColorSection({ selectedColor, locale, onSelectColor }: ColorSectionProps) {
return (
<>
<div className="font-mono-overline mb-2 text-muted-foreground">{translate(locale, 'customize.color')}</div>
2026-05-11 16:37:06 +02:00
<AccentColorPicker
className="mb-3 gap-2"
selectedColor={selectedColor}
onSelectColor={onSelectColor}
size={24}
/>
</>
)
}
function IconSection({
selectedIcon,
search,
filteredIcons,
locale,
onSearchChange,
onSelectIcon,
}: IconSectionProps) {
return (
<>
<div className="font-mono-overline mb-2 text-muted-foreground">{translate(locale, 'customize.icon')}</div>
<div className="relative mb-2">
<MagnifyingGlass
size={14}
className="absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none"
/>
<Input
type="text"
value={search}
onChange={(event) => onSearchChange(event.target.value)}
placeholder={translate(locale, 'customize.searchIcons')}
className="h-7 pl-7 pr-2 py-1 text-[12px]"
/>
</div>
2026-05-02 10:02:57 +02:00
<div
className="grid gap-1 overflow-y-auto"
style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(30px, 1fr))', maxHeight: 160 }}
>
{filteredIcons.length === 0 ? (
<div className="w-full py-6 text-center text-[12px] text-muted-foreground">
{translate(locale, 'customize.noIconsFound')}
</div>
) : (
filteredIcons.map(({ name, Icon }) => (
<Button
key={name}
type="button"
variant="ghost"
size="icon-xs"
className={cn(
2026-05-02 10:02:57 +02:00
'h-[30px] w-[30px] justify-self-center rounded p-0 transition-colors',
selectedIcon === name
? 'bg-primary/10 text-primary'
: 'text-muted-foreground hover:bg-accent hover:text-foreground',
)}
onClick={() => onSelectIcon(name)}
title={name}
aria-label={name}
>
2026-05-02 10:02:57 +02:00
<Icon size={ICON_PICKER_ICON_SIZE} className={ICON_PICKER_ICON_CLASS_NAME} />
</Button>
))
)}
</div>
</>
)
}
function TemplateSection({ templateText, locale, onTemplateChange }: TemplateSectionProps) {
return (
<>
<div className="font-mono-overline mb-2 mt-3 text-muted-foreground">{translate(locale, 'customize.template')}</div>
<Textarea
value={templateText}
onChange={(event) => onTemplateChange(event.target.value)}
placeholder={translate(locale, 'customize.templatePlaceholder')}
className="min-h-20 max-h-[200px] resize-y px-2 py-1.5 text-[12px] font-mono"
data-testid="template-textarea"
/>
</>
)
}
function DoneSection({ locale, onClose }: { locale: AppLocale; onClose: () => void }) {
return (
<div className="mt-3 flex justify-end">
<Button
type="button"
variant="ghost"
size="xs"
className="text-muted-foreground hover:text-foreground"
onClick={onClose}
>
{translate(locale, 'customize.done')}
</Button>
</div>
)
}
export function TypeCustomizePopover({
currentIcon,
currentColor,
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
currentTemplate,
onChangeIcon,
onChangeColor,
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
onChangeTemplate,
onClose,
showTemplate = true,
showDone = true,
surface = 'popover',
locale = 'en',
}: TypeCustomizePopoverProps) {
const [selectedColor, setSelectedColor] = useState(currentColor)
const [selectedIcon, setSelectedIcon] = useState(currentIcon)
const [search, setSearch] = useState('')
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
const [templateText, setTemplateText] = useState(currentTemplate ?? '')
const filteredIcons = useMemo(() => filterIcons(ICON_OPTIONS, search), [search])
2026-05-17 19:15:55 +02:00
const debouncedSaveTemplate = useDebouncedCallback(onChangeTemplate, 500)
const handleColorClick = (key: string) => {
setSelectedColor(key)
onChangeColor(key)
}
const handleIconClick = (name: string) => {
setSelectedIcon(name)
onChangeIcon(name)
}
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
const handleTemplateChange = (value: string) => {
setTemplateText(value)
2026-05-17 19:15:55 +02:00
debouncedSaveTemplate.run(value)
}
const handleDone = () => {
debouncedSaveTemplate.flush()
onClose()
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
}
return (
<div
className={cn(
'text-popover-foreground z-50',
surface === 'popover' && 'rounded-lg border bg-popover shadow-md',
)}
style={surface === 'popover' ? { width: 320, padding: 12 } : undefined}
onClick={(e) => e.stopPropagation()}
onContextMenu={(e) => e.stopPropagation()}
>
<ColorSection selectedColor={selectedColor} locale={locale} onSelectColor={handleColorClick} />
<IconSection
selectedIcon={selectedIcon}
search={search}
filteredIcons={filteredIcons}
locale={locale}
onSearchChange={setSearch}
onSelectIcon={handleIconClick}
feat: note templates per type (💡 Note templates per tipo) (#170) * feat: add template field to type entries and template-aware note creation - Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS - Rust: support YAML block scalar (|) for multi-line strings in frontmatter - Rust: fix value continuation detection to handle block scalars properly - TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch - Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment - resolveNewNote/buildNoteContent accept optional template parameter - handleCreateNote and handleCreateNoteImmediate look up type template - Tests for all new behavior (Rust + TypeScript) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section - Add template textarea with debounced save to TypeCustomizePopover - Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App - Add useDebouncedCallback hook for 500ms template save debounce - Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI - Create design/note-templates.pen placeholder Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: useRef type arg + template field in bulk mock entries * style: rustfmt --------- Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 08:37:06 +01:00
/>
{showTemplate && (
<TemplateSection templateText={templateText} locale={locale} onTemplateChange={handleTemplateChange} />
)}
2026-05-17 19:15:55 +02:00
{showDone && <DoneSection locale={locale} onClose={handleDone} />}
</div>
)
}