fix(person): type mention items as PersonSummaryDTO, regenerate api
The dropdown and editor typed /api/persons list items as the full Person entity. The actual wire shape is PersonSummaryDTO, which until the previous commit had no date fields - so the life-date subtitle rendered blank in production while fixtures (built from the entity type) kept the tests green. Retype items as the summary projection and guard the two personId consumers against the schema-optional id. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2381,6 +2381,14 @@ export interface components {
|
||||
documentCount?: number;
|
||||
alias?: string;
|
||||
notes?: string;
|
||||
/** Format: date */
|
||||
birthDate?: string;
|
||||
/** @enum {string} */
|
||||
birthDatePrecision?: "DAY" | "MONTH" | "SEASON" | "YEAR" | "RANGE" | "APPROX" | "UNKNOWN";
|
||||
/** Format: date */
|
||||
deathDate?: string;
|
||||
/** @enum {string} */
|
||||
deathDatePrecision?: "DAY" | "MONTH" | "SEASON" | "YEAR" | "RANGE" | "APPROX" | "UNKNOWN";
|
||||
personType?: string;
|
||||
familyMember?: boolean;
|
||||
provisional?: boolean;
|
||||
@@ -2490,10 +2498,10 @@ export interface components {
|
||||
/** Format: int32 */
|
||||
number?: number;
|
||||
sort?: components["schemas"]["SortObject"];
|
||||
first?: boolean;
|
||||
last?: boolean;
|
||||
/** Format: int32 */
|
||||
numberOfElements?: number;
|
||||
first?: boolean;
|
||||
last?: boolean;
|
||||
empty?: boolean;
|
||||
};
|
||||
PageableObject: {
|
||||
|
||||
@@ -15,7 +15,9 @@ import { m } from '$lib/paraglide/messages.js';
|
||||
// — see Felix #3 on PR #629.
|
||||
import { MAX_QUERY_LENGTH } from './mentionConstants';
|
||||
|
||||
type Person = components['schemas']['Person'];
|
||||
// PersonSummaryDTO, not Person: /api/persons list items are the summary projection.
|
||||
// Typing them as the full entity hid a runtime bug (missing date fields, #812).
|
||||
type Person = components['schemas']['PersonSummaryDTO'];
|
||||
|
||||
// The dropdown receives a single reactive state object. PersonMentionEditor
|
||||
// mutates fields on this object (model.items = ..., etc.) and Svelte's $state
|
||||
|
||||
@@ -7,7 +7,9 @@ import MentionDropdownFixture from './MentionDropdown.test-fixture.svelte';
|
||||
import { m } from '$lib/paraglide/messages.js';
|
||||
import type { components } from '$lib/generated/api';
|
||||
|
||||
type Person = components['schemas']['Person'];
|
||||
// PersonSummaryDTO mirrors the real runtime shape: /api/persons list items are
|
||||
// the summary projection, not the full entity (#812).
|
||||
type Person = components['schemas']['PersonSummaryDTO'];
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { untrack } from 'svelte';
|
||||
import MentionDropdown from './MentionDropdown.svelte';
|
||||
import type { components } from '$lib/generated/api';
|
||||
|
||||
type Person = components['schemas']['Person'];
|
||||
type Person = components['schemas']['PersonSummaryDTO'];
|
||||
type DropdownState = {
|
||||
items: Person[];
|
||||
command: (item: Person) => void;
|
||||
|
||||
@@ -12,7 +12,9 @@ import MentionDropdown from './MentionDropdown.svelte';
|
||||
import { createMentionNodeView } from './mentionNodeView';
|
||||
import { MAX_QUERY_LENGTH, SEARCH_DEBOUNCE_MS, SEARCH_RESULT_LIMIT } from './mentionConstants';
|
||||
|
||||
type Person = components['schemas']['Person'];
|
||||
// PersonSummaryDTO, not Person: /api/persons list items are the summary projection.
|
||||
// Typing them as the full entity hid a runtime bug (missing date fields, #812).
|
||||
type Person = components['schemas']['PersonSummaryDTO'];
|
||||
|
||||
type Props = {
|
||||
value: string;
|
||||
@@ -216,14 +218,15 @@ const controller = createMentionController();
|
||||
// reflected data-person-id or the search input).
|
||||
function commitRelink(pos: number): CommitFn {
|
||||
return (item: Person) => {
|
||||
if (!editor) return;
|
||||
if (!editor || !item.id) return;
|
||||
const personId = item.id;
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.command(({ tr, state }) => {
|
||||
const node = state.doc.nodeAt(pos);
|
||||
if (!node || node.type.name !== 'mention') return false;
|
||||
tr.setNodeMarkup(pos, undefined, { ...node.attrs, personId: item.id });
|
||||
tr.setNodeMarkup(pos, undefined, { ...node.attrs, personId });
|
||||
return true;
|
||||
})
|
||||
.run();
|
||||
@@ -364,8 +367,10 @@ onMount(() => {
|
||||
render() {
|
||||
const buildFreshCommit = (loose: LooseRenderProps): CommitFn => {
|
||||
const clippedQuery = loose.query.slice(0, MAX_QUERY_LENGTH);
|
||||
return (item: Person) =>
|
||||
return (item: Person) => {
|
||||
if (!item.id) return;
|
||||
loose.command({ personId: item.id, displayName: clippedQuery });
|
||||
};
|
||||
};
|
||||
return {
|
||||
onStart(renderProps) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import { m } from '$lib/paraglide/messages.js';
|
||||
// module so the test cannot drift from production. Sara on PR #629 round 3.
|
||||
import { SEARCH_DEBOUNCE_MS } from './mentionConstants';
|
||||
|
||||
type Person = components['schemas']['Person'];
|
||||
type Person = components['schemas']['PersonSummaryDTO'];
|
||||
type PersonMention = components['schemas']['PersonMention'];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user