diff --git a/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs b/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs index a60f206e2..c5ffc2974 100644 --- a/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs +++ b/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs @@ -911,6 +911,12 @@ private void ApplySenseToLexSense(Sense sense, ILexSense lexSense) } } + public Task GetSense(Guid entryId, Guid id) + { + var lcmSense = SenseRepository.GetObject(id); + return Task.FromResult(lcmSense is null ? null : FromLexSense(lcmSense)); + } + public Task CreateSense(Guid entryId, Sense sense) { if (sense.Id == default) sense.Id = Guid.NewGuid(); @@ -938,6 +944,17 @@ public Task UpdateSense(Guid entryId, Guid senseId, UpdateObjectInput UpdateSense(Guid entryId, Sense before, Sense after) + { + await Cache.DoUsingNewOrCurrentUOW("Update Sense", + "Revert Sense", + async () => + { + await SenseSync.Sync(entryId, after, before, this); + }); + return await GetSense(entryId, after.Id) ?? throw new NullReferenceException("unable to find sense with id " + after.Id); + } + public Task AddSemanticDomainToSense(Guid senseId, SemanticDomain semanticDomain) { UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW("Add Semantic Domain to Sense", diff --git a/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs b/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs index ff925b4c5..82d5190ca 100644 --- a/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs +++ b/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs @@ -190,6 +190,11 @@ public async Task RemoveComplexFormType(Guid entryId, Guid complexFormTypeId) await Task.CompletedTask; } + public Task GetSense(Guid entryId, Guid id) + { + return api.GetSense(entryId, id); + } + public Task CreateSense(Guid entryId, Sense sense) { DryRunRecords.Add(new DryRunRecord(nameof(CreateSense), $"Create sense {sense.Gloss}")); @@ -206,6 +211,13 @@ public async Task UpdateSense(Guid entryId, Guid senseId, UpdateObjectInp return sense; } + public async Task UpdateSense(Guid entryId, Sense before, Sense after) + { + DryRunRecords.Add(new DryRunRecord(nameof(UpdateSense), + $"Update sense {after.Id}")); + return await GetSense(entryId, after.Id) ?? throw new NullReferenceException($"unable to find sense with id {after.Id}"); + } + public Task DeleteSense(Guid entryId, Guid senseId) { DryRunRecords.Add(new DryRunRecord(nameof(DeleteSense), $"Delete sense {senseId}")); diff --git a/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs b/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs index 387dd8a0e..3955ab957 100644 --- a/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs +++ b/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs @@ -464,6 +464,16 @@ private async IAsyncEnumerable CreateSenseChanges(Guid entryId, Sense s } } + public async Task GetSense(Guid entryId, Guid id) + { + var entry = await Entries.AsTracking(false) + .LoadWith(e => e.Senses) + .ThenLoad(s => s.ExampleSentences) + .AsQueryable() + .SingleOrDefaultAsync(e => e.Id == entryId); + return entry?.Senses.FirstOrDefault(s => s.Id == id); + } + public async Task CreateSense(Guid entryId, Sense sense) { await dataModel.AddChanges(ClientId, await CreateSenseChanges(entryId, sense).ToArrayAsync()); @@ -480,6 +490,12 @@ public async Task UpdateSense(Guid entryId, return await dataModel.GetLatest(senseId) ?? throw new NullReferenceException(); } + public async Task UpdateSense(Guid entryId, Sense before, Sense after) + { + await SenseSync.Sync(entryId, after, before, this); + return await GetSense(entryId, after.Id) ?? throw new NullReferenceException("unable to find sense with id " + after.Id); + } + public async Task DeleteSense(Guid entryId, Guid senseId) { await dataModel.AddChange(ClientId, new DeleteChange(senseId)); diff --git a/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs b/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs index 03d1aa440..ff8a5cfba 100644 --- a/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs +++ b/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs @@ -13,6 +13,7 @@ public interface IMiniLcmReadApi IAsyncEnumerable GetEntries(QueryOptions? options = null); IAsyncEnumerable SearchEntries(string query, QueryOptions? options = null); Task GetEntry(Guid id); + Task GetSense(Guid entryId, Guid id); Task GetPartOfSpeech(Guid id); Task GetSemanticDomain(Guid id); Task GetExampleSentence(Guid entryId, Guid senseId, Guid id); diff --git a/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs b/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs index 1c5301fb8..b41040cb1 100644 --- a/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs +++ b/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs @@ -48,6 +48,7 @@ Task UpdateWritingSystem(WritingSystemId id, #region Sense Task CreateSense(Guid entryId, Sense sense); Task UpdateSense(Guid entryId, Guid senseId, UpdateObjectInput update); + Task UpdateSense(Guid entryId, Sense before, Sense after); Task DeleteSense(Guid entryId, Guid senseId); Task AddSemanticDomainToSense(Guid senseId, SemanticDomain semanticDomain); Task RemoveSemanticDomainFromSense(Guid senseId, Guid semanticDomainId); diff --git a/backend/LfClassicData/LfClassicMiniLcmApi.cs b/backend/LfClassicData/LfClassicMiniLcmApi.cs index c8c25c8fa..b2377bce6 100644 --- a/backend/LfClassicData/LfClassicMiniLcmApi.cs +++ b/backend/LfClassicData/LfClassicMiniLcmApi.cs @@ -315,6 +315,15 @@ private static SemanticDomain ToSemanticDomain(Entities.OptionListItem item) return ToEntry(entry); } + public async Task GetSense(Guid entryId, Guid id) + { + var entry = await Entries.Find(e => e.Guid == entryId).FirstOrDefaultAsync(); + if (entry is null) return null; + var sense = entry.Senses?.FirstOrDefault(s => s?.Guid == id); + if (sense is null) return null; + return ToSense(entryId, sense); + } + public async Task GetExampleSentence(Guid entryId, Guid senseId, Guid id) { var entry = await Entries.Find(e => e.Guid == entryId).FirstOrDefaultAsync();