Skip to content

Commit

Permalink
Migrate last selected books to last selected scripture ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
RaymondLuong3 committed Dec 9, 2024
1 parent 4805aff commit 8a007bb
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 58 deletions.
9 changes: 9 additions & 0 deletions src/RealtimeServer/scriptureforge/models/translate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ export interface BaseProject {
shortName: string;
}

/**
* A per-project scripture range.
*/
export interface ProjectScriptureRange {
projectId: string;
scriptureRange: string;
}

export interface DraftConfig {
additionalTrainingData: boolean;
additionalTrainingSourceEnabled: boolean;
Expand All @@ -38,6 +46,7 @@ export interface DraftConfig {
lastSelectedTrainingBooks: number[];
lastSelectedTrainingDataFiles: string[];
lastSelectedTrainingScriptureRange?: string;
lastSelectedTrainingScriptureRanges?: ProjectScriptureRange[];
lastSelectedTranslationBooks: number[];
lastSelectedTranslationScriptureRange?: string;
servalConfig?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,36 +220,36 @@ describe('SFProjectMigrations', () => {
expect(projectDoc.data.translateConfig.preTranslate).toBe(false);
});
});
});

describe('version 11', () => {
it('adds biblical terms properties', async () => {
const env = new TestEnvironment(10);
const conn = env.server.connect();
await createDoc(conn, SF_PROJECTS_COLLECTION, 'project01', {});
let projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.biblicalTermsConfig).not.toBeDefined();
describe('version 11', () => {
it('adds biblical terms properties', async () => {
const env = new TestEnvironment(10);
const conn = env.server.connect();
await createDoc(conn, SF_PROJECTS_COLLECTION, 'project01', {});
let projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.biblicalTermsConfig).not.toBeDefined();

await env.server.migrateIfNecessary();
await env.server.migrateIfNecessary();

projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.biblicalTermsConfig.biblicalTermsEnabled).toBe(false);
expect(projectDoc.data.biblicalTermsConfig.hasRenderings).toBe(false);
projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.biblicalTermsConfig.biblicalTermsEnabled).toBe(false);
expect(projectDoc.data.biblicalTermsConfig.hasRenderings).toBe(false);
});
});
});

describe('version 12', () => {
it('adds draftConfig to translateConfig', async () => {
const env = new TestEnvironment(11);
const conn = env.server.connect();
await createDoc(conn, SF_PROJECTS_COLLECTION, 'project01', { translateConfig: {} });
let projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig).not.toBeDefined();
describe('version 12', () => {
it('adds draftConfig to translateConfig', async () => {
const env = new TestEnvironment(11);
const conn = env.server.connect();
await createDoc(conn, SF_PROJECTS_COLLECTION, 'project01', { translateConfig: {} });
let projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig).not.toBeDefined();

await env.server.migrateIfNecessary();
await env.server.migrateIfNecessary();

projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig).toBeDefined();
projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig).toBeDefined();
});
});

describe('version 13', () => {
Expand Down Expand Up @@ -455,6 +455,28 @@ describe('version 12', () => {
expect(projectDoc.data.translateConfig.draftConfig.additionalTrainingSourceEnabled).toBe(false);
});
});

describe('version 21', () => {
it('copies selected training and translation books to scripture ranges', async () => {
const env = new TestEnvironment(20);
const conn = env.server.connect();

await createDoc(conn, SF_PROJECTS_COLLECTION, 'project01', {
translateConfig: { draftConfig: { lastSelectedTrainingBooks: [1, 2, 3], lastSelectedTranslationBooks: [4, 5] } }
});
let projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTrainingBooks).toEqual([1, 2, 3]);
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTranslationBooks).toEqual([4, 5]);

await env.server.migrateIfNecessary();

projectDoc = await fetchDoc(conn, SF_PROJECTS_COLLECTION, 'project01');
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTrainingBooks).toEqual([1, 2, 3]);
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTranslationBooks).toEqual([4, 5]);
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTrainingScriptureRange).toEqual('GEN;EXO;LEV');
expect(projectDoc.data.translateConfig.draftConfig.lastSelectedTranslationScriptureRange).toEqual('NUM;DEU');
});
});
});

class TestEnvironment {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Canon } from '@sillsdev/scripture';
import { Doc, Op } from 'sharedb/lib/client';
import { DocMigration, MigrationConstructor } from '../../common/migration';
import { submitMigrationOp } from '../../common/realtime-server';
Expand Down Expand Up @@ -343,6 +344,38 @@ class SFProjectMigration20 extends DocMigration {
}
}

class SFProjectMigration21 extends DocMigration {
static readonly VERSION = 21;

async migrateDoc(doc: Doc): Promise<void> {
const ops: Op[] = [];
if (doc.data.translateConfig.draftConfig.lastSelectedTrainingScriptureRange == null) {
const trainingRangeFromBooks: string[] = doc.data.translateConfig.draftConfig.lastSelectedTrainingBooks.map(
(b: number) => Canon.bookNumberToId(b)
);
if (trainingRangeFromBooks.length > 0) {
ops.push({
p: ['translateConfig', 'draftConfig', 'lastSelectedTrainingScriptureRange'],
oi: trainingRangeFromBooks.join(';')
});
}
}
if (doc.data.translateConfig.draftConfig.lastSelectedTranslationScriptureRange == null) {
const translationRangeFromBooks: string[] = doc.data.translateConfig.draftConfig.lastSelectedTranslationBooks.map(
(b: number) => Canon.bookNumberToId(b)
);
if (translationRangeFromBooks.length > 0) {
ops.push({
p: ['translateConfig', 'draftConfig', 'lastSelectedTranslationScriptureRange'],
oi: translationRangeFromBooks.join(';')
});
}
}

await submitMigrationOp(SFProjectMigration20.VERSION, doc, ops);
}
}

export const SF_PROJECT_MIGRATIONS: MigrationConstructor[] = [
SFProjectMigration1,
SFProjectMigration2,
Expand All @@ -363,5 +396,6 @@ export const SF_PROJECT_MIGRATIONS: MigrationConstructor[] = [
SFProjectMigration17,
SFProjectMigration18,
SFProjectMigration19,
SFProjectMigration20
SFProjectMigration20,
SFProjectMigration21
];
15 changes: 15 additions & 0 deletions src/RealtimeServer/scriptureforge/services/sf-project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,21 @@ export class SFProjectService extends ProjectService<SFProject> {
lastSelectedTrainingScriptureRange: {
bsonType: 'string'
},
lastSelectedTrainingScriptureRanges: {
bsonType: 'array',
items: {
bsonType: 'object',
properties: {
projectId: {
bsonType: 'string'
},
scriptureRange: {
bsonType: 'string'
}
},
additionalProperties: false
}
},
lastSelectedTranslationBooks: {
bsonType: 'array',
items: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,9 @@ describe('ServalProjectComponent', () => {
shortName: 'P4'
},
lastSelectedTrainingBooks: preTranslate ? [1, 2] : [],
lastSelectedTranslationBooks: preTranslate ? [3, 4] : []
lastSelectedTranslationBooks: preTranslate ? [3, 4] : [],
lastSelectedTrainingScriptureRange: preTranslate ? 'GEN;EXO' : undefined,
lastSelectedTranslationScriptureRange: preTranslate ? 'LEV;NUM' : undefined
},
preTranslate,
source: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { SFProjectService } from '../core/sf-project.service';
import { BuildDto } from '../machine-api/build-dto';
import { NoticeComponent } from '../shared/notice/notice.component';
import { SharedModule } from '../shared/shared.module';
import { projectLabel } from '../shared/utils';
import { booksFromScriptureRange, projectLabel } from '../shared/utils';
import { DraftZipProgress } from '../translate/draft-generation/draft-generation';
import { DraftGenerationService } from '../translate/draft-generation/draft-generation.service';
import { DraftInformationComponent } from '../translate/draft-generation/draft-information/draft-information.component';
Expand Down Expand Up @@ -142,13 +142,13 @@ export class ServalProjectComponent extends DataLoadingComponent implements OnIn
this.rows = rows;

// Setup the books
this.trainingBooks = project.translateConfig.draftConfig.lastSelectedTrainingBooks.map(bookNum =>
Canon.bookNumberToEnglishName(bookNum)
);
this.trainingBooks = booksFromScriptureRange(
project.translateConfig.draftConfig.lastSelectedTrainingScriptureRange ?? ''
).map(bookNum => Canon.bookNumberToEnglishName(bookNum));
this.trainingFiles = project.translateConfig.draftConfig.lastSelectedTrainingDataFiles;
this.translationBooks = project.translateConfig.draftConfig.lastSelectedTranslationBooks.map(bookNum =>
Canon.bookNumberToEnglishName(bookNum)
);
this.translationBooks = booksFromScriptureRange(
project.translateConfig.draftConfig.lastSelectedTranslationScriptureRange ?? ''
).map(bookNum => Canon.bookNumberToEnglishName(bookNum));

this.draftConfig = project.translateConfig.draftConfig;
this.draftJob$ = SFProjectService.hasDraft(project) ? this.getDraftJob(projectDoc.id) : of(undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ describe('DraftGenerationStepsComponent', () => {
expect(component.done.emit).toHaveBeenCalledWith({
trainingDataFiles,
trainingScriptureRanges: [{ projectId: 'sourceProject', scriptureRange: 'LEV' }],
translationScriptureRanges: [{ projectId: 'sourceProject', scriptureRange: 'GEN;EXO' }],
translationScriptureRange: 'GEN;EXO',
fastTraining: false
} as DraftGenerationStepsResult);
expect(component.isStepsCompleted).toBe(true);
Expand Down Expand Up @@ -482,7 +482,7 @@ describe('DraftGenerationStepsComponent', () => {
{ projectId: 'sourceProject', scriptureRange: 'LEV' },
{ projectId: 'sourceProject2', scriptureRange: 'LEV' }
],
translationScriptureRanges: [{ projectId: 'sourceProject', scriptureRange: 'GEN;EXO' }],
translationScriptureRange: 'GEN;EXO',
fastTraining: false
} as DraftGenerationStepsResult);
expect(component.isStepsCompleted).toBe(true);
Expand Down Expand Up @@ -562,7 +562,7 @@ describe('DraftGenerationStepsComponent', () => {
expect(component.done.emit).toHaveBeenCalledWith({
trainingDataFiles,
trainingScriptureRanges: [{ projectId: 'sourceProject', scriptureRange: 'GEN;EXO' }],
translationScriptureRanges: [{ projectId: 'sourceProject', scriptureRange: 'LEV;NUM' }],
translationScriptureRange: 'LEV;NUM',
fastTraining: true
} as DraftGenerationStepsResult);
expect(generateDraftButton['disabled']).toBe(true);
Expand All @@ -578,7 +578,7 @@ describe('DraftGenerationStepsComponent', () => {
draftConfig: {
lastSelectedTrainingDataFiles: [],
lastSelectedTranslationScriptureRange: 'GEN;EXO',
lastSelectedTrainingScriptureRange: 'LEV'
lastSelectedTrainingScriptureRanges: [{ projectId: 'test', scriptureRange: 'LEV' }]
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TranslocoModule } from '@ngneat/transloco';
import { Canon } from '@sillsdev/scripture';
import { TranslocoMarkupModule } from 'ngx-transloco-markup';
import { TrainingData } from 'realtime-server/lib/esm/scriptureforge/models/training-data';
import { ProjectScriptureRange } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
import { Subscription, merge } from 'rxjs';
import { filter, tap } from 'rxjs/operators';
import { ActivatedProjectService } from 'xforge-common/activated-project.service';
Expand All @@ -19,7 +20,6 @@ import { SharedModule } from '../../../shared/shared.module';
import { booksFromScriptureRange, projectLabel } from '../../../shared/utils';
import { NllbLanguageService } from '../../nllb-language.service';
import { ConfirmSourcesComponent } from '../confirm-sources/confirm-sources.component';
import { ProjectScriptureRange } from '../draft-generation';
import { DraftSource, DraftSourceIds, DraftSourcesService } from '../draft-sources.service';
import { TrainingDataMultiSelectComponent } from '../training-data/training-data-multi-select.component';
import { TrainingDataUploadDialogComponent } from '../training-data/training-data-upload-dialog.component';
Expand All @@ -30,7 +30,7 @@ export interface DraftGenerationStepsResult {
trainingScriptureRange?: string;
trainingScriptureRanges: ProjectScriptureRange[];
translationScriptureRange?: string;
translationScriptureRanges: ProjectScriptureRange[];
translationScriptureRanges?: ProjectScriptureRange[];
fastTraining: boolean;
}

Expand Down Expand Up @@ -322,14 +322,10 @@ export class DraftGenerationStepsComponent extends SubscriptionDisposable implem
)
);
}
const translationScriptureRange: ProjectScriptureRange = this.convertToScriptureRange(
this.draftSourceProjectIds!.draftingSourceId,
this.userSelectedTranslateBooks
);
this.done.emit({
trainingScriptureRanges,
trainingDataFiles: this.selectedTrainingDataIds,
translationScriptureRanges: [translationScriptureRange],
translationScriptureRange: this.userSelectedTranslateBooks.map(b => Canon.bookNumberToId(b)).join(';'),
fastTraining: this.fastTraining
});
}
Expand Down Expand Up @@ -397,8 +393,18 @@ export class DraftGenerationStepsComponent extends SubscriptionDisposable implem

private setInitialTrainingBooks(availableBooks: number[]): void {
// Get the previously selected training books from the target project
const previousTrainingRange: string =
this.activatedProject.projectDoc?.data?.translateConfig.draftConfig.lastSelectedTrainingScriptureRange ?? '';
const trainingSourceId =
this.draftSourceProjectIds?.trainingAlternateSourceId ?? this.draftSourceProjectIds?.trainingSourceId;
let previousTrainingRange: string =
this.activatedProject.projectDoc?.data?.translateConfig.draftConfig.lastSelectedTrainingScriptureRanges?.find(
r => r.projectId === trainingSourceId
)?.scriptureRange ?? '';
const trainingScriptureRange =
this.activatedProject.projectDoc?.data?.translateConfig.draftConfig.lastSelectedTrainingScriptureRange;
if (previousTrainingRange === '' && trainingScriptureRange != null) {
previousTrainingRange =
this.activatedProject.projectDoc?.data?.translateConfig.draftConfig.lastSelectedTrainingScriptureRange ?? '';
}
const previousBooks: Set<number> = new Set<number>(booksFromScriptureRange(previousTrainingRange));

// The intersection is all of the available books in the source project that match the target's previous books
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ describe('DraftGenerationComponent', () => {
},
draftConfig: {
lastSelectedTrainingBooks: preTranslate ? [1] : [],
lastSelectedTranslationBooks: preTranslate ? [2] : []
lastSelectedTranslationBooks: preTranslate ? [2] : [],
lastSelectedTrainingScriptureRange: preTranslate ? 'GEN' : undefined,
lastSelectedTranslationScriptureRange: preTranslate ? 'EXO' : undefined
}
},
texts: [
Expand Down Expand Up @@ -2359,7 +2361,7 @@ describe('DraftGenerationComponent', () => {

// Update the has draft flag for the project
projectDoc.data!.texts[0].chapters[0].hasDraft = true;
projectDoc.data!.translateConfig.draftConfig.lastSelectedTranslationBooks = [1];
projectDoc.data!.translateConfig.draftConfig.lastSelectedTranslationScriptureRange = 'GEN';
projectSubject.next(projectDoc);
buildSubject.next({ ...buildDto, state: BuildStates.Completed });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ export class DraftGenerationComponent extends DataLoadingComponent implements On
trainingScriptureRange: result.trainingScriptureRange,
trainingScriptureRanges: result.trainingScriptureRanges,
translationScriptureRange: result.translationScriptureRange,
translationScriptureRanges: result.trainingScriptureRanges,
translationScriptureRanges: result.translationScriptureRanges,
fastTraining: result.fastTraining
});
}
Expand Down Expand Up @@ -568,7 +568,7 @@ export class DraftGenerationComponent extends DataLoadingComponent implements On
private hasStartedBuild(projectDoc: SFProjectProfileDoc): boolean {
return (
projectDoc.data?.translateConfig.preTranslate === true &&
projectDoc.data?.translateConfig.draftConfig.lastSelectedTranslationBooks.length > 0
projectDoc.data?.translateConfig.draftConfig.lastSelectedTranslationScriptureRange != null
);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InjectionToken } from '@angular/core';
import { ProjectScriptureRange } from 'realtime-server/lib/esm/scriptureforge/models/translate-config';
import { BuildStates } from '../../machine-api/build-states';

/**
Expand All @@ -14,14 +15,6 @@ export interface BuildConfig {
fastTraining: boolean;
}

/**
* A per-project scripture range.
*/
export interface ProjectScriptureRange {
projectId: string;
scriptureRange: string;
}

/**
* Dictionary of 'segmentRef -> segment text'.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class TestEnvironment {
],
translateConfig: {
preTranslate: true,
draftConfig: { lastSelectedTranslationBooks: [40], lastSelectedTrainingBooks: [41] }
draftConfig: { lastSelectedTranslationScriptureRange: 'MAT', lastSelectedTrainingScriptureRange: 'MRK' }
},
userRoles: TestEnvironment.rolesByUser,
biblicalTermsConfig: { biblicalTermsEnabled: true }
Expand Down

0 comments on commit 8a007bb

Please sign in to comment.