- {{ t("draft_queued_header") }}
- @if (!hasDraftQueueDepth(draftJob)) {
- {{ t("draft_queued_detail") }}
+ @if (isSyncing()) {
+ {{ t("draft_syncing") }}
+ {{ t("draft_syncing_detail") }}
} @else {
-
- {{ t("draft_queued_detail_multiple", { count: draftJob.queueDepth }) }}
-
+ {{ t("draft_queued_header") }}
+ @if (!hasDraftQueueDepth(draftJob)) {
+ {{ t("draft_queued_detail") }}
+ } @else {
+
+ {{ t("draft_queued_detail_multiple", { count: draftJob.queueDepth }) }}
+
+ }
}
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.spec.ts
index 0c89087bd0..f8cc3492be 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.spec.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.spec.ts
@@ -1,5 +1,5 @@
import { HttpErrorResponse } from '@angular/common/http';
-import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
@@ -10,12 +10,12 @@ import { SFProjectRole } from 'realtime-server/lib/esm/scriptureforge/models/sf-
import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data';
import { TextInfoPermission } from 'realtime-server/lib/esm/scriptureforge/models/text-info-permission';
import { ProjectType } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
-import { BehaviorSubject, EMPTY, Subject, of, throwError } from 'rxjs';
+import { BehaviorSubject, EMPTY, of, Subject, throwError } from 'rxjs';
import { instance, mock, verify, when } from 'ts-mockito';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
import { AuthService } from 'xforge-common/auth.service';
import { DialogService } from 'xforge-common/dialog.service';
-import { FeatureFlagService, createTestFeatureFlag } from 'xforge-common/feature-flags/feature-flag.service';
+import { createTestFeatureFlag, FeatureFlagService } from 'xforge-common/feature-flags/feature-flag.service';
import { I18nService } from 'xforge-common/i18n.service';
import { Locale } from 'xforge-common/models/i18n-locale';
import { UserDoc } from 'xforge-common/models/user-doc';
@@ -2096,6 +2096,49 @@ describe('DraftGenerationComponent', () => {
verify(mockDialogRef.close()).once();
});
+ it('should track whether the current project is not syncing', fakeAsync(() => {
+ let env = new TestEnvironment();
+ env.fixture.detectChanges();
+ tick();
+
+ expect(env.component.isSyncing()).toBe(false);
+ }));
+
+ it('should track whether the current project is syncing', fakeAsync(() => {
+ const projectDoc: SFProjectProfileDoc = {
+ data: createTestProjectProfile({
+ writingSystem: {
+ tag: 'xyz'
+ },
+ translateConfig: {
+ projectType: ProjectType.BackTranslation,
+ source: {
+ projectRef: 'testSourceProjectId',
+ writingSystem: {
+ tag: 'en'
+ }
+ }
+ },
+ sync: {
+ queuedCount: 1
+ }
+ })
+ } as SFProjectProfileDoc;
+ let env = new TestEnvironment(() => {
+ mockActivatedProjectService = jasmine.createSpyObj('ActivatedProjectService', [''], {
+ projectId: projectId,
+ projectId$: of(projectId),
+ projectDoc: projectDoc,
+ projectDoc$: of(projectDoc),
+ changes$: of(projectDoc)
+ });
+ });
+ env.fixture.detectChanges();
+ tick();
+
+ expect(env.component.isSyncing()).toBe(true);
+ }));
+
it('should display the Paratext credentials update prompt when startBuild throws a forbidden error', fakeAsync(() => {
let env = new TestEnvironment(() => {
mockDraftGenerationService.startBuildOrGetActiveBuild.and.returnValue(
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.ts
index 0ee7c57ae0..f2ab2ee892 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.ts
@@ -10,7 +10,7 @@ import { RouterLink } from 'ngx-transloco-markup-router-link';
import { SystemRole } from 'realtime-server/lib/esm/common/models/system-role';
import { SFProjectRole } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-role';
import { ProjectType } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
-import { Subscription, combineLatest, of } from 'rxjs';
+import { combineLatest, of, Subscription } from 'rxjs';
import { catchError, filter, switchMap, tap } from 'rxjs/operators';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
import { AuthService } from 'xforge-common/auth.service';
@@ -33,7 +33,7 @@ import { ServalProjectComponent } from '../../serval-administration/serval-proje
import { SharedModule } from '../../shared/shared.module';
import { WorkingAnimatedIndicatorComponent } from '../../shared/working-animated-indicator/working-animated-indicator.component';
import { NllbLanguageService } from '../nllb-language.service';
-import { BuildConfig, DraftZipProgress, activeBuildStates } from './draft-generation';
+import { activeBuildStates, BuildConfig, DraftZipProgress } from './draft-generation';
import {
DraftGenerationStepsComponent,
DraftGenerationStepsResult
@@ -478,6 +478,10 @@ export class DraftGenerationComponent extends DataLoadingComponent implements On
return activeBuildStates.includes(job?.state as BuildStates);
}
+ isSyncing(): boolean {
+ return this.activatedProject.projectDoc.data.sync.queuedCount > 0;
+ }
+
isDraftQueued(job?: BuildDto): boolean {
return [BuildStates.Queued, BuildStates.Pending].includes(job?.state as BuildStates);
}
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 9b4b9235c9..ddc1f57275 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
@@ -189,6 +189,8 @@
"draft_active_detail": "Generating draft; this usually takes at least {{ count }} hours.",
"draft_active_header": "Draft in progress",
"draft_is_ready": "Your draft is ready",
+ "draft_syncing": "Draft initializing",
+ "draft_syncing_detail": "Your project is being synced before queuing the draft.",
"draft_queued_detail_multiple": "The translation draft generation is number {{ count }} in the queue, and will begin once the server is finished with other projects. Please check back later.",
"draft_queued_detail": "Generation of the translation draft has been queued, and will begin once the server is finished with another project. Please check back later.",
"draft_queued_header": "Draft queued",