@ -22,7 +22,13 @@ import {
EntityTableConfig
} from '@home/models/entity/entities-table-config.models' ;
import { Router } from '@angular/router' ;
import { Resource , ResourceInfo , ResourceType , ResourceTypeTranslationMap } from '@shared/models/resource.models' ;
import {
Resource ,
ResourceInfo , ResourceInfoWithReferences ,
ResourceType ,
ResourceTypeTranslationMap ,
toResourceDeleteResult
} from '@shared/models/resource.models' ;
import { EntityType , entityTypeResources , entityTypeTranslations } from '@shared/models/entity-type.models' ;
import { NULL_UUID } from '@shared/models/id/has-uuid' ;
import { DatePipe } from '@angular/common' ;
@ -35,9 +41,19 @@ import { Authority } from '@shared/models/authority.enum';
import { ResourcesLibraryComponent } from '@home/components/resources/resources-library.component' ;
import { PageLink } from '@shared/models/page/page-link' ;
import { EntityAction } from '@home/models/entity/entity-component.models' ;
import { map } from 'rxjs/operators' ;
import { catchError , map } from 'rxjs/operators' ;
import { ResourcesTableHeaderComponent } from '@home/pages/admin/resource/resources-table-header.component' ;
import { ResourceLibraryTabsComponent } from '@home/pages/admin/resource/resource-library-tabs.component' ;
import { forkJoin , of } from "rxjs" ;
import {
ResourcesInUseDialogComponent ,
ResourcesInUseDialogData
} from "@shared/components/resource/resources-in-use-dialog.component" ;
import { parseHttpErrorMessage } from "@core/utils" ;
import { ActionNotificationShow } from "@core/notification/notification.actions" ;
import { ResourcesDatasource } from "@home/pages/admin/resource/resources-datasource" ;
import { MatDialog } from "@angular/material/dialog" ;
import { DialogService } from "@core/services/dialog.service" ;
@Injectable ( )
export class ResourcesLibraryTableConfigResolver {
@ -49,6 +65,8 @@ export class ResourcesLibraryTableConfigResolver {
private resourceService : ResourceService ,
private translate : TranslateService ,
private router : Router ,
private dialog : MatDialog ,
private dialogService : DialogService ,
private datePipe : DatePipe ) {
this . config . entityType = EntityType . TB_RESOURCE ;
@ -76,19 +94,27 @@ export class ResourcesLibraryTableConfigResolver {
icon : 'file_download' ,
isEnabled : ( ) = > true ,
onAction : ( $event , entity ) = > this . downloadResource ( $event , entity )
}
} ,
{
name : this.translate.instant ( 'resource.delete' ) ,
icon : 'delete' ,
isEnabled : ( resource ) = > this . config . deleteEnabled ( resource ) ,
onAction : ( $event , entity ) = > this . deleteResource ( $event , entity )
} ,
) ;
this . config . deleteEntityTitle = resource = > this . translate . instant ( 'resource.delete-resource-title' ,
{ resourceTitle : resource.title } ) ;
this . config . deleteEntityContent = ( ) = > this . translate . instant ( 'resource.delete-resource-text' ) ;
this . config . deleteEntitiesTitle = count = > this . translate . instant ( 'resource.delete-resources-title' , { count } ) ;
this . config . deleteEntitiesContent = ( ) = > this . translate . instant ( 'resource.delete-resources-text' ) ;
this . config . groupActionDescriptors = [ {
name : this.translate.instant ( 'action.delete' ) ,
icon : 'delete' ,
isEnabled : true ,
onAction : ( $event , entities ) = > this . deleteResources ( $event , entities )
} ] ;
this . config . entitiesDeleteEnabled = false ;
this . config . entitiesFetchFunction = pageLink = > this . resourceService . getResources ( pageLink , this . config . componentsData . resourceType ) ;
this . config . loadEntity = id = > this . resourceService . getResourceInfoById ( id . id ) ;
this . config . saveEntity = resource = > this . saveResource ( resource ) ;
this . config . deleteEntity = id = > this . resourceService . deleteResource ( id . id ) ;
this . config . onEntityAction = action = > this . onResourceAction ( action ) ;
}
@ -147,6 +173,8 @@ export class ResourcesLibraryTableConfigResolver {
case 'downloadResource' :
this . downloadResource ( action . event , action . entity ) ;
return true ;
case 'deleteLibrary' :
this . deleteResource ( action . event , action . entity ) ;
}
return false ;
}
@ -165,4 +193,138 @@ export class ResourcesLibraryTableConfigResolver {
return authority === Authority . SYS_ADMIN ;
}
}
private deleteResource ( $event : Event , resource : ResourceInfo ) {
if ( $event ) {
$event . stopPropagation ( ) ;
}
this . dialogService . confirm (
this . translate . instant ( 'resource.delete-resource-title' , { resourceTitle : resource.title } ) ,
this . translate . instant ( 'resource.delete-resource-text' ) ,
this . translate . instant ( 'action.no' ) ,
this . translate . instant ( 'action.yes' ) ,
true
) . subscribe ( ( result ) = > {
if ( result ) {
this . resourceService . deleteResource ( resource . id . id , false , { ignoreErrors : true } ) . pipe (
map ( ( ) = > toResourceDeleteResult ( resource ) ) ,
catchError ( ( err ) = > of ( toResourceDeleteResult ( resource , err ) ) )
) . subscribe (
( deleteResult ) = > {
if ( deleteResult . success ) {
if ( this . config . getEntityDetailsPage ( ) ) {
this . config . getEntityDetailsPage ( ) . goBack ( ) ;
} else {
this . config . updateData ( true ) ;
}
} else if ( deleteResult . resourceIsReferencedError ) {
const resources : ResourceInfoWithReferences [ ] = [ { . . . resource , . . . { references : deleteResult.references } } ] ;
const data = {
multiple : false ,
resources ,
configuration : {
title : 'resource.resource-is-in-use' ,
message : this.translate.instant ( 'resource.resource-is-in-use-text' , { title : resources [ 0 ] . title } ) ,
deleteText : 'resource.delete-resource-in-use-text' ,
selectedText : 'resource.selected-resources' ,
columns : [ 'select' , 'title' , 'references' ]
}
} ;
this . dialog . open < ResourcesInUseDialogComponent , ResourcesInUseDialogData ,
ResourceInfo [ ] > ( ResourcesInUseDialogComponent , {
disableClose : true ,
panelClass : [ 'tb-dialog' , 'tb-fullscreen-dialog' ] ,
data
} ) . afterClosed ( ) . subscribe ( ( resources ) = > {
if ( resources ) {
this . resourceService . deleteResource ( resource . id . id , true ) . subscribe ( ( ) = > {
if ( this . config . getEntityDetailsPage ( ) ) {
this . config . getEntityDetailsPage ( ) . goBack ( ) ;
} else {
this . config . updateData ( true ) ;
}
} ) ;
}
} ) ;
} else {
const errorMessageWithTimeout = parseHttpErrorMessage ( deleteResult . error , this . translate ) ;
setTimeout ( ( ) = > {
this . store . dispatch ( new ActionNotificationShow ( { message : errorMessageWithTimeout.message , type : 'error' } ) ) ;
} , errorMessageWithTimeout . timeout ) ;
}
}
) ;
}
} ) ;
}
private deleteResources ( $event : Event , resources : ResourceInfo [ ] ) {
if ( $event ) {
$event . stopPropagation ( ) ;
}
if ( resources && resources . length ) {
const title = this . translate . instant ( 'resource.delete-resources-title' , { count : resources.length } ) ;
const content = this . translate . instant ( 'resource.delete-resources-text' ) ;
this . dialogService . confirm ( title , content ,
this . translate . instant ( 'action.no' ) ,
this . translate . instant ( 'action.yes' ) ) . subscribe ( ( result ) = > {
if ( result ) {
const tasks = resources . map ( ( resource ) = >
this . resourceService . deleteResource ( resource . id . id , false , { ignoreErrors : true } ) . pipe (
map ( ( ) = > toResourceDeleteResult ( resource ) ) ,
catchError ( ( err ) = > of ( toResourceDeleteResult ( resource , err ) ) )
)
) ;
forkJoin ( tasks ) . subscribe (
( deleteResults ) = > {
const anySuccess = deleteResults . some ( res = > res . success ) ;
const referenceErrors = deleteResults . filter ( res = > res . resourceIsReferencedError ) ;
const otherError = deleteResults . find ( res = > ! res . success ) ;
if ( anySuccess ) {
this . config . updateData ( ) ;
}
if ( referenceErrors ? . length ) {
const resourcesWithReferences : ResourceInfoWithReferences [ ] =
referenceErrors . map ( ref = > ( { . . . ref . resource , . . . { references : ref.references } } ) ) ;
const data = {
multiple : true ,
resources : resourcesWithReferences ,
configuration : {
title : 'resource.resources-are-in-use' ,
message : this.translate.instant ( 'resource.resources-are-in-use-text' ) ,
deleteText : 'resource.delete-resource-in-use-text' ,
selectedText : 'resource.selected-resources' ,
datasource : new ResourcesDatasource ( this . resourceService , resourcesWithReferences , ( ) = > true ) ,
columns : [ 'select' , 'title' , 'references' ]
}
} ;
this . dialog . open < ResourcesInUseDialogComponent , ResourcesInUseDialogData ,
ResourceInfo [ ] > ( ResourcesInUseDialogComponent , {
disableClose : true ,
panelClass : [ 'tb-dialog' , 'tb-fullscreen-dialog' ] ,
data
} ) . afterClosed ( ) . subscribe ( ( forceDeleteResources ) = > {
if ( forceDeleteResources && forceDeleteResources . length ) {
const forceDeleteTasks = forceDeleteResources . map ( ( resource ) = >
this . resourceService . deleteResource ( resource . id . id , true )
) ;
forkJoin ( forceDeleteTasks ) . subscribe (
( ) = > {
this . config . updateData ( ) ;
}
) ;
}
} ) ;
} else if ( otherError ) {
const errorMessageWithTimeout = parseHttpErrorMessage ( otherError . error , this . translate ) ;
setTimeout ( ( ) = > {
this . store . dispatch ( new ActionNotificationShow ( { message : errorMessageWithTimeout.message , type : 'error' } ) ) ;
} , errorMessageWithTimeout . timeout ) ;
}
}
) ;
}
} ) ;
}
}
}