Skip to content

Commit fb0b5be

Browse files
committed
SF-3742 Prompt user to select formatting options before generating draft
1 parent 6b4e141 commit fb0b5be

File tree

8 files changed

+69
-22
lines changed

8 files changed

+69
-22
lines changed

src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ <h1>
227227
@if (!isDraftInProgress(draftJob) && !hasAnyCompletedBuild) {
228228
<section class="action-button-strip">
229229
@if (isSourcesConfigurationComplete) {
230-
<button mat-flat-button color="primary" (click)="generateDraft()">
230+
<button mat-flat-button color="primary" (click)="generateDraftClicked()">
231231
<mat-icon>auto_awesome</mat-icon>
232232
{{ t("generate_draft_button") }}
233233
</button>
@@ -358,7 +358,7 @@ <h3>{{ t("draft_finishing_header") }}</h3>
358358
@if (hasDraftBooksAvailable) {
359359
<app-draft-download-button [build]="lastCompletedBuild" />
360360
@if (featureFlags.usfmFormat.enabled) {
361-
<button mat-button [routerLink]="['format']">
361+
<button mat-button [routerLink]="draftOptionsService.formattingOptionsPath">
362362
<mat-icon>settings</mat-icon>
363363
{{ t("format_draft") }}
364364
</button>
@@ -395,7 +395,7 @@ <h3>{{ t("draft_finishing_header") }}</h3>
395395
mat-flat-button
396396
color="primary"
397397
type="button"
398-
(click)="generateDraft({ withConfirm: !featureFlags.newDraftHistory.enabled })"
398+
(click)="generateDraftClicked({ withConfirm: !featureFlags.newDraftHistory.enabled })"
399399
>
400400
<mat-icon>add</mat-icon> {{ t("generate_new_draft") }}
401401
</button>

src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-generation.component.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
import { DraftGenerationService } from './draft-generation.service';
5959
import { DraftHistoryListComponent } from './draft-history-list/draft-history-list.component';
6060
import { DraftInformationComponent } from './draft-information/draft-information.component';
61+
import { DraftOptionsService } from './draft-options.service';
6162
import { DraftPreviewBooksComponent } from './draft-preview-books/draft-preview-books.component';
6263
import { DRAFT_SIGNUP_RESPONSE_DAYS } from './draft-signup-form/draft-onboarding-form.component';
6364
import { DraftSource } from './draft-source';
@@ -176,6 +177,7 @@ export class DraftGenerationComponent extends DataLoadingComponent implements On
176177
protected readonly noticeService: NoticeService,
177178
protected readonly urlService: ExternalUrlService,
178179
protected readonly featureFlags: FeatureFlagService,
180+
protected readonly draftOptionsService: DraftOptionsService,
179181
private readonly projectService: SFProjectService,
180182
private destroyRef: DestroyRef
181183
) {
@@ -332,7 +334,30 @@ export class DraftGenerationComponent extends DataLoadingComponent implements On
332334
});
333335
}
334336

335-
async generateDraft({ withConfirm = false } = {}): Promise<void> {
337+
get formattingOptionsRequired(): boolean {
338+
return (
339+
this.draftOptionsService.areFormattingOptionsSupportedForBuild(this.lastCompletedBuild) &&
340+
!this.draftOptionsService.areFormattingOptionsSelected()
341+
);
342+
}
343+
344+
async generateDraftClicked({ withConfirm = false } = {}): Promise<void> {
345+
if (this.formattingOptionsRequired) {
346+
const dialogRef = this.dialogService.openGenericDialog({
347+
title: this.i18n.translate('draft_generation.choose_formatting_options'),
348+
message: this.i18n.translate('draft_generation.choose_formatting_options_before_new_draft'),
349+
options: [
350+
{
351+
value: true,
352+
label: this.i18n.translate('draft_generation.formatting_options'),
353+
highlight: true,
354+
icon: 'build'
355+
}
356+
]
357+
});
358+
if (await dialogRef.result) await this.router.navigate(this.draftOptionsService.formattingOptionsPath);
359+
return;
360+
}
336361
if (withConfirm) {
337362
const isConfirmed: boolean | undefined = await this.dialogService.openGenericDialog({
338363
title: this.i18n.translate('draft_generation.dialog_confirm_draft_regeneration_title'),

src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-history-list/draft-history-entry/draft-history-entry.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
{{ t("select_formatting_options") }}
2727
</p>
2828
<div class="formatting-options-container">
29-
<button matButton="filled" class="format-usfm" [routerLink]="['format']">
29+
<button matButton="filled" class="format-usfm" [routerLink]="draftOptionsService.formattingOptionsPath">
3030
<mat-icon>build</mat-icon>
3131
<span class="hide-lt-lg">{{ t("formatting_options") }}</span>
3232
<span class="hide-gt-lg">{{ t("formatting") }}</span>
@@ -56,7 +56,7 @@
5656
</button>
5757
<app-draft-download-button matButton="outlined" [build]="entry" />
5858
@if (formattingOptionsSupported && isLatestBuild) {
59-
<button matButton class="format-usfm" [routerLink]="['format']">
59+
<button matButton class="format-usfm" [routerLink]="draftOptionsService.formattingOptionsPath">
6060
<mat-icon>build</mat-icon> {{ t("formatting_options") }}
6161
</button>
6262
}

src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-history-list/draft-history-entry/draft-history-entry.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export class DraftHistoryEntryComponent {
338338
private readonly trainingDataService: TrainingDataService,
339339
private readonly activatedProjectService: ActivatedProjectService,
340340
readonly featureFlags: FeatureFlagService,
341-
private readonly draftOptionsService: DraftOptionsService,
341+
protected readonly draftOptionsService: DraftOptionsService,
342342
private readonly permissionsService: PermissionsService,
343343
private readonly destroyRef: DestroyRef,
344344
private readonly dialog: MatDialog

src/SIL.XForge.Scripture/ClientApp/src/app/translate/draft-generation/draft-options.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,8 @@ export class DraftOptionsService {
3636
? new Date(entry.additionalInfo.dateFinished) > FORMATTING_OPTIONS_SUPPORTED_DATE
3737
: false;
3838
}
39+
40+
get formattingOptionsPath(): string[] {
41+
return ['projects', this.activatedProjectService.projectId!, 'draft-generation', 'format'];
42+
}
3943
}

src/SIL.XForge.Scripture/ClientApp/src/assets/i18n/non_checking_en.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@
169169
"successfully_applied_all_chapters": "Successfully applied all chapters to {{ bookName }}"
170170
},
171171
"draft_generation": {
172+
"choose_formatting_options": "Choose formatting options to continue",
173+
"choose_formatting_options_before_new_draft": "Before you can create a new draft, you need to choose formatting options.",
174+
"formatting_options": "Formatting options",
172175
"back_translation_requirement": "Back translation drafts can only be generated into the roughly 200 [link:supportedLanguagesUrl]supported languages[/link].",
173176
"cancel_generation_button": "Cancel",
174177
"configure_sources": "Configure sources",
@@ -299,7 +302,7 @@
299302
"options_for_paragraph_breaks_and_quotation_marks": "Options for paragraph breaks and quotation marks to make editing easier",
300303
"requested_at": "Requested {{ requestedAtTime }}.",
301304
"requested_by": "Requested by {{ requestedByUserName }} at {{ requestedAtTime }}.",
302-
"select_formatting_options": "The draft has been created, and there are new formatting options to select. You will only need to do this once, but you can change them whenever you wish.",
305+
"select_formatting_options": "The draft has been created. Choose formatting options to continue.",
303306
"show_model_training_configuration": "Show model training configuration",
304307
"training_books": "Training books",
305308
"training_data_files_used": "The following data files were used to train the model.",

src/SIL.XForge.Scripture/ClientApp/src/xforge-common/generic-dialog/generic-dialog.component.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,18 @@ <h2 mat-dialog-title>{{ title }}</h2>
88
@for (option of options; track option.label) {
99
@if (option.highlight) {
1010
<button mat-flat-button color="primary" [mat-dialog-close]="option.value">
11+
@if (option.icon != null) {
12+
<mat-icon>{{ option.icon }}</mat-icon>
13+
}
1114
{{ option.label | async }}
1215
</button>
1316
} @else {
14-
<button mat-button [mat-dialog-close]="option.value">{{ option.label | async }}</button>
17+
<button mat-button [mat-dialog-close]="option.value">
18+
@if (option.icon != null) {
19+
<mat-icon>{{ option.icon }}</mat-icon>
20+
}
21+
{{ option.label | async }}
22+
</button>
1523
}
1624
}
1725
</div>
Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
import { CdkScrollable } from '@angular/cdk/scrolling';
2+
import { AsyncPipe } from '@angular/common';
13
import { Component, Inject } from '@angular/core';
4+
import { MatButton } from '@angular/material/button';
25
import {
36
MAT_DIALOG_DATA,
4-
MatDialogRef,
5-
MatDialogTitle,
6-
MatDialogContent,
77
MatDialogActions,
8-
MatDialogClose
8+
MatDialogClose,
9+
MatDialogContent,
10+
MatDialogRef,
11+
MatDialogTitle
912
} from '@angular/material/dialog';
13+
import { MatIcon } from '@angular/material/icon';
1014
import { Observable } from 'rxjs';
11-
import { CdkScrollable } from '@angular/cdk/scrolling';
12-
import { MatButton } from '@angular/material/button';
13-
import { AsyncPipe } from '@angular/common';
1415

1516
export interface GenericDialogOptions<T> {
1617
title?: Observable<string>;
@@ -19,6 +20,7 @@ export interface GenericDialogOptions<T> {
1920
label: Observable<string>;
2021
value: T;
2122
highlight?: boolean;
23+
icon?: string;
2224
}[];
2325
}
2426

@@ -33,7 +35,16 @@ export interface GenericDialogRef<T> {
3335
@Component({
3436
selector: 'app-generic-dialog',
3537
templateUrl: './generic-dialog.component.html',
36-
imports: [MatDialogTitle, CdkScrollable, MatDialogContent, MatDialogActions, MatButton, MatDialogClose, AsyncPipe]
38+
imports: [
39+
MatDialogTitle,
40+
CdkScrollable,
41+
MatDialogContent,
42+
MatDialogActions,
43+
MatButton,
44+
MatDialogClose,
45+
AsyncPipe,
46+
MatIcon
47+
]
3748
})
3849
export class GenericDialogComponent<T> {
3950
constructor(@Inject(MAT_DIALOG_DATA) private readonly data: GenericDialogOptions<T>) {}
@@ -46,11 +57,7 @@ export class GenericDialogComponent<T> {
4657
return this.data.message;
4758
}
4859

49-
get options(): {
50-
label: Observable<string>;
51-
value: T;
52-
highlight?: boolean | undefined;
53-
}[] {
60+
get options(): GenericDialogOptions<T>['options'] {
5461
return this.data.options;
5562
}
5663
}

0 commit comments

Comments
 (0)