feat(fp): WP-27 — brief UX layer (undo/redo, standaardbrief, passage search, diff badges)
CI / frontend (push) Failing after 1m15s
CI / storybook-a11y (push) Failing after 4m43s
CI / backend (push) Successful in 1m24s
CI / codeql (csharp) (push) Failing after 2m51s
CI / e2e (push) Failing after 3h4m8s
CI / codeql (javascript-typescript) (push) Failing after 1m30s
CI / api-client-drift (push) Successful in 1m53s
CI / frontend (push) Failing after 1m15s
CI / storybook-a11y (push) Failing after 4m43s
CI / backend (push) Successful in 1m24s
CI / codeql (csharp) (push) Failing after 2m51s
CI / e2e (push) Failing after 3h4m8s
CI / codeql (javascript-typescript) (push) Failing after 1m30s
CI / api-client-drift (push) Successful in 1m53s
Brief letter-composition UX improvements: - undo/redo history in the brief store (snapshot stacks, Ctrl/Cmd+Z) + retry-save - "Standaardbrief invoegen" starter for empty sections; isDefault library passages (backend DTO/seed + adapter parse) - passage-picker client-side search (rich-text textOf helper) - rejection diff badges on the letter canvas + show/hide changes toggle (pure brief-diff domain fns + spec) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { Brief, LetterBlock } from './brief';
|
||||
import { diffBlocks, changedBlocks } from './brief-diff';
|
||||
|
||||
function block(id: string, text: string): LetterBlock {
|
||||
return { type: 'freeText', blockId: id, content: { paragraphs: [{ nodes: [{ type: 'text', text }] }] } };
|
||||
}
|
||||
|
||||
function brief(blocks: LetterBlock[]): Brief {
|
||||
return {
|
||||
briefId: 'b1',
|
||||
beroep: 'arts',
|
||||
templateId: 't1',
|
||||
placeholders: [],
|
||||
sections: [{ sectionKey: 'kern', title: 'Kern', required: true, locked: false, blocks }],
|
||||
status: { tag: 'draft' },
|
||||
drafterId: 'u1',
|
||||
};
|
||||
}
|
||||
|
||||
describe('diffBlocks', () => {
|
||||
it('marks added, removed, changed and unchanged by blockId', () => {
|
||||
const before = brief([block('local-1', 'a'), block('local-2', 'b'), block('local-3', 'c')]);
|
||||
const after = brief([block('local-1', 'a'), block('local-2', 'B!'), block('local-4', 'd')]);
|
||||
const diffs = diffBlocks(before, after);
|
||||
const byId = new Map(diffs.map((d) => [d.blockId, d.kind]));
|
||||
expect(byId.get('local-1')).toBe('unchanged');
|
||||
expect(byId.get('local-2')).toBe('changed');
|
||||
expect(byId.get('local-3')).toBe('removed'); // gone from after
|
||||
expect(byId.get('local-4')).toBe('added'); // new in after
|
||||
});
|
||||
|
||||
it('changedBlocks drops unchanged and keeps added/removed/changed', () => {
|
||||
const before = brief([block('local-1', 'a'), block('local-2', 'b')]);
|
||||
const after = brief([block('local-1', 'a'), block('local-2', 'B'), block('local-3', 'c')]);
|
||||
const map = changedBlocks(diffBlocks(before, after));
|
||||
expect(map.has('local-1')).toBe(false);
|
||||
expect(map.get('local-2')).toBe('changed');
|
||||
expect(map.get('local-3')).toBe('added');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user