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

add open in flex button to fw lite #948

Merged
merged 8 commits into from
Jul 12, 2024
4 changes: 2 additions & 2 deletions backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
throw new NotImplementedException();
}

public async IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech()

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

View workflow job for this annotation

GitHub Actions / Build FW Lite

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 151 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite

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.
{
foreach (var partOfSpeech in PartOfSpeechRepository.AllInstances().OrderBy(p => p.Name.BestAnalysisAlternative.Text))
{
Expand All @@ -156,7 +156,7 @@
}
}

public async IAsyncEnumerable<SemanticDomain> GetSemanticDomains()

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

View workflow job for this annotation

GitHub Actions / Build FW Lite

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 159 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite

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.
{
foreach (var semanticDomain in SemanticDomainRepository.AllInstances().OrderBy(p => p.Name.BestAnalysisAlternative.Text))
{
Expand Down Expand Up @@ -236,7 +236,7 @@
return GetEntries(null, options);
}

public async IAsyncEnumerable<Entry> GetEntries(

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

View workflow job for this annotation

GitHub Actions / Build FW Lite

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 239 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite

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.
Func<ILexEntry, bool>? predicate, QueryOptions? options = null)
{
var entries = EntriesRepository.AllInstances();
Expand Down Expand Up @@ -301,11 +301,11 @@
Cache.ServiceLocator.ActionHandler,
() =>
{
var rootMorphType = MorphTypeRepository.GetObject(MoMorphTypeTags.kguidMorphRoot);
var stemMorphType = MorphTypeRepository.GetObject(MoMorphTypeTags.kguidMorphStem);
var firstSense = entry.Senses.FirstOrDefault();
var lexEntry = LexEntryFactory.Create(new LexEntryComponents
{
MorphType = rootMorphType,
MorphType = stemMorphType,
LexemeFormAlternatives = MultiStringToTsStrings(entry.LexemeForm),
GlossAlternatives = MultiStringToTsStrings(firstSense?.Gloss),
GlossFeatures = [],
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/LocalWebApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
app.MapHistoryRoutes();
app.MapActivities();
app.MapProjectRoutes();
app.MapFwIntegrationRoutes();
app.MapTest();
app.MapImport();
app.MapAuthRoutes();
Expand Down
32 changes: 32 additions & 0 deletions backend/FwLite/LocalWebApp/Routes/FwIntegrationRoutes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using FwDataMiniLcmBridge;
using LocalWebApp.Hubs;
using Microsoft.AspNetCore.SignalR;
using Microsoft.OpenApi.Models;

namespace LocalWebApp.Routes;

public static class FwIntegrationRoutes
{
public static IEndpointConventionBuilder MapFwIntegrationRoutes(this WebApplication app)
{
var group = app.MapGroup($"/api/fw/{{{FwDataMiniLcmHub.ProjectRouteKey}}}").WithOpenApi(
operation =>
{
operation.Parameters.Add(new OpenApiParameter()
{
Name = FwDataMiniLcmHub.ProjectRouteKey, In = ParameterLocation.Path, Required = true
});
return operation;
});
group.MapGet("/open/entry/{id}",
async (FwDataProjectContext context, IHubContext<FwDataMiniLcmHub, ILexboxHubClient> hubContext, FwDataFactory factory, Guid id) =>
{
if (context.Project is null) return Results.BadRequest("No project is set in the context");
await hubContext.Clients.Group(context.Project.Name).OnProjectClosed(CloseReason.Locked);
factory.CloseCurrentProject();
//need to use redirect as a way to not trigger flex until after we have closed the project
return Results.Redirect($"silfw://localhost/link?database={context.Project.Name}&tool=lexiconEdit&guid={id}");
});
return group;
}
}
3 changes: 2 additions & 1 deletion frontend/viewer/src/FwDataProjectView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@
SetupSignalR(connection, {
history: false,
write: true,
openWithFlex: true,
},
{
OnEntryUpdated: async (entry: Entry) => {
console.log('OnEntryUpdated', entry);
},
async OnProjectClosed(reason: CloseReason): Promise<void> {
connected = false;
// connected = false;
switch (reason) {
case CloseReason.User:
navigate('/');
Expand Down
25 changes: 25 additions & 0 deletions frontend/viewer/src/ProjectView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import { ViewerSearchParam, getSearchParam, updateSearchParam } from './lib/utils/search-params';
import SaveStatus from './lib/status/SaveStatus.svelte';
import { saveEventDispatcher, saveHandler } from './lib/services/save-event-service';
import {AppNotification} from './lib/notifications/notifications';
import flexLogo from './lib/assets/flex-logo.png';

export let loading = false;

Expand Down Expand Up @@ -215,6 +217,13 @@
unsubSelectedEntry();
};
});

async function openInFlex() {
AppNotification.displayAction('The project is open in FieldWorks. Please close it to reopen.', 'warning', {
label: 'Open',
callback: () => window.location.reload()
});
}
</script>

<svelte:head>
Expand Down Expand Up @@ -311,6 +320,22 @@

</div>
{/if}
{#if $features.openWithFlex && $selectedEntry}
<div class="contents">
<!-- button must be a link otherwise it won't follow the redirect to a protocol handler-->
<Button
hahn-kev marked this conversation as resolved.
Show resolved Hide resolved
href={`/api/fw/${projectName}/open/entry/${$selectedEntry.id}`}
on:click={openInFlex}
variant="fill-light"
color="info"
size="sm">
<img src={flexLogo} alt="FieldWorks logo" class="h-6"/>
<div class="hidden" class:sm:contents={!$entryActionsPortal.collapsed}>
Open in FieldWorks
</div>
</Button>
</div>
{/if}
<div class="contents max-sm:hidden" class:hidden={collapseActionBar}>
<Toc entry={$selectedEntry} />
</div>
Expand Down
3 changes: 2 additions & 1 deletion frontend/viewer/src/lib/services/lexbox-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export enum WritingSystemType {
export interface LexboxApiFeatures {
history?: boolean;
write?: boolean;
};
openWithFlex?: boolean;
}

export interface LexboxApi {
GetWritingSystems(): Promise<WritingSystems>;
Expand Down
Loading