diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.html b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.html
index f9c8105b3b..d35c4feb0f 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.html
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.html
@@ -83,8 +83,12 @@
- @if (isLoaded) {
+ @if (isLoaded && appOnline && biblicalTermsLoaded) {
{{ t("not_found") }}
+ } @else if (appOnline && !biblicalTermsLoaded) {
+ {{ t("loading") }}
+ } @else if (isLoaded && !biblicalTermsLoaded) {
+ {{ t("offline") }}
}
|
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.spec.ts
index d77036e1e3..e3ac083f77 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.spec.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.spec.ts
@@ -27,7 +27,10 @@ import { anything, capture, instance, mock, verify, when } from 'ts-mockito';
import { GenericDialogComponent, GenericDialogOptions } from 'xforge-common/generic-dialog/generic-dialog.component';
import { I18nService } from 'xforge-common/i18n.service';
import { Locale } from 'xforge-common/models/i18n-locale';
+import { OnlineStatusService } from 'xforge-common/online-status.service';
import { QueryParameters } from 'xforge-common/query-parameters';
+import { TestOnlineStatusModule } from 'xforge-common/test-online-status.module';
+import { TestOnlineStatusService } from 'xforge-common/test-online-status.service';
import { TestRealtimeModule } from 'xforge-common/test-realtime.module';
import { TestRealtimeService } from 'xforge-common/test-realtime.service';
import { configureTestingModule, TestTranslocoModule } from 'xforge-common/test-utils';
@@ -51,12 +54,19 @@ const mockedUserService = mock(UserService);
describe('BiblicalTermsComponent', () => {
configureTestingModule(() => ({
- imports: [NoopAnimationsModule, TestTranslocoModule, UICommonModule, TestRealtimeModule.forRoot(SF_TYPE_REGISTRY)],
+ imports: [
+ NoopAnimationsModule,
+ TestOnlineStatusModule.forRoot(),
+ TestTranslocoModule,
+ UICommonModule,
+ TestRealtimeModule.forRoot(SF_TYPE_REGISTRY)
+ ],
providers: [
{ provide: I18nService, useMock: mockedI18nService },
{ provide: MatDialog, useMock: mockedMatDialog },
{ provide: SFProjectService, useMock: mockedProjectService },
- { provide: UserService, useMock: mockedUserService }
+ { provide: UserService, useMock: mockedUserService },
+ { provide: OnlineStatusService, useClass: TestOnlineStatusService }
]
}));
@@ -376,6 +386,14 @@ describe('BiblicalTermsComponent', () => {
expect(env.notFoundMessage.length).toBe(1);
}));
+ it('should show the offline message if not connected to internet', fakeAsync(() => {
+ const env = new TestEnvironment('project01', 1, 1, '4');
+ env.setupProjectData('en');
+ env.onlineStatus = false;
+ env.wait();
+ expect(env.offlineMessage.length).toBe(1);
+ }));
+
it('should not show the not found message when loading the component', fakeAsync(() => {
const env = new TestEnvironment(undefined, 1, 1, '4');
env.wait();
@@ -391,6 +409,9 @@ class TestEnvironment {
readonly mockedDialogRef = mock, GenericDialogOptions>>(MatDialogRef);
readonly realtimeService: TestRealtimeService = TestBed.inject(TestRealtimeService);
readonly locale$: BehaviorSubject = new BehaviorSubject({} as Locale);
+ readonly testOnlineStatusService: TestOnlineStatusService = TestBed.inject(
+ OnlineStatusService
+ ) as TestOnlineStatusService;
private openNoteDialogs: MockNoteDialogRef[] = [];
@@ -424,6 +445,7 @@ class TestEnvironment {
when(mockedMatDialog.open(GenericDialogComponent, anything())).thenReturn(instance(this.mockedDialogRef));
when(this.mockedDialogRef.afterClosed()).thenReturn(of());
when(mockedMatDialog.openDialogs).thenCall(() => this.openNoteDialogs);
+ this.testOnlineStatusService.setIsOnline(true);
this.fixture = TestBed.createComponent(BiblicalTermsComponent);
this.component = this.fixture.componentInstance;
@@ -467,6 +489,16 @@ class TestEnvironment {
return this.fixture.nativeElement.querySelectorAll('.not-found');
}
+ get offlineMessage(): NodeList {
+ return this.fixture.nativeElement.querySelectorAll('.offline-message');
+ }
+
+ set onlineStatus(hasConnection: boolean) {
+ this.testOnlineStatusService.setIsOnline(hasConnection);
+ tick();
+ this.fixture.detectChanges();
+ }
+
getBiblicalTermDoc(projectId: string, dataId: string): BiblicalTermDoc {
return this.realtimeService.get(BiblicalTermDoc.COLLECTION, getBiblicalTermDocId(projectId, dataId));
}
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.ts
index 7319b41549..f820609585 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/biblical-terms/biblical-terms.component.ts
@@ -23,6 +23,7 @@ import { DialogService } from 'xforge-common/dialog.service';
import { I18nService } from 'xforge-common/i18n.service';
import { RealtimeQuery } from 'xforge-common/models/realtime-query';
import { NoticeService } from 'xforge-common/notice.service';
+import { OnlineStatusService } from 'xforge-common/online-status.service';
import { UICommonModule } from 'xforge-common/ui-common.module';
import { UserService } from 'xforge-common/user.service';
import { objectId } from 'xforge-common/utils';
@@ -180,6 +181,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
readonly columnsToDisplay = ['term', 'category', 'gloss', 'renderings', 'id'];
readonly rangeFilters: RangeFilter[] = ['current_verse', 'current_chapter', 'current_book'];
rows: Row[] = [];
+ biblicalTermsLoaded: boolean = false;
private biblicalTermQuery?: RealtimeQuery;
private biblicalTermSub?: Subscription;
@@ -202,6 +204,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
noticeService: NoticeService,
readonly i18n: I18nService,
private readonly dialogService: DialogService,
+ private readonly onlineStatusService: OnlineStatusService,
private readonly projectService: SFProjectService,
private readonly userService: UserService
) {
@@ -240,6 +243,10 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
this.verse$.next(verse);
}
+ get appOnline(): boolean {
+ return this.onlineStatusService.isOnline && this.onlineStatusService.isBrowserOnline;
+ }
+
get selectedCategory(): string {
// To stop visual glitches in the dropdown while the categories are loading, return the category as all
if (this.categoriesLoading) {
@@ -307,6 +314,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
this.loadingStarted();
this.categoriesLoading = true;
const biblicalTermsAndNotesChanges$: Observable = await this.getBiblicalTermsAndNotesChanges(projectId);
+
this.biblicalTermSub?.unsubscribe();
this.biblicalTermSub = this.subscribe(
@@ -322,6 +330,12 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
this.categoriesLoading = false;
}
);
+
+ if (!this.appOnline && biblicalTermsAndNotesChanges$.pipe(filter(val => val == null))) {
+ this.loadingFinished();
+ } else {
+ this.biblicalTermsLoaded = true;
+ }
});
}
@@ -488,6 +502,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
]);
// Return a merged observable to monitor changes
+
return merge(
this.biblicalTermQuery.ready$.pipe(filter(isReady => isReady)),
this.biblicalTermQuery.remoteChanges$,
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json b/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json
index a10446ef46..9b4b9235c9 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json
+++ b/src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json
@@ -34,8 +34,10 @@
"current_verse": "Current Verse",
"edit_renderings": "Edit Renderings",
"gloss": "Gloss",
+ "loading": "Loading...",
"not_found": "No Biblical Terms match your criteria.",
"notes": "Notes",
+ "offline": "Currently unavailable offline. Please connect to the internet, once loaded you can continue viewing them offline.",
"renderings": "Renderings",
"settings": "Settings",
"show": "Show",