diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.scss b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.scss
index 8f370cbbf3..0e77c38448 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.scss
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.scss
@@ -85,7 +85,16 @@ form {
.actions {
display: flex;
- justify-content: space-between;
+ column-gap: 8px;
+ align-items: center;
+ justify-content: flex-end;
+
+ .progress {
+ visibility: hidden;
+ &.saving {
+ visibility: visible;
+ }
+ }
}
.new {
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.spec.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.spec.ts
index 9686f9a588..ac1c194c23 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.spec.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.spec.ts
@@ -5,7 +5,11 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router';
import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data';
import { TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
-import { DraftUsfmConfig, ParagraphBreakFormat } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
+import {
+ DraftUsfmConfig,
+ ParagraphBreakFormat,
+ QuoteFormat
+} from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
import { of } from 'rxjs';
import { anything, deepEqual, mock, verify, when } from 'ts-mockito';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
@@ -94,9 +98,10 @@ describe('DraftUsfmFormatComponent', () => {
verify(mockedDraftHandlingService.getDraft(anything(), anything())).thrice();
}));
- it('should initialize and default to best guess', fakeAsync(async () => {
+ it('should initialize and default to best guess and automatic quotes', fakeAsync(async () => {
const env = new TestEnvironment();
expect(env.component.paragraphFormat.value).toBe(ParagraphBreakFormat.BestGuess);
+ expect(env.component.quoteFormat.value).toBe(QuoteFormat.Automatic);
expect(await env.component.confirmLeave()).toBe(true);
}));
@@ -143,7 +148,8 @@ describe('DraftUsfmFormatComponent', () => {
env.fixture.detectChanges();
verify(mockedProjectService.onlineSetUsfmConfig(env.projectId, deepEqual(config))).once();
verify(mockedServalAdministration.onlineRetrievePreTranslationStatus(env.projectId)).once();
- verify(mockedRouter.navigate(deepEqual(['projects', env.projectId, 'draft-generation']))).never();
+ verify(mockedNoticeService.show(anything())).once();
+ verify(mockedRouter.navigate(deepEqual(['projects', env.projectId, 'draft-generation']))).once();
}));
it('should not save if format is empty', fakeAsync(() => {
@@ -183,6 +189,7 @@ class TestEnvironment {
this.onlineStatusService.setIsOnline(true);
when(mockedNoticeService.show(anything())).thenResolve();
when(mockedDialogService.confirm(anything(), anything(), anything())).thenResolve(true);
+ when(mockedServalAdministration.onlineRetrievePreTranslationStatus(anything())).thenResolve();
this.setupProject(args.config);
this.fixture = TestBed.createComponent(DraftUsfmFormatComponent);
this.component = this.fixture.componentInstance;
diff --git a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.ts b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.ts
index a366c70b7d..819a406268 100644
--- a/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.ts
+++ b/src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-usfm-format/draft-usfm-format.component.ts
@@ -13,7 +13,11 @@ import { Router } from '@angular/router';
import { translate, TranslocoModule } from '@ngneat/transloco';
import { Delta } from 'quill';
import { TextInfo } from 'realtime-server/lib/esm/scriptureforge/models/text-info';
-import { DraftUsfmConfig, ParagraphBreakFormat } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
+import {
+ DraftUsfmConfig,
+ ParagraphBreakFormat,
+ QuoteFormat
+} from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
import { combineLatest, first, Subject, switchMap } from 'rxjs';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
import { DataLoadingComponent } from 'xforge-common/data-loading-component';
@@ -59,12 +63,17 @@ export class DraftUsfmFormatComponent extends DataLoadingComponent implements Af
chapters: number[] = [];
isInitializing: boolean = true;
paragraphBreakFormat = ParagraphBreakFormat;
+ quoteStyleFormat = QuoteFormat;
paragraphFormat = new FormControl(ParagraphBreakFormat.BestGuess);
+ quoteFormat = new FormControl(QuoteFormat.Automatic);
usfmFormatForm: FormGroup = new FormGroup({
- paragraphFormat: this.paragraphFormat
+ paragraphFormat: this.paragraphFormat,
+ quoteFormat: this.quoteFormat
});
+ protected saving = false;
+
private updateDraftConfig$: Subject = new Subject();
private lastSavedState?: DraftUsfmConfig;
@@ -167,14 +176,18 @@ export class DraftUsfmFormatComponent extends DataLoadingComponent implements Af
if (this.projectId == null || !this.isOnline || this.currentFormat == null) return;
try {
+ this.saving = true;
await this.projectService.onlineSetUsfmConfig(this.projectId, this.currentFormat);
this.lastSavedState = this.currentFormat;
// not awaited so that the user is directed to the draft generation page
this.servalAdministration.onlineRetrievePreTranslationStatus(this.projectId).then(() => {
+ this.router.navigate(['projects', this.projectId, 'draft-generation']);
this.noticeService.show(translate('draft_usfm_format.changes_have_been_saved'));
});
} catch {
this.noticeService.showError(translate('draft_usfm-format.failed_to_save'));
+ } finally {
+ this.saving = false;
}
}
@@ -189,7 +202,8 @@ export class DraftUsfmFormatComponent extends DataLoadingComponent implements Af
private setUsfmConfig(config?: DraftUsfmConfig): void {
this.usfmFormatForm.setValue({
- paragraphFormat: config?.paragraphFormat ?? ParagraphBreakFormat.BestGuess
+ paragraphFormat: config?.paragraphFormat ?? ParagraphBreakFormat.BestGuess,
+ quoteFormat: QuoteFormat.Automatic
});
this.lastSavedState = this.currentFormat;
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 c7c8fddec7..d912281c5c 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
@@ -335,17 +335,18 @@
"changes_have_been_saved": "Changes have been saved",
"cancel": "Cancel",
"connect_to_the_internet": "Please connect to the internet to change the USFM format for your draft",
- "draft_format_description": "Your draft has completed. However, there are some formatting options that you can choose before using your draft.",
+ "draft_format_description": "The draft has been created. Here are some formatting options for the text. You can try each option to see the difference it makes.",
"draft_format_options": "Format draft",
"failed_to_save": "Failed to save changes. Try again later.",
+ "new": "New",
"option_best_guess": "Best guess",
- "option_best_guess_description": "Mid-verse paragraph breaks in the source will be placed at the best guess of where they should be in the draft.",
+ "option_best_guess_description": "Line breaks in the source will be placed at the best guess of where they should be in the draft. Recommended for most projects.",
"option_end": "Move to end",
- "option_end_description": "Mid-verse paragraph breaks in the source will be moved to the end of the verse in the draft.",
+ "option_end_description": "Line breaks in the source will be moved to the end of the verse.",
"option_remove": "Remove",
- "option_remove_description": "Mid-verse paragraph breaks in the source will be omitted in the draft.",
- "paragraph_break_description": "Scripture Forge translates each verse as a whole for best text quality. Choose how the paragraph breaks from the source verses are placed.",
- "paragraph_break_title": "Mid-verse paragraph breaks",
+ "option_remove_description": "Line breaks in the source will be omitted from the draft.",
+ "line_breaks_description": "Scripture Forge translates complete verses, without line breaks, because this gives the best draft. Choose where to place the line breaks from the source.",
+ "line_breaks_title": "Line breaks",
"save_changes": "Save"
},
"editor": {