Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refresh related entries on changes #1377

Merged
merged 12 commits into from
Feb 17, 2025
Merged
29 changes: 15 additions & 14 deletions backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
}
await Cache.DoUsingNewOrCurrentUOW("Update WritingSystem",
"Revert WritingSystem",
async () =>

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FwHeadless / publish-fw-headless

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 215 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
var updateProxy = new UpdateWritingSystemProxy(lcmWritingSystem)
{
Expand All @@ -224,14 +224,14 @@
return await GetWritingSystem(id, type);
}

public async Task<WritingSystem> UpdateWritingSystem(WritingSystem before, WritingSystem after)
public async Task<WritingSystem> UpdateWritingSystem(WritingSystem before, WritingSystem after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await Cache.DoUsingNewOrCurrentUOW("Update WritingSystem",
"Revert WritingSystem",
async () =>
{
await WritingSystemSync.Sync(before, after, this);
await WritingSystemSync.Sync(before, after, api ?? this);
});
return await GetWritingSystem(after.WsId, after.Type) ?? throw new NullReferenceException($"unable to find {after.Type} writing system with id {after.WsId}");
}
Expand Down Expand Up @@ -284,10 +284,10 @@
return Task.FromResult(FromLcmPartOfSpeech(lcmPartOfSpeech));
}

public async Task<PartOfSpeech> UpdatePartOfSpeech(PartOfSpeech before, PartOfSpeech after)
public async Task<PartOfSpeech> UpdatePartOfSpeech(PartOfSpeech before, PartOfSpeech after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await PartOfSpeechSync.Sync(before, after, this);
await PartOfSpeechSync.Sync(before, after, api ?? this);
return await GetPartOfSpeech(after.Id) ?? throw new NullReferenceException($"unable to find part of speech with id {after.Id}");
}

Expand Down Expand Up @@ -370,10 +370,10 @@
return Task.FromResult(FromLcmSemanticDomain(lcmSemanticDomain));
}

public async Task<SemanticDomain> UpdateSemanticDomain(SemanticDomain before, SemanticDomain after)
public async Task<SemanticDomain> UpdateSemanticDomain(SemanticDomain before, SemanticDomain after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await SemanticDomainSync.Sync(before, after, this);
await SemanticDomainSync.Sync(before, after, api ?? this);
return await GetSemanticDomain(after.Id) ?? throw new NullReferenceException($"unable to find semantic domain with id {after.Id}");
}

Expand Down Expand Up @@ -445,10 +445,10 @@
return Task.FromResult(ToComplexFormType(type));
}

public async Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after)
public async Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await ComplexFormTypeSync.Sync(before, after, this);
await ComplexFormTypeSync.Sync(before, after, api ?? this);
return ToComplexFormType(ComplexFormTypesFlattened.Single(c => c.Guid == after.Id));
}

Expand Down Expand Up @@ -954,14 +954,14 @@
return Task.FromResult(FromLexEntry(lexEntry));
}

public async Task<Entry> UpdateEntry(Entry before, Entry after)
public async Task<Entry> UpdateEntry(Entry before, Entry after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await Cache.DoUsingNewOrCurrentUOW("Update Entry",
"Revert entry",
async () =>
{
await EntrySync.Sync(before, after, this);
await EntrySync.Sync(before, after, api ?? this);
});
return await GetEntry(after.Id) ?? throw new NullReferenceException("unable to find entry with id " + after.Id);
}
Expand Down Expand Up @@ -1121,14 +1121,14 @@
return Task.FromResult(FromLexSense(lexSense));
}

public async Task<Sense> UpdateSense(Guid entryId, Sense before, Sense after)
public async Task<Sense> UpdateSense(Guid entryId, Sense before, Sense after, IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await Cache.DoUsingNewOrCurrentUOW("Update Sense",
"Revert Sense",
async () =>
{
await SenseSync.Sync(entryId, before, after, this);
await SenseSync.Sync(entryId, before, after, api ?? this);
});
return await GetSense(entryId, after.Id) ?? throw new NullReferenceException("unable to find sense with id " + after.Id);
}
Expand Down Expand Up @@ -1239,14 +1239,15 @@
public async Task<ExampleSentence> UpdateExampleSentence(Guid entryId,
Guid senseId,
ExampleSentence before,
ExampleSentence after)
ExampleSentence after,
IMiniLcmApi? api = null)
{
await validators.ValidateAndThrow(after);
await Cache.DoUsingNewOrCurrentUOW("Update Example Sentence",
"Revert Example Sentence",
async () =>
{
await ExampleSentenceSync.Sync(entryId, senseId, before, after, this);
await ExampleSentenceSync.Sync(entryId, senseId, before, after, api ?? this);
});
return await GetExampleSentence(entryId, senseId, after.Id) ?? throw new NullReferenceException("unable to find example sentence with id " + after.Id);
}
Expand Down
98 changes: 20 additions & 78 deletions backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

namespace FwLiteProjectSync;

public class DryRunMiniLcmApi(IMiniLcmApi api) : IMiniLcmApi
public partial class DryRunMiniLcmApi(IMiniLcmApi api) : IMiniLcmApi
{
[BeaKona.AutoInterface(typeof(IMiniLcmReadApi))]
private readonly IMiniLcmApi _api = api;

public void Dispose()
{
}
Expand All @@ -14,11 +17,6 @@

public record DryRunRecord(string Method, string Description);

public Task<WritingSystems> GetWritingSystems()
{
return api.GetWritingSystems();
}

public Task<WritingSystem> CreateWritingSystem(WritingSystemType type, WritingSystem writingSystem)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateWritingSystem), $"Create writing system {type}"));
Expand All @@ -31,30 +29,20 @@
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateWritingSystem),
$"Update writing system {type}, changes: {update.Summarize()}"));
var ws = await api.GetWritingSystems();
var ws = await _api.GetWritingSystems();
return (type switch

Check warning on line 33 in backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FwHeadless / publish-fw-headless

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(MiniLcm.Models.WritingSystemType)2' is not covered.

Check warning on line 33 in backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(MiniLcm.Models.WritingSystemType)2' is not covered.

Check warning on line 33 in backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(MiniLcm.Models.WritingSystemType)2' is not covered.

Check warning on line 33 in backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(MiniLcm.Models.WritingSystemType)2' is not covered.

Check warning on line 33 in backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(MiniLcm.Models.WritingSystemType)2' is not covered.
{
WritingSystemType.Vernacular => ws.Vernacular,
WritingSystemType.Analysis => ws.Analysis
}).First(w => w.WsId == id);
}

public Task<WritingSystem> UpdateWritingSystem(WritingSystem before, WritingSystem after)
public Task<WritingSystem> UpdateWritingSystem(WritingSystem before, WritingSystem after, IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateEntry), $"Update {after.Type} writing system {after.WsId}"));
return Task.FromResult(after);
}

public IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech()
{
return api.GetPartsOfSpeech();
}

public Task<PartOfSpeech?> GetPartOfSpeech(Guid id)
{
return api.GetPartOfSpeech(id);
}

public Task<PartOfSpeech> CreatePartOfSpeech(PartOfSpeech partOfSpeech)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreatePartOfSpeech), $"Create part of speech {partOfSpeech.Name}"));
Expand All @@ -64,10 +52,10 @@
public Task<PartOfSpeech> UpdatePartOfSpeech(Guid id, UpdateObjectInput<PartOfSpeech> update)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdatePartOfSpeech), $"Update part of speech {id}"));
return GetPartOfSpeech(id)!;
return _api.GetPartOfSpeech(id)!;
}

public Task<PartOfSpeech> UpdatePartOfSpeech(PartOfSpeech before, PartOfSpeech after)
public Task<PartOfSpeech> UpdatePartOfSpeech(PartOfSpeech before, PartOfSpeech after, IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdatePartOfSpeech), $"Update part of speech {after.Id}"));
return Task.FromResult(after);
Expand All @@ -79,16 +67,6 @@
return Task.CompletedTask;
}

public IAsyncEnumerable<SemanticDomain> GetSemanticDomains()
{
return api.GetSemanticDomains();
}

public Task<SemanticDomain?> GetSemanticDomain(Guid id)
{
return api.GetSemanticDomain(id);
}

public Task<SemanticDomain> CreateSemanticDomain(SemanticDomain semanticDomain)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateSemanticDomain),
Expand All @@ -99,10 +77,10 @@
public Task<SemanticDomain> UpdateSemanticDomain(Guid id, UpdateObjectInput<SemanticDomain> update)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateSemanticDomain), $"Update semantic domain {id}"));
return GetSemanticDomain(id)!;
return _api.GetSemanticDomain(id)!;
}

public Task<SemanticDomain> UpdateSemanticDomain(SemanticDomain before, SemanticDomain after)
public Task<SemanticDomain> UpdateSemanticDomain(SemanticDomain before, SemanticDomain after, IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateSemanticDomain), $"Update semantic domain {after.Id}"));
return Task.FromResult(after);
Expand All @@ -114,17 +92,6 @@
return Task.CompletedTask;
}

public IAsyncEnumerable<ComplexFormType> GetComplexFormTypes()
{
return api.GetComplexFormTypes();
}

public Task<ComplexFormType?> GetComplexFormType(Guid id)
{
return api.GetComplexFormType(id);
}


public Task<ComplexFormType> CreateComplexFormType(ComplexFormType complexFormType)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateComplexFormType),
Expand All @@ -135,10 +102,10 @@
public async Task<ComplexFormType> UpdateComplexFormType(Guid id, UpdateObjectInput<ComplexFormType> update)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateComplexFormType), $"Update complex form type {id}"));
return await GetComplexFormType(id) ?? throw new NullReferenceException($"unable to find complex form type with id {id}");
return await _api.GetComplexFormType(id) ?? throw new NullReferenceException($"unable to find complex form type with id {id}");
}

public Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after)
public Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after, IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateComplexFormType), $"Update complex form type {after.Id}"));
return Task.FromResult(after);
Expand All @@ -150,21 +117,6 @@
return Task.CompletedTask;
}

public IAsyncEnumerable<Entry> GetEntries(QueryOptions? options = null)
{
return api.GetEntries(options);
}

public IAsyncEnumerable<Entry> SearchEntries(string query, QueryOptions? options = null)
{
return api.SearchEntries(query, options);
}

public Task<Entry?> GetEntry(Guid id)
{
return api.GetEntry(id);
}

public Task<Entry> CreateEntry(Entry entry)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateEntry), $"Create entry {entry.Headword()}"));
Expand All @@ -174,10 +126,10 @@
public Task<Entry> UpdateEntry(Guid id, UpdateObjectInput<Entry> update)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateEntry), $"Update entry {id}"));
return GetEntry(id)!;
return _api.GetEntry(id)!;
}

public Task<Entry> UpdateEntry(Entry before, Entry after)
public Task<Entry> UpdateEntry(Entry before, Entry after, IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateEntry), $"Update entry {after.Id}"));
return Task.FromResult(after);
Expand All @@ -194,12 +146,6 @@
DryRunRecords.Add(new DryRunRecord(nameof(RemoveComplexFormType), $"Remove complex form type {complexFormTypeId}, from entry {entryId}"));
await Task.CompletedTask;
}

public Task<Sense?> GetSense(Guid entryId, Guid id)
{
return api.GetSense(entryId, id);
}

public Task<Sense> CreateSense(Guid entryId, Sense sense, BetweenPosition? position = null)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateSense), $"Create sense {sense.Gloss} between {position?.Previous} and {position?.Next}"));
Expand All @@ -210,17 +156,17 @@
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateSense),
$"Update sense {senseId}, changes: {update.Summarize()}"));
var entry = await GetEntry(entryId) ??
var entry = await _api.GetEntry(entryId) ??
throw new NullReferenceException($"unable to find entry with id {entryId}");
var sense = entry.Senses.First(s => s.Id == senseId);
return sense;
}

public async Task<Sense> UpdateSense(Guid entryId, Sense before, Sense after)
public async Task<Sense> UpdateSense(Guid entryId, Sense before, Sense after, IMiniLcmApi? api)
{
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}");
return await _api.GetSense(entryId, after.Id) ?? throw new NullReferenceException($"unable to find sense with id {after.Id}");
}

public Task MoveSense(Guid entryId, Guid senseId, BetweenPosition between)
Expand All @@ -247,11 +193,6 @@
return Task.CompletedTask;
}

public Task<ExampleSentence?> GetExampleSentence(Guid entryId, Guid senseId, Guid id)
{
return api.GetExampleSentence(entryId, senseId, id);
}

public Task<ExampleSentence> CreateExampleSentence(Guid entryId, Guid senseId, ExampleSentence exampleSentence, BetweenPosition? position = null)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateExampleSentence), $"Create example sentence {exampleSentence.Sentence} between {position?.Previous} and {position?.Next}"));
Expand All @@ -265,14 +206,15 @@
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateExampleSentence),
$"Update example sentence {exampleSentenceId}, changes: {update.Summarize()}"));
var exampleSentence = await GetExampleSentence(entryId, senseId, exampleSentenceId);
var exampleSentence = await _api.GetExampleSentence(entryId, senseId, exampleSentenceId);
return exampleSentence ?? throw new NullReferenceException($"unable to find example sentence with id {exampleSentenceId}");
}

public Task<ExampleSentence> UpdateExampleSentence(Guid entryId,
Guid senseId,
ExampleSentence before,
ExampleSentence after)
ExampleSentence after,
IMiniLcmApi? api)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateExampleSentence), $"Update example sentence {after.Id}"));
return Task.FromResult(after);
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/FwLiteProjectSync/FwLiteProjectSync.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BeaKona.AutoInterfaceGenerator" Version="1.0.42"/>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/FwLiteShared/FwLiteShared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BeaKona.AutoInterfaceGenerator" Version="1.0.42" />
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.0"/>
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
services.AddSingleton<CombinedProjectsService>();
services.AddSingleton<GlobalEventBus>();
services.AddSingleton<ProjectEventBus>();
services.AddSingleton<MiniLcmApiNotifyWrapperFactory>();
services.AddScoped<JsEventListener>();
//this is scoped so that there will be once instance per blazor circuit, this prevents issues where the same instance is used when reloading the page.
//it also avoids issues if there's multiple blazor circuits running at the same time
Expand Down Expand Up @@ -68,7 +69,7 @@
return new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true

Check warning on line 72 in backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This call site is reachable on all platforms. 'HttpClientHandler.ServerCertificateCustomValidationCallback' is unsupported on: 'browser'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)

Check warning on line 72 in backend/FwLite/FwLiteShared/FwLiteSharedKernel.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Android

This call site is reachable on all platforms. 'HttpClientHandler.ServerCertificateCustomValidationCallback' is unsupported on: 'browser'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
};
});
}
Expand Down
Loading
Loading