refactor(document): extract shared DocumentOption type and createDocumentTypeahead factory
DocumentPickerDropdown and DocumentMultiSelect had identical createTypeahead configs, fetch logic, and formatDocLabel helpers. Extracted to documentTypeahead.ts; all four consumers import from the shared module. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { components } from '$lib/generated/api';
|
||||
import { m } from '$lib/paraglide/messages.js';
|
||||
import { clickOutside } from '$lib/shared/actions/clickOutside';
|
||||
import { createTypeahead } from '$lib/shared/hooks/useTypeahead.svelte';
|
||||
import { formatDocumentDate, type DatePrecision } from '$lib/shared/utils/documentDate';
|
||||
import { getLocale } from '$lib/paraglide/runtime.js';
|
||||
|
||||
type DocumentListItem = components['schemas']['DocumentListItem'];
|
||||
type DocumentOption = Pick<
|
||||
DocumentListItem,
|
||||
'id' | 'title' | 'documentDate' | 'metaDatePrecision' | 'metaDateEnd'
|
||||
>;
|
||||
import {
|
||||
createDocumentTypeahead,
|
||||
formatDocumentOption,
|
||||
type DocumentOption
|
||||
} from './documentTypeahead';
|
||||
|
||||
interface Props {
|
||||
alreadyAddedIds?: Set<string>;
|
||||
@@ -26,20 +21,7 @@ let {
|
||||
|
||||
const listboxId = 'doc-picker-listbox';
|
||||
|
||||
const picker = createTypeahead<DocumentOption>({
|
||||
fetchUrl: (q) =>
|
||||
fetch(`/api/documents/search?q=${encodeURIComponent(q)}&size=10`)
|
||||
.then((r) => r.json())
|
||||
.then((b: { items: DocumentListItem[] }) =>
|
||||
b.items.map((it) => ({
|
||||
id: it.id,
|
||||
title: it.title,
|
||||
documentDate: it.documentDate,
|
||||
metaDatePrecision: it.metaDatePrecision,
|
||||
metaDateEnd: it.metaDateEnd
|
||||
}))
|
||||
)
|
||||
});
|
||||
const picker = createDocumentTypeahead();
|
||||
|
||||
let inputValue = $state('');
|
||||
|
||||
@@ -59,18 +41,6 @@ function handleSelect(doc: DocumentOption) {
|
||||
picker.close();
|
||||
onSelect(doc);
|
||||
}
|
||||
|
||||
function formatDocLabel(doc: DocumentOption): string {
|
||||
if (!doc.documentDate) return doc.title;
|
||||
const label = formatDocumentDate(
|
||||
doc.documentDate,
|
||||
doc.metaDatePrecision as DatePrecision,
|
||||
doc.metaDateEnd,
|
||||
null,
|
||||
getLocale()
|
||||
);
|
||||
return `${doc.title} · ${label}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:clickOutside onclickoutside={() => picker.close()} class="relative">
|
||||
@@ -113,7 +83,7 @@ function formatDocLabel(doc: DocumentOption): string {
|
||||
: 'cursor-pointer hover:bg-muted focus:bg-muted focus:outline-none'
|
||||
].join(' ')}
|
||||
>
|
||||
{formatDocLabel(doc)}
|
||||
{formatDocumentOption(doc)}
|
||||
{#if disabled}
|
||||
<span class="sr-only">{m.journey_already_added()}</span>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user