Skip to content

Commit b5c99c3

Browse files
committed
Moved training file upload into draft sources page
This follows the Balsamiq design on SF-3434. The only surprise here was that the training files needed to be added to the project settings, since they weren't actually saved until you start a build. I coordinated with Peter on this part.
1 parent c4b4dac commit b5c99c3

15 files changed

+186
-224
lines changed

src/SIL.XForge.Scripture/ClientApp/src/app/core/models/sf-project-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface SFProjectSettings {
99
biblicalTermsEnabled?: boolean | null;
1010

1111
additionalTrainingData?: boolean | null;
12+
additionalTrainingDataFiles?: string[] | null;
1213
additionalTrainingSourceEnabled?: boolean | null;
1314
additionalTrainingSourceParatextId?: string | null;
1415
alternateSourceEnabled?: boolean | null;

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

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -179,36 +179,6 @@ <h2>{{ t("reference_books") }}</h2>
179179
</button>
180180
</div>
181181
</mat-step>
182-
@if (trainingDataFilesAvailable) {
183-
<mat-step [completed]="true">
184-
<ng-template matStepLabel>
185-
{{ t("choose_additional_training_data_files_header") }}
186-
</ng-template>
187-
<h1>{{ t("choose_additional_training_data_files_title") }}</h1>
188-
<app-training-data-multi-select
189-
[availableTrainingData]="availableTrainingFiles"
190-
[selectedTrainingDataIds]="selectedTrainingFileIds"
191-
(trainingDataSelect)="onTrainingDataSelect($event)"
192-
data-test-id="draft-stepper-training-data-files"
193-
></app-training-data-multi-select>
194-
<div class="button-strip">
195-
<button mat-stroked-button matStepperPrevious>
196-
<mat-icon>chevron_{{ i18n.backwardDirectionWord }}</mat-icon>
197-
{{ t("back") }}
198-
</button>
199-
<button
200-
mat-flat-button
201-
(click)="tryAdvanceStep()"
202-
color="primary"
203-
class="advance-button"
204-
[disabled]="isStepsCompleted"
205-
>
206-
{{ t("next") }}
207-
<mat-icon iconPositionEnd>chevron_{{ i18n.forwardDirectionWord }}</mat-icon>
208-
</button>
209-
</div>
210-
</mat-step>
211-
}
212182
@if (featureFlags.showDeveloperTools.enabled) {
213183
<mat-step [completed]="true">
214184
<ng-template matStepLabel>

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

Lines changed: 4 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
44
import { By } from '@angular/platform-browser';
55
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
66
import { createTestProjectProfile } from 'realtime-server/lib/esm/scriptureforge/models/sf-project-test-data';
7-
import { BehaviorSubject, of, Subject } from 'rxjs';
8-
import { anything, instance, mock, verify, when } from 'ts-mockito';
7+
import { BehaviorSubject, of } from 'rxjs';
8+
import { anything, mock, verify, when } from 'ts-mockito';
99
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
1010
import { createTestFeatureFlag, FeatureFlagService } from 'xforge-common/feature-flags/feature-flag.service';
11-
import { RealtimeQuery } from 'xforge-common/models/realtime-query';
1211
import { NoticeService } from 'xforge-common/notice.service';
1312
import { OnlineStatusService } from 'xforge-common/online-status.service';
1413
import { TestRealtimeModule } from 'xforge-common/test-realtime.module';
1514
import { configureTestingModule, TestTranslocoModule } from 'xforge-common/test-utils';
1615
import { SFProjectProfileDoc } from '../../../core/models/sf-project-profile-doc';
1716
import { SF_TYPE_REGISTRY } from '../../../core/models/sf-type-registry';
18-
import { TrainingDataDoc } from '../../../core/models/training-data-doc';
1917
import { ProgressService, TextProgress } from '../../../shared/progress-service/progress.service';
2018
import { NllbLanguageService } from '../../nllb-language.service';
2119
import { DraftSource, DraftSourcesAsArrays, DraftSourcesService } from '../draft-sources.service';
22-
import { TrainingDataService } from '../training-data/training-data.service';
2320
import { DraftGenerationStepsComponent, DraftGenerationStepsResult } from './draft-generation-steps.component';
2421

2522
describe('DraftGenerationStepsComponent', () => {
@@ -29,18 +26,11 @@ describe('DraftGenerationStepsComponent', () => {
2926
const mockActivatedProjectService = mock(ActivatedProjectService);
3027
const mockFeatureFlagService = mock(FeatureFlagService);
3128
const mockNllbLanguageService = mock(NllbLanguageService);
32-
const mockTrainingDataService = mock(TrainingDataService);
3329
const mockProgressService = mock(ProgressService);
3430
const mockOnlineStatusService = mock(OnlineStatusService);
3531
const mockNoticeService = mock(NoticeService);
3632
const mockDraftSourceService = mock(DraftSourcesService);
3733

38-
const mockTrainingDataQuery: RealtimeQuery<TrainingDataDoc> = mock(RealtimeQuery);
39-
const trainingDataQueryLocalChanges$: Subject<void> = new Subject<void>();
40-
when(mockTrainingDataQuery.localChanges$).thenReturn(trainingDataQueryLocalChanges$);
41-
when(mockTrainingDataQuery.ready$).thenReturn(of(true));
42-
when(mockTrainingDataQuery.remoteChanges$).thenReturn(of());
43-
when(mockTrainingDataQuery.remoteDocChanges$).thenReturn(of());
4434
when(mockActivatedProjectService.projectId).thenReturn('project01');
4535

4636
configureTestingModule(() => ({
@@ -50,7 +40,6 @@ describe('DraftGenerationStepsComponent', () => {
5040
{ provide: DraftSourcesService, useMock: mockDraftSourceService },
5141
{ provide: FeatureFlagService, useMock: mockFeatureFlagService },
5242
{ provide: NllbLanguageService, useMock: mockNllbLanguageService },
53-
{ provide: TrainingDataService, useMock: mockTrainingDataService },
5443
{ provide: ProgressService, useMock: mockProgressService },
5544
{ provide: OnlineStatusService, useMock: mockOnlineStatusService },
5645
{ provide: NoticeService, useMock: mockNoticeService },
@@ -127,10 +116,6 @@ describe('DraftGenerationStepsComponent', () => {
127116
when(mockActivatedProjectService.changes$).thenReturn(targetProjectDoc$);
128117
when(mockNllbLanguageService.isNllbLanguageAsync(anything())).thenResolve(true);
129118
when(mockNllbLanguageService.isNllbLanguageAsync('xyz')).thenResolve(false);
130-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
131-
instance(mockTrainingDataQuery)
132-
);
133-
when(mockTrainingDataQuery.docs).thenReturn([]);
134119
when(mockFeatureFlagService.showDeveloperTools).thenReturn(createTestFeatureFlag(false));
135120

136121
fixture = TestBed.createComponent(DraftGenerationStepsComponent);
@@ -408,10 +393,6 @@ describe('DraftGenerationStepsComponent', () => {
408393
when(mockFeatureFlagService.showDeveloperTools).thenReturn(createTestFeatureFlag(false));
409394
when(mockNllbLanguageService.isNllbLanguageAsync(anything())).thenResolve(true);
410395
when(mockNllbLanguageService.isNllbLanguageAsync('xyz')).thenResolve(false);
411-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
412-
instance(mockTrainingDataQuery)
413-
);
414-
when(mockTrainingDataQuery.docs).thenReturn([]);
415396

416397
fixture = TestBed.createComponent(DraftGenerationStepsComponent);
417398
component = fixture.componentInstance;
@@ -662,10 +643,6 @@ describe('DraftGenerationStepsComponent', () => {
662643
when(mockActivatedProjectService.changes$).thenReturn(of({} as any));
663644
when(mockActivatedProjectService.projectDoc).thenReturn({} as any);
664645
when(mockFeatureFlagService.showDeveloperTools).thenReturn(createTestFeatureFlag(true));
665-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
666-
instance(mockTrainingDataQuery)
667-
);
668-
when(mockTrainingDataQuery.docs).thenReturn([]);
669646

670647
fixture = TestBed.createComponent(DraftGenerationStepsComponent);
671648
component = fixture.componentInstance;
@@ -799,10 +776,6 @@ describe('DraftGenerationStepsComponent', () => {
799776
when(mockDraftSourceService.getDraftProjectSources()).thenReturn(of(config));
800777
when(mockActivatedProjectService.projectDoc).thenReturn(mockTargetProjectDoc);
801778
when(mockActivatedProjectService.projectDoc$).thenReturn(of(mockTargetProjectDoc));
802-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
803-
instance(mockTrainingDataQuery)
804-
);
805-
when(mockTrainingDataQuery.docs).thenReturn([]);
806779

807780
fixture = TestBed.createComponent(DraftGenerationStepsComponent);
808781
component = fixture.componentInstance;
@@ -870,61 +843,26 @@ describe('DraftGenerationStepsComponent', () => {
870843
texts: availableBooks,
871844
translateConfig: {
872845
source: { projectRef: 'sourceProject', shortName: 'sP1', writingSystem: { tag: 'eng' } },
873-
draftConfig: { additionalTrainingData: true }
846+
draftConfig: { additionalTrainingData: true, lastSelectedTrainingDataFiles: ['file1'] }
874847
},
875848
writingSystem: { tag: 'nllb' }
876849
})
877850
} as SFProjectProfileDoc;
878851
const targetProjectDoc$ = new BehaviorSubject<SFProjectProfileDoc>(mockTargetProjectDoc);
879-
const mockTrainingDataDoc = mock(TrainingDataDoc);
880852

881853
beforeEach(fakeAsync(() => {
882854
when(mockDraftSourceService.getDraftProjectSources()).thenReturn(of(config));
883855
when(mockActivatedProjectService.projectDoc$).thenReturn(targetProjectDoc$);
884856
when(mockActivatedProjectService.changes$).thenReturn(targetProjectDoc$);
885857
when(mockActivatedProjectService.projectDoc).thenReturn(mockTargetProjectDoc);
886858
when(mockFeatureFlagService.showDeveloperTools).thenReturn(createTestFeatureFlag(false));
887-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
888-
instance(mockTrainingDataQuery)
889-
);
890-
when(mockTrainingDataQuery.docs).thenReturn([mockTrainingDataDoc]);
891859

892860
fixture = TestBed.createComponent(DraftGenerationStepsComponent);
893861
component = fixture.componentInstance;
894862
fixture.detectChanges();
895863
tick();
896864
}));
897865

898-
it('should allow additional training data', () => {
899-
expect(component.trainingDataFilesAvailable).toBe(true);
900-
expect(component.availableTrainingFiles.length).toBe(1);
901-
});
902-
903-
it('updates available training data file after uploaded or deleted', () => {
904-
fixture.detectChanges();
905-
component.tryAdvanceStep();
906-
fixture.detectChanges();
907-
component.onTranslateBookSelect([3], config.draftingSources[0]);
908-
fixture.detectChanges();
909-
component.tryAdvanceStep();
910-
component.onTranslatedBookSelect([2]);
911-
fixture.detectChanges();
912-
component.tryAdvanceStep();
913-
expect(component.availableTrainingFiles.length).toEqual(1);
914-
915-
// Delete a training data file
916-
when(mockTrainingDataQuery.docs).thenReturn([]);
917-
trainingDataQueryLocalChanges$.next();
918-
fixture.detectChanges();
919-
expect(component.availableTrainingFiles.length).toEqual(0);
920-
921-
// Upload a training data file
922-
when(mockTrainingDataQuery.docs).thenReturn([mockTrainingDataDoc]);
923-
trainingDataQueryLocalChanges$.next();
924-
fixture.detectChanges();
925-
expect(component.availableTrainingFiles.length).toEqual(1);
926-
});
927-
928866
it('generates draft with training data file', () => {
929867
fixture.detectChanges();
930868
component.tryAdvanceStep();
@@ -935,13 +873,7 @@ describe('DraftGenerationStepsComponent', () => {
935873
component.onTranslatedBookSelect([2]);
936874
fixture.detectChanges();
937875
component.tryAdvanceStep();
938-
expect(component.availableTrainingFiles.length).toEqual(1);
939-
expect(component.selectedTrainingFileIds).toEqual([]);
940876

941-
const fileIds = ['file1'];
942-
component.onTrainingDataSelect(fileIds);
943-
fixture.detectChanges();
944-
expect(component.selectedTrainingFileIds).toEqual(fileIds);
945877
spyOn(component.done, 'emit');
946878
component.tryAdvanceStep();
947879
fixture.detectChanges();
@@ -950,7 +882,7 @@ describe('DraftGenerationStepsComponent', () => {
950882
expect(component.done.emit).toHaveBeenCalledWith({
951883
trainingScriptureRanges: [{ projectId: 'source1', scriptureRange: 'EXO' }],
952884
translationScriptureRanges: [{ projectId: 'draftingSource', scriptureRange: 'LEV' }],
953-
trainingDataFiles: fileIds,
885+
trainingDataFiles: ['file1'],
954886
fastTraining: false,
955887
useEcho: false
956888
});
@@ -1021,10 +953,6 @@ describe('DraftGenerationStepsComponent', () => {
1021953
when(mockActivatedProjectService.projectDoc$).thenReturn(
1022954
new BehaviorSubject<SFProjectProfileDoc>(mockTargetProjectDoc)
1023955
);
1024-
when(mockTrainingDataService.queryTrainingDataAsync(anything(), anything())).thenResolve(
1025-
instance(mockTrainingDataQuery)
1026-
);
1027-
when(mockTrainingDataQuery.docs).thenReturn([]);
1028956
when(mockFeatureFlagService.showDeveloperTools).thenReturn(createTestFeatureFlag(false));
1029957

1030958
fixture = TestBed.createComponent(DraftGenerationStepsComponent);

0 commit comments

Comments
 (0)