import { Injectable } from "@angular/core" ; import { Database } from "../../core/database/database" ; import { Papa } from "ngx-papaparse" ; import { UntilDestroy , untilDestroyed } from "@ngneat/until-destroy" ; import { BackupService } from "../../core/admin/services/backup.service" ; import { ConfirmationDialogService } from "../../core/confirmation-dialog/confirmation-dialog.service" ; import { MatSnackBar } from "@angular/material/snack-bar" ; import { readFile } from "../../utils/utils" ; import { DynamicEntityService } from "../../core/entity/dynamic-entity.service" ; @ Injectable ( ) @ UntilDestroy ( ) export class DataImportService { constructor ( private db , private papa , private backupService , private confirmationDialog , private snackBar , private dynamicEntityService ) { } async importCsvContentToDB ( csv ) { const parsedCsv = this . papa . parse ( csv , { header : true , dynamicTyping : true , skipEmptyLines : true , } ) ; for ( const record of parsedCsv . data ) { for ( const propertyName in record ) { if ( record [ propertyName ] === null || propertyName === "_rev" ) { delete record [ propertyName ] ; } } if ( record [ "_id" ] !== undefined ) { const entityType = record [ "_id" ] . split ( ":" ) [ 0 ] ; const ctor = this . dynamicEntityService . getEntityConstructor ( entityType ) ; record [ "searchIndices" ] = Object . assign ( new ctor ( ) , record ) . searchIndices ; } await this . db . put ( record , true ) ; } } param file async handleCsvImport ( file ) { const restorePoint = await this . backupService . getJsonExport ( ) ; const newData = await readFile ( file ) ; const dialogRef = this . confirmationDialog . openDialog ( $localize `Import new data?` , $localize `Are you sure you want to import this file? This will add or update ${ newData . trim ( ) . split ( "\n" ) . length - 1 } records from the loaded file. Existing records with same "_id" in the database will be overwritten!` ) ; dialogRef . afterClosed ( ) . subscribe ( async ( confirmed ) => { if ( ! confirmed ) { return ; } await this . importCsvContentToDB ( newData ) ; const snackBarRef = this . snackBar . open ( $localize `Import completed?` , "Undo" , { duration : 8000 , } ) ; snackBarRef . onAction ( ) . pipe ( untilDestroyed ( this ) ) . subscribe ( async ( ) => { await this . backupService . clearDatabase ( ) ; await this . backupService . importJson ( restorePoint , true ) ; } ) ; } ) ; } }