diff --git a/backend/FwLite/LocalWebApp/Hubs/MiniLcmApiHubBase.cs b/backend/FwLite/LocalWebApp/Hubs/MiniLcmApiHubBase.cs index 36fa19493..5f477f6e8 100644 --- a/backend/FwLite/LocalWebApp/Hubs/MiniLcmApiHubBase.cs +++ b/backend/FwLite/LocalWebApp/Hubs/MiniLcmApiHubBase.cs @@ -65,9 +65,9 @@ public virtual async Task CreateEntry(Entry entry) return newEntry; } - public virtual async Task UpdateEntry(Guid id, JsonPatchDocument update) + public virtual async Task UpdateEntry(Entry before, Entry after) { - var entry = await miniLcmApi.UpdateEntry(id, new UpdateObjectInput(update)); + var entry = await miniLcmApi.UpdateEntry(before, after); await NotifyEntryUpdated(entry); return entry; } diff --git a/frontend/viewer/src/lib/Editor.svelte b/frontend/viewer/src/lib/Editor.svelte index dec8bec88..71bf2492f 100644 --- a/frontend/viewer/src/lib/Editor.svelte +++ b/frontend/viewer/src/lib/Editor.svelte @@ -2,9 +2,7 @@ import type {IEntry, IExampleSentence, ISense} from './mini-lcm'; import EntryEditor from './entry-editor/object-editors/EntryEditor.svelte'; import {createEventDispatcher, getContext} from 'svelte'; - import jsonPatch from 'fast-json-patch'; import {useLexboxApi} from './services/service-provider'; - import {isEmptyId} from './utils'; import type { SaveHandler } from './services/save-event-service'; import {useViewSettings} from './services/view-service'; @@ -27,26 +25,8 @@ const viewSettings = useViewSettings(); - function withoutSenses(entry: IEntry): Omit { - let {senses, ...rest} = entry; - return rest; - } - function withoutExamples(sense: ISense): Omit { - let {exampleSentences, ...rest} = sense; - return rest; - } - async function onChange(e: { entry: IEntry, sense?: ISense, example?: IExampleSentence }) { await updateEntry(e.entry); - if (e.sense !== undefined) { - await updateSense(e.sense); - detectSenseIndexChanges(e.entry, e.sense); - if (e.example !== undefined) { - await updateExample(e.sense.id, e.example); - detectExampleIndexChanges(e.entry, e.sense, e.example); - } - } - dispatch('change', {entry: e.entry}); updateInitialEntry(); } @@ -66,60 +46,7 @@ async function updateEntry(updatedEntry: IEntry) { if (entry.id != updatedEntry.id) throw new Error('Entry id mismatch'); - let operations = jsonPatch.compare(withoutSenses(initialEntry), withoutSenses(updatedEntry)); - if (operations.length == 0) return; - console.debug('updateEntry', operations); - await saveHandler(() => lexboxApi.UpdateEntry(updatedEntry.id, operations)); - } - - async function updateSense(updatedSense: ISense) { - if (isEmptyId(updatedSense.id)) { - updatedSense.id = crypto.randomUUID(); - await saveHandler(() => lexboxApi.CreateSense(entry.id, updatedSense)); - return; - } - const initialSense = initialEntry.senses.find(s => s.id === updatedSense.id); - if (!initialSense) throw new Error('Sense not found in initial entry'); - let operations = jsonPatch.compare(withoutExamples(initialSense), withoutExamples(updatedSense)); - if (operations.length == 0) return; - console.debug('updateSense', operations); - await saveHandler(() => lexboxApi.UpdateSense(entry.id, updatedSense.id, operations)); - } - - async function updateExample(senseId: string, updatedExample: IExampleSentence) { - const initialSense = initialEntry.senses.find(s => s.id === senseId); - if (!initialSense) throw new Error('Sense not found in initial entry'); - if (isEmptyId(updatedExample.id)) { - updatedExample.id = crypto.randomUUID(); - await saveHandler(() => lexboxApi.CreateExampleSentence(entry.id, senseId, updatedExample)); - return; - } - const initialExample = initialSense.exampleSentences.find(e => e.id === updatedExample.id); - if (!initialExample) throw new Error('Example not found in initial sense'); - let operations = jsonPatch.compare(initialExample, updatedExample); - if (operations.length == 0) return; - console.debug('updateExample', operations); - await saveHandler(() => lexboxApi.UpdateExampleSentence(entry.id, senseId, updatedExample.id, operations)); - } - - function detectSenseIndexChanges(entry: IEntry, sense: ISense) { - const initialIndex = initialEntry.senses.findIndex(s => s.id === sense.id); - if (initialIndex === -1) return; - const currentIndex = entry.senses.findIndex(s => s.id === sense.id); - if (currentIndex === -1) return; - if (initialIndex !== currentIndex) { - // todo figure out how to send this to the server - } - } - - function detectExampleIndexChanges(entry: IEntry, sense: ISense, example: IExampleSentence) { - const initialIndex = initialEntry.senses.find(s => s.id == sense.id)?.exampleSentences.findIndex(s => s.id === example.id); - if (initialIndex === -1 || initialIndex === undefined) return; - const currentIndex = sense.exampleSentences.findIndex(s => s.id === example.id); - if (currentIndex === -1) return; - if (initialIndex !== currentIndex) { - // todo figure out how to send this to the server - } + await saveHandler(() => lexboxApi.UpdateEntry(initialEntry, updatedEntry)); } diff --git a/frontend/viewer/src/lib/generated-signalr-client/TypedSignalR.Client/index.ts b/frontend/viewer/src/lib/generated-signalr-client/TypedSignalR.Client/index.ts index 7bc72a381..bd972d5e6 100644 --- a/frontend/viewer/src/lib/generated-signalr-client/TypedSignalR.Client/index.ts +++ b/frontend/viewer/src/lib/generated-signalr-client/TypedSignalR.Client/index.ts @@ -3,10 +3,10 @@ /* tslint:disable */ import type {ComplexFormType, Entry, ExampleSentence, PartOfSpeech, QueryOptions, SemanticDomain, Sense, WritingSystem, WritingSystems} from '../../mini-lcm'; -import type { ILexboxApiHub, ILexboxClient } from './Lexbox.ClientServer.Hubs'; +import type {ILexboxApiHub, ILexboxClient} from './Lexbox.ClientServer.Hubs'; -import { HubConnection } from '@microsoft/signalr'; -import type { JsonOperation } from '../Lexbox.ClientServer.Hubs'; +import {HubConnection} from '@microsoft/signalr'; +import type {JsonOperation} from '../Lexbox.ClientServer.Hubs'; import type {WritingSystemType} from '../../services/lexbox-api'; // components @@ -174,8 +174,8 @@ class ILexboxApiHub_HubProxy implements ILexboxApiHub { return await this.connection.invoke("CreateEntry", entry); } - public readonly UpdateEntry = async (id: string, update: JsonOperation[]): Promise => { - return await this.connection.invoke("UpdateEntry", id, update); + public readonly UpdateEntry = async (before: Entry, after: Entry): Promise => { + return await this.connection.invoke("UpdateEntry", before, after); } public readonly DeleteEntry = async (id: string): Promise => { diff --git a/frontend/viewer/src/lib/in-memory-api-service.ts b/frontend/viewer/src/lib/in-memory-api-service.ts index 70878dbb5..6e6226e9a 100644 --- a/frontend/viewer/src/lib/in-memory-api-service.ts +++ b/frontend/viewer/src/lib/in-memory-api-service.ts @@ -1,4 +1,6 @@ -import {entries, projectName, writingSystems} from './entry-data'; +/* eslint-disable @typescript-eslint/naming-convention */ + +import {entries, projectName, writingSystems} from './entry-data'; import type { IEntry, IExampleSentence, @@ -123,10 +125,9 @@ export class InMemoryApiService implements LexboxApiClient { return Promise.resolve(entry); } - UpdateEntry(guid: string, update: JsonPatch): Promise { - const entry = entries.find(e => e.id === guid)!; - applyPatch(entry, update); - return Promise.resolve(entry); + UpdateEntry(_before: IEntry, after: IEntry): Promise { + entries.splice(entries.findIndex(e => e.id === after.id), 1, after); + return Promise.resolve(after); } CreateSense(entryGuid: string, sense: ISense): Promise { diff --git a/frontend/viewer/src/lib/services/lexbox-api.ts b/frontend/viewer/src/lib/services/lexbox-api.ts index e968a01ad..8226378f4 100644 --- a/frontend/viewer/src/lib/services/lexbox-api.ts +++ b/frontend/viewer/src/lib/services/lexbox-api.ts @@ -37,7 +37,7 @@ export interface LexboxApi { GetEntry(guid: string): Promise; CreateEntry(entry: IEntry): Promise; - UpdateEntry(guid: string, update: JsonPatch): Promise; + UpdateEntry(before: IEntry, after: IEntry): Promise; DeleteEntry(guid: string): Promise; CreateSense(entryGuid: string, sense: ISense): Promise;