feat(magic-notes): add rich table editing
Add native Quill table insertion and contextual row, column, and table actions. Preserve table-only drafts through composer validation, IPC, and storage, and document the saved behavior.\n\nRelease note: 魔法笔记支持插入和编辑表格,空单元格表格也可保存并在重新打开后恢复。
This commit is contained in:
@@ -118,6 +118,24 @@ describe('Magic note SQLite and filesystem storage', () => {
|
||||
expect(database.getMagicNote(created.id)).toEqual(before)
|
||||
})
|
||||
|
||||
it('persists and reopens a rich table whose cells contain no text', () => {
|
||||
const { database, directory } = setup()
|
||||
const note = database.createMagicNote({ title: 'Empty table' })
|
||||
const table: MagicNoteContent = {
|
||||
version: 1,
|
||||
ops: [{ insert: '\n', attributes: { table: 'row-1' } }]
|
||||
}
|
||||
|
||||
const saved = database.createMagicNoteEntry({ noteId: note.id, content: table, plainText: 'ignored' })
|
||||
expect(saved.entries.at(-1)?.content).toEqual(table)
|
||||
|
||||
database.close()
|
||||
const reopened = new AssistantDatabase(join(directory, 'assistant.sqlite'))
|
||||
connections.push(reopened)
|
||||
reopened.initialize(directory)
|
||||
expect(reopened.getMagicNote(note.id).entries.at(-1)?.content).toEqual(table)
|
||||
})
|
||||
|
||||
it.each(['missing', 'invalid-json', 'invalid-media'] as const)('retains all assets when a later retained body has %s corruption', (failure) => {
|
||||
const { database, directory } = setup()
|
||||
const note = database.createMagicNote({ title: 'Retained bodies', content: rich })
|
||||
|
||||
@@ -16,6 +16,21 @@ function fixture(database: Partial<AssistantStoragePort>) {
|
||||
}
|
||||
|
||||
describe('async magic notes IPC', () => {
|
||||
it('passes an empty-cell table through schema and content validation', async () => {
|
||||
const createMagicNoteEntry = vi.fn<AssistantStoragePort['createMagicNoteEntry']>()
|
||||
createMagicNoteEntry.mockResolvedValue({
|
||||
id: 'note', title: 'Note', preview: '', entryCount: 1, pinned: false, tags: [],
|
||||
revision: 1, createdAt: '', updatedAt: '', createdEntryId: 'entry', entries: []
|
||||
})
|
||||
const f = fixture({ createMagicNoteEntry })
|
||||
const content = { version: 1 as const, ops: [{ insert: '\n', attributes: { table: 'row-1' } }] }
|
||||
|
||||
await f.invoke(ipcChannels.magicNotesCreateEntry, {
|
||||
noteId: '00000000-0000-4000-8000-000000000001', content
|
||||
})
|
||||
expect(createMagicNoteEntry).toHaveBeenCalledWith(expect.objectContaining({ content, plainText: '' }))
|
||||
})
|
||||
|
||||
it('resolves list DTOs and preserves sender/schema checks before storage', async () => {
|
||||
const listMagicNotes = vi.fn(async () => [])
|
||||
const createMagicNote = vi.fn()
|
||||
|
||||
Reference in New Issue
Block a user