import { FileUploadEvent , ShowHeaderMode , UploadService } from '@alfresco/adf-core' ; import { Component , OnDestroy , OnInit } from '@angular/core' ; import { ActivatedRoute , Params , Router } from '@angular/router' ; import { Store } from '@ngrx/store' ; import { MinimalNodeEntity , MinimalNodeEntryEntity , PathElement , PathElementEntity } from '@alfresco/js-api' ; import { ContentManagementService } from '../../services/content-management.service' ; import { NodeActionsService } from '../../services/node-actions.service' ; import { PageComponent } from '../page.component' ; import { AppExtensionService , ContentApiService } from '@alfresco/aca-shared' ; import { SetCurrentFolderAction , isAdmin , AppStore , UploadFileVersionAction } from '@alfresco/aca-shared/store' ; import { BreakpointObserver , Breakpoints } from '@angular/cdk/layout' ; import { debounceTime , takeUntil } from 'rxjs/operators' ; import { FilterSearch , ShareDataRow } from '@alfresco/adf-content-services' ; import { DocumentListPresetRef } from '@alfresco/adf-extensions' ; @ Component ( { templateUrl : './files.component.html' } ) export class FilesComponent extends PageComponent implements OnInit , OnDestroy { isValidPath = true ; isSmallScreen = false ; isAdmin = false ; selectedNode : MinimalNodeEntity ; queryParams = null ; private nodePath : PathElement [ ] ; columns : DocumentListPresetRef [ ] = [ ] ; constructor ( private router , private route , private contentApi , store , private nodeActionsService , private uploadService , content , extensions , private breakpointObserver ) { super ( store , extensions , content ) ; } ngOnInit ( ) { super . ngOnInit ( ) ; const { route , nodeActionsService , uploadService } = this ; const { data } = route . snapshot ; this . title = data . title ; route . queryParamMap . subscribe ( ( queryMap ) => { this . queryParams = queryMap . params ; } ) ; route . params . subscribe ( ( { folderId } ) => { const nodeId = folderId || data . defaultNodeId ; this . contentApi . getNode ( nodeId ) . subscribe ( ( node ) => { this . isValidPath = true ; if ( node . entry && node . entry . isFolder ) { this . updateCurrentNode ( node . entry ) ; } else { this . router . navigate ( [ '/personal-files' , node . entry . parentId ] , { replaceUrl : true } ) ; } } , ( ) => ( this . isValidPath = false ) ) ; } ) ; this . subscriptions = this . subscriptions . concat ( [ nodeActionsService . contentCopied . subscribe ( ( nodes ) => this . onContentCopied ( nodes ) ) , uploadService . fileUploadComplete . pipe ( debounceTime ( 300 ) ) . subscribe ( ( file ) => this . onFileUploadedEvent ( file ) ) , uploadService . fileUploadDeleted . pipe ( debounceTime ( 300 ) ) . subscribe ( ( file ) => this . onFileUploadedEvent ( file ) ) , this . breakpointObserver . observe ( [ Breakpoints . HandsetPortrait , Breakpoints . HandsetLandscape ] ) . subscribe ( ( result ) => { this . isSmallScreen = result . matches ; } ) ] ) ; this . store . select ( isAdmin ) . pipe ( takeUntil ( this . onDestroy$ ) ) . subscribe ( ( value ) => { this . isAdmin = value ; } ) ; this . columns = this . extensions . documentListPresets . files || [ ] ; } ngOnDestroy ( ) { this . store . dispatch ( new SetCurrentFolderAction ( null ) ) ; super . ngOnDestroy ( ) ; } navigate ( nodeId = null ) { const currentNodeId = this . route . snapshot . paramMap . get ( 'folderId' ) ; const urlWithoutParams = decodeURIComponent ( this . router . url ) . split ( '?' ) [ 0 ] ; const urlToNavigate = this . getUrlToNavigate ( urlWithoutParams , currentNodeId , nodeId ) ; this . router . navigate ( urlToNavigate ) ; } private getUrlToNavigate ( currentURL , currentNodeId , nextNodeId ) { return currentNodeId ? this . getNextNodeUrlToNavigate ( currentURL , currentNodeId , nextNodeId ) : this . appendNextNodeIdToUrl ( currentURL , nextNodeId ) ; } private getNextNodeUrlToNavigate ( currentURL , currentNodeId , nextNodeId ) { const urlToNavigate = nextNodeId && ! this . isRootNode ( nextNodeId ) ? this . replaceCurrentNodeIdWithNextNodeId ( currentURL , currentNodeId , nextNodeId ) : this . removeNodeIdFromUrl ( currentURL , currentNodeId ) ; urlToNavigate . shift ( ) ; return urlToNavigate ; } private replaceCurrentNodeIdWithNextNodeId ( currentURL , currentNodeId , nextNodeId ) { const nextNodeUrlToNavigate = currentURL . split ( '/' ) ; const index = nextNodeUrlToNavigate . indexOf ( currentNodeId ) ; if ( index > 0 ) { nextNodeUrlToNavigate [ index ] = nextNodeId ; } return nextNodeUrlToNavigate ; } private removeNodeIdFromUrl ( currentURL , currentNodeId ) { const rootUrl = currentURL . replace ( currentNodeId , '' ) . split ( '/' ) ; rootUrl . pop ( ) ; return rootUrl ; } private appendNextNodeIdToUrl ( currentURL , nodeId ) { const navigateToNodeUrl = currentURL . split ( '/' ) ; if ( nodeId && ! this . isRootNode ( nodeId ) ) { navigateToNodeUrl . push ( nodeId ) ; } navigateToNodeUrl . shift ( ) ; return navigateToNodeUrl ; } onUploadNewVersion ( ev ) { this . store . dispatch ( new UploadFileVersionAction ( ev ) ) ; } navigateTo ( node ) { if ( node && node . entry ) { this . selectedNode = node ; const { isFolder } = node . entry ; if ( isFolder ) { let id ; if ( node . entry . nodeType === 'app:folderlink' ) { id = node . entry . properties [ 'cm:destination' ] ; } else { id = node . entry . id ; } this . documentList . resetNewFolderPagination ( ) ; this . navigate ( id ) ; return ; } this . showPreview ( node , { location : this . router . url } ) ; } } handleNodeClick ( event ) { this . navigateTo ( ( event as CustomEvent ) . detail ?. node ) ; } onBreadcrumbNavigate ( route ) { this . documentList . resetNewFolderPagination ( ) ; if ( this . nodePath && this . nodePath . length > 2 ) { if ( this . nodePath [ 1 ] . name === 'Sites' && this . nodePath [ 2 ] . id === route . id ) { return this . navigate ( this . nodePath [ 3 ] . id ) ; } } this . navigate ( route . id ) ; } onFileUploadedEvent ( event ) { const node = event . file . data ; if ( node && node . entry && node . entry . parentId === this . getParentNodeId ( ) ) { this . reload ( this . selectedNode ) ; return ; } if ( event && event . file . options . parentId === this . getParentNodeId ( ) ) { this . displayFolderParent ( event . file . options . path , 0 ) ; return ; } if ( event && event . file . options . parentId ) { if ( this . nodePath ) { const correspondingNodePath = this . nodePath . find ( ( pathItem ) => pathItem . id === event . file . options . parentId ) ; if ( correspondingNodePath ) { const correspondingIndex = this . nodePath . length - this . nodePath . indexOf ( correspondingNodePath ) ; this . displayFolderParent ( event . file . options . path , correspondingIndex ) ; } } } } displayFolderParent ( filePath = '' , index ) { const parentName = filePath . split ( '/' ) [ index ] ; const currentFoldersDisplayed = ( this . documentList . data . getRows ( ) as ShareDataRow [ ] ) || [ ] ; const alreadyDisplayedParentFolder = currentFoldersDisplayed . find ( ( row ) => row . node . entry . isFolder && row . node . entry . name === parentName ) ; if ( alreadyDisplayedParentFolder ) { return ; } this . reload ( this . selectedNode ) ; } onContentCopied ( nodes ) { const newNode = nodes . find ( ( node ) => { return node && node . entry && node . entry . parentId === this . getParentNodeId ( ) ; } ) ; if ( newNode ) { this . reload ( this . selectedNode ) ; } } private async updateCurrentNode ( node ) { this . nodePath = null ; if ( node && node . path && node . path . elements ) { const elements = node . path . elements ; this . nodePath = elements . map ( ( pathElement ) => { return Object . assign ( { } , pathElement ) ; } ) ; if ( elements . length > 1 ) { if ( elements [ 1 ] . name === 'User Homes' ) { if ( ! this . isAdmin ) { elements . splice ( 0 , 2 ) ; } } else if ( elements [ 1 ] . name === 'Sites' ) { await this . normalizeSitePath ( node ) ; } } } this . node = node ; this . store . dispatch ( new SetCurrentFolderAction ( node ) ) ; } private async normalizeSitePath ( node ) { const elements = node . path . elements ; elements . splice ( 1 , 1 ) ; if ( this . isSiteContainer ( node ) ) { const parentNode = await this . contentApi . getNodeInfo ( node . parentId ) . toPromise ( ) ; node . name = parentNode . properties [ 'cm:title' ] || parentNode . name ; elements . splice ( 1 , 1 ) ; } else { const docLib = elements . findIndex ( ( el ) => el . name === 'documentLibrary' ) ; if ( docLib > - 1 ) { const siteFragment = elements [ docLib - 1 ] ; const siteNode = await this . contentApi . getNodeInfo ( siteFragment . id ) . toPromise ( ) ; siteFragment . name = siteNode . properties [ 'cm:title' ] || siteNode . name ; elements . splice ( docLib , 1 ) ; } } } isSiteContainer ( node ) { if ( node && node . aspectNames && node . aspectNames . length > 0 ) { return node . aspectNames . indexOf ( 'st:siteContainer' ) >= 0 ; } return false ; } isRootNode ( nodeId ) { if ( this . node && this . node . path && this . node . path . elements && this . node . path . elements . length > 0 ) { return this . node . path . elements [ 0 ] . id === nodeId ; } return false ; } onFilterSelected ( activeFilters ) { if ( activeFilters . length ) { this . showHeader = ShowHeaderMode . Always ; this . navigateToFilter ( activeFilters ) ; } else { this . router . navigate ( [ '.' ] , { relativeTo : this . route } ) ; this . showHeader = ShowHeaderMode . Data ; this . onAllFilterCleared ( ) ; } } navigateToFilter ( activeFilters ) { const objectFromMap = { } ; activeFilters . forEach ( ( filter ) => { let paramValue ; if ( filter . value && filter . value . from && filter . value . to ) { paramValue = `${ filter . value . from }||${ filter . value . to }` ; } else { paramValue = filter . value ; } objectFromMap [ filter . key ] = paramValue ; } ) ; this . router . navigate ( [ ] , { relativeTo : this . route , queryParams : objectFromMap } ) ; } isFilterHeaderActive ( ) { return this . showHeader === ShowHeaderMode . Always ; } onError ( ) { this . isValidPath = false ; } }