UNPKG

angular-t9n

Version:

A translation tool for Angular i18n

101 lines (91 loc) 2.99 kB
import { Injectable } from '@angular/core'; import { switchMap } from 'rxjs/operators'; import { TranslationTargetUnitResponse } from '../../../models'; import { ImportResult } from './import-result'; import { TranslationTargetService } from './translation-target.service'; @Injectable() export class ImportService { constructor(private _translationTargetService: TranslationTargetService) {} async import(files: FileList, state: 'translated' | 'reviewed' | 'final') { const { read, utils } = await import('xlsx'); const result = new ImportResult(); const unitRows = await Promise.all( Array.from(files).map(async (f) => { try { const binary = await this._readFileAsBinary(f); const workbook = read(binary, { type: 'binary' }); const sheet = workbook.Sheets[workbook.SheetNames[0]]; const rows = utils .sheet_to_json<string[]>(sheet, { header: 1 }) .slice(1) .map((row) => this._toPartialTargetUnit(row)) .filter((u) => u.id && u.target); if (!rows.length) { throw new Error(`${f.name} contains no valid units`); } return rows; } catch (e) { console.log(e); result.failedFiles.push(f.name); return [] as Partial<TranslationTargetUnitResponse>[]; } }), ); await Promise.all( unitRows .reduce((current, next) => current.concat(next), []) .map(async (u) => { try { const response = (await this._importUnit(u, state).toPromise())!; result.importedUnits.push(response); } catch { result.failedUnits.push(u); } }), ); return result.sort(); } private _readFileAsBinary(file: File) { return new Promise<any>((resolve, reject) => { const reader = new FileReader(); reader.onload = (event: ProgressEvent<FileReader>) => { const bytes = new Uint8Array(event.target!.result as ArrayBuffer); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } resolve(binary); }; reader.onerror = (event: ProgressEvent<FileReader>) => reject(event.target!.error); reader.onabort = () => reject(); reader.readAsArrayBuffer(file); }); } private _toPartialTargetUnit([ id, description, meaning, source, target, ]: string[]): Partial<TranslationTargetUnitResponse> { return { id, description, meaning, source, target, }; } private _importUnit( unit: Partial<TranslationTargetUnitResponse>, state: 'translated' | 'reviewed' | 'final', ) { return this._translationTargetService .unit(unit.id!) .pipe( switchMap((u) => this._translationTargetService.updateUnit({ ...u, target: unit.target!, state }), ), ); } }