Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2f8bf57
SF-3532 Dispose realtime docs when no longer in use
Nateowami Aug 6, 2025
d52b352
describe magic number
marksvc Oct 8, 2025
9a1b922
checking-text when
marksvc Oct 8, 2025
9189b5d
realtime query: add further description with name
marksvc Oct 8, 2025
52fa6f2
rm debugger
marksvc Oct 8, 2025
98878b3
adjust comment
marksvc Oct 8, 2025
4cc7197
realtime doc: isUnsubscribed$ refactor
marksvc Oct 8, 2025
acc4637
realtime doc activeDocSubscriptionsCount refactor
marksvc Oct 8, 2025
914159f
realtime service changes
marksvc Oct 8, 2025
c938386
realtime query beingDisposed
marksvc Oct 8, 2025
b306089
sf-project service fetch before unsubscribe
marksvc Oct 8, 2025
dd348fc
draft-jobs add dr
marksvc Oct 8, 2025
158327a
blank-page template
marksvc Oct 8, 2025
0a8277b
roles and permissions dialog: rm duplicate subscribe
marksvc Oct 9, 2025
9071a47
realtime.service fix change
marksvc Oct 9, 2025
6483369
realtime-doc NG0911 complete
marksvc Oct 9, 2025
b5bbd27
sf-project service optional chaining
marksvc Oct 9, 2025
e66fbb9
text-doc service: try finally
marksvc Oct 10, 2025
16ca4bd
text-doc service: try finally createTextDoc
marksvc Oct 10, 2025
e52122c
text doc service: rm destroyRef
marksvc Oct 10, 2025
6e58135
checking-overview.component spec: factory create
marksvc Oct 10, 2025
5e124ed
refactor init to factory method
marksvc Oct 10, 2025
c2f19e8
question-dialog.component.spec args
marksvc Oct 10, 2025
306803f
draft-sources.component.spec args
marksvc Oct 10, 2025
b9ef8fb
cache.service comment
marksvc Oct 10, 2025
a47cf45
realtime.service else
marksvc Oct 10, 2025
6d86a35
cache service: revise. write tests
marksvc Oct 10, 2025
ce9fa99
realtime.service name,comment
marksvc Oct 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ async function joinAsChecker(
// Give time for the last answer to be saved
await page.waitForTimeout(500);
} catch (e) {
if (preset.pauseOnFailure) await page.pause();
console.error('Error running tests for checker ' + userNumber);
console.error(e);
await screenshot(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ServalAdminAuthGuard } from './serval-administration/serval-admin-auth.
import { ServalAdministrationComponent } from './serval-administration/serval-administration.component';
import { ServalProjectComponent } from './serval-administration/serval-project.component';
import { SettingsComponent } from './settings/settings.component';
import { BlankPageComponent } from './shared/blank-page/blank-page.component';
import { PageNotFoundComponent } from './shared/page-not-found/page-not-found.component';
import { SettingsAuthGuard, SyncAuthGuard } from './shared/project-router.guard';
import { SyncComponent } from './sync/sync.component';
Expand All @@ -33,6 +34,7 @@ const routes: Routes = [
{ path: 'serval-administration/:projectId', component: ServalProjectComponent, canActivate: [ServalAdminAuthGuard] },
{ path: 'serval-administration', component: ServalAdministrationComponent, canActivate: [ServalAdminAuthGuard] },
{ path: 'system-administration', component: SystemAdministrationComponent, canActivate: [SystemAdminAuthGuard] },
{ path: 'blank-page', component: BlankPageComponent },
{ path: '**', component: PageNotFoundComponent }
];

Expand Down
186 changes: 108 additions & 78 deletions src/SIL.XForge.Scripture/ClientApp/src/app/app.component.spec.ts

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/SIL.XForge.Scripture/ClientApp/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { FileService } from 'xforge-common/file.service';
import { I18nService } from 'xforge-common/i18n.service';
import { LocationService } from 'xforge-common/location.service';
import { Breakpoint, MediaBreakpointService } from 'xforge-common/media-breakpoints/media-breakpoint.service';
import { DocSubscription } from 'xforge-common/models/realtime-doc';
import { UserDoc } from 'xforge-common/models/user-doc';
import { NoticeService } from 'xforge-common/notice.service';
import { OnlineStatusService } from 'xforge-common/online-status.service';
Expand Down Expand Up @@ -282,7 +283,8 @@ export class AppComponent extends DataLoadingComponent implements OnInit, OnDest
this.userService.setCurrentProjectId(this.currentUserDoc!, this._selectedProjectDoc.id);
this.projectUserConfigDoc = await this.projectService.getUserConfig(
this._selectedProjectDoc.id,
this.currentUserDoc!.id
this.currentUserDoc!.id,
new DocSubscription('AppComponent', this.destroyRef)
);
if (this.selectedProjectDeleteSub != null) {
this.selectedProjectDeleteSub.unsubscribe();
Expand Down
12 changes: 11 additions & 1 deletion src/SIL.XForge.Scripture/ClientApp/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { OverlayContainer } from '@angular/cdk/overlay';
import { DatePipe } from '@angular/common';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { APP_ID, ErrorHandler, NgModule, inject, provideAppInitializer } from '@angular/core';
import { APP_ID, ErrorHandler, inject, NgModule, provideAppInitializer } from '@angular/core';
import { MatRipple } from '@angular/material/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ServiceWorkerModule } from '@angular/service-worker';
Expand Down Expand Up @@ -37,6 +37,7 @@ import { ProjectComponent } from './project/project.component';
import { ScriptureChooserDialogComponent } from './scripture-chooser-dialog/scripture-chooser-dialog.component';
import { DeleteProjectDialogComponent } from './settings/delete-project-dialog/delete-project-dialog.component';
import { SettingsComponent } from './settings/settings.component';
import { CacheService } from './shared/cache-service/cache.service';
import { GlobalNoticesComponent } from './shared/global-notices/global-notices.component';
import { SharedModule } from './shared/shared.module';
import { TextNoteDialogComponent } from './shared/text/text-note-dialog/text-note-dialog.component';
Expand All @@ -46,6 +47,11 @@ import { LynxInsightsModule } from './translate/editor/lynx/insights/lynx-insigh
import { TranslateModule } from './translate/translate.module';
import { UsersModule } from './users/users.module';

/** Initialization function for any services that need to be run but are not depended on by any component. */
function initializeGlobalServicesFactory(_cacheService: CacheService): () => Promise<any> {
return () => Promise.resolve();
}

@NgModule({
declarations: [
AppComponent,
Expand Down Expand Up @@ -97,6 +103,10 @@ import { UsersModule } from './users/users.module';
{ provide: ErrorHandler, useClass: ExceptionHandlingService },
{ provide: OverlayContainer, useClass: InAppRootOverlayContainer },
provideHttpClient(withInterceptorsFromDi()),
provideAppInitializer(() => {
const initializerFn = initializeGlobalServicesFactory(inject(CacheService));
return initializerFn();
}),
provideAppInitializer(() => {
const initializerFn = preloadEnglishTranslations(inject(TranslocoService));
return initializerFn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,18 +368,18 @@ describe('ChapterAudioDialogComponent', () => {
expect(result.timingData[1].to).toEqual(1.296);
}));

it('will not save or upload if there is no audio', fakeAsync(() => {
it('will not save or upload if there is no audio', fakeAsync(async () => {
env.component.prepareTimingFileUpload(env.timingFile);
env.component.save();
await env.component.save();
env.fixture.detectChanges();

expect(env.numberOfTimesDialogClosed).toEqual(0);
expect(env.wrapperAudio.classList.contains('invalid')).toBe(true);
}));

it('will not save or upload if there is no timing data', fakeAsync(() => {
it('will not save or upload if there is no timing data', fakeAsync(async () => {
env.component.audioUpdate(env.audioFile);
env.component.save();
await env.component.save();
env.fixture.detectChanges();

expect(env.numberOfTimesDialogClosed).toEqual(0);
Expand Down Expand Up @@ -478,15 +478,15 @@ describe('ChapterAudioDialogComponent', () => {
expect(env.wrapperTiming.classList.contains('valid')).toBe(true);
}));

it('will not try to save dialog if offline', fakeAsync(() => {
it('will not try to save dialog if offline', fakeAsync(async () => {
env.onlineStatus = false;
env.component.audioUpdate(env.audioFile);
tick();
env.component.prepareTimingFileUpload(env.timingFile);
tick();

// SUT
env.component.save();
await env.component.save();
tick();
env.fixture.detectChanges();
flush();
Expand Down
Loading