import * as React from 'react' ; import styles from './FolderExplorer.module.scss' ; import * as strings from 'PropertyControlStrings' ; import { Icon } from "office-ui-fabric-react/lib/Icon" ; import { IFolderExplorerProps , IFolderExplorerState } from '.' ; import { FolderExplorerService } from '../../../../services/FolderExplorerService' ; import { IFolder , IFolderExplorerService } from '../../../../services/IFolderExplorerService' ; import { NewFolder } from "../NewFolder" ; import { Breadcrumb , IBreadcrumbItem } from "office-ui-fabric-react/lib/Breadcrumb" ; import { SearchBox } from 'office-ui-fabric-react/lib/SearchBox' ; export class FolderExplorer extends React . Component < IFolderExplorerProps , IFolderExplorerState > { private _spService : IFolderExplorerService ; private _allLibraries : IFolder [ ] = [ ] ; private _allFolders : IFolder [ ] = [ ] ; constructor ( props ) { super ( props ) ; this . _spService = new FolderExplorerService ( this . props . context . serviceScope ) ; this . state = { foldersLoading : false , folders : [ ] , selectedFolder : null , } ; } public async componentDidMount ( ) { const targetFolder = this . props . defaultFolder ? this . props . defaultFolder : this . props . rootFolder ; const siteAbsoluteUrl = this . props . siteAbsoluteUrl || this . props . context . pageContext . web . absoluteUrl ; if ( siteAbsoluteUrl . lastIndexOf ( targetFolder . ServerRelativeUrl , siteAbsoluteUrl . length - targetFolder . ServerRelativeUrl . length ) === - 1 ) { this . _allLibraries = await this . _spService . GetDocumentLibraries ( siteAbsoluteUrl ) ; } await this . _getFolders ( targetFolder ) ; } public render ( ) { const siteAbsoluteUrl = this . props . siteAbsoluteUrl || this . props . context . pageContext . web . absoluteUrl ; return ( < div > { ! this . props . hiddenBreadcrumb && this . _getBreadcrumbDOM ( ) } < div style = { { opacity : this . state . foldersLoading ? 0.8 : 1 , } } > { ! this . props . hiddenFilterBox && this . _allFolders . length > 0 && < div > < SearchBox className = { styles . filterBox } placeholder = { strings . FolderFilterBoxPlaceholder } onSearch = { this . _onChangeFilterText } onChange = { ( e , value ) => this . _onChangeFilterText ( value ) } /> < /div>} { this . state . folders . length === 0 && < div className = { styles . status } > < span role = "status" > { this . state . foldersLoading ? strings . FolderExplorerLoading : strings . FolderExplorerNoItems } < /span> < /div>} { this . state . folders . length > 0 && < div > { this . state . folders . map ( ( folder ) => { return ( < div className = { styles . libraryItem } onClick = { ( ) => { this . _getFolders ( folder ) ; } } > < Icon iconName = "FabricFolder" className = { styles . folderIcon } / > { folder . Name } < /div>); } ) } < /div>} { this . props . canCreateFolders && ( this . state . selectedFolder && this . state . selectedFolder . ServerRelativeUrl !== this . props . context . pageContext . web . serverRelativeUrl ) && < NewFolder context = { this . props . context } siteAbsoluteUrl = { siteAbsoluteUrl } selectedFolder = { this . state . selectedFolder } addSubFolder = { this . _addSubFolder } > < /NewFolder>} < /div> < /div>); } private _getBreadcrumbDOM = ( ) : JSX . Element => { let breadCrumbDOM = null ; let breadCrumbItems = this . _getCurrentBreadcrumbItems ( ) ; let overflowIndex = breadCrumbItems . length > 1 ? 1 : 0 ; breadCrumbDOM = < Breadcrumb items = { breadCrumbItems } className = { styles . breadcrumbPath } maxDisplayedItems = { 3 } overflowIndex = { overflowIndex } / > ; return breadCrumbDOM ; } ; private _getCurrentBreadcrumbItems = ( ) : IBreadcrumbItem [ ] => { let items = [ ] ; if ( this . props . initialBreadcrumbItems ) { items = [ ... this . props . initialBreadcrumbItems ] ; } let rootItem = { text : this . props . rootFolder . Name , key : 'Root-Item' , onClick : this . _getFolders . bind ( this , this . props . rootFolder ) } ; items . push ( rootItem ) ; if ( this . state . selectedFolder && this . state . selectedFolder . ServerRelativeUrl !== this . props . rootFolder . ServerRelativeUrl ) { const folderPathSplit = this . state . selectedFolder . ServerRelativeUrl . replace ( this . props . rootFolder . ServerRelativeUrl , '' ) . split ( '/' ) ; let folderPath = this . props . rootFolder . ServerRelativeUrl ; folderPathSplit . forEach ( ( folderName , index ) => { if ( folderName !== '' ) { folderPath += '/' + folderName ; let itemText = folderName ; const lib = this . _allLibraries . filter ( l => l . ServerRelativeUrl === folderPath ) ; if ( lib . length === 1 ) { itemText = lib [ 0 ] . Name ; } let folderItem = { text : itemText , key : `Folder-${ index . toString ( ) }` , onClick : this . _getFolders . bind ( this , { Name : folderName , ServerRelativeUrl : folderPath } ) } ; items . push ( folderItem ) ; } } ) ; } items [ items . length - 1 ] . isCurrentItem = true ; return items ; } ; private _onChangeFilterText = ( filterText ) : void => { this . setState ( { folders : filterText ? this . _allFolders . filter ( f => f . Name . toLowerCase ( ) . indexOf ( filterText . toLowerCase ( ) ) > - 1 ) : this . _allFolders } ) ; } ; private _getFolders = async ( folder ) : Promise < void > => { this . setState ( { foldersLoading : true } ) ; try { const siteAbsoluteUrl = this . props . siteAbsoluteUrl || this . props . context . pageContext . web . absoluteUrl ; if ( siteAbsoluteUrl . lastIndexOf ( folder . ServerRelativeUrl , siteAbsoluteUrl . length - folder . ServerRelativeUrl . length ) !== - 1 ) { if ( this . _allLibraries . length > 0 ) { this . _allFolders = [ ... this . _allLibraries ] ; } else { this . _allLibraries = await this . _spService . GetDocumentLibraries ( siteAbsoluteUrl ) ; this . _allFolders = [ ... this . _allLibraries ] ; } } else { this . _allFolders = await this . _spService . GetFolders ( siteAbsoluteUrl , folder . ServerRelativeUrl ) ; } this . setState ( { folders : this . _allFolders , selectedFolder : folder , foldersLoading : false } ) ; this . props . onSelect ( folder ) ; } catch ( error ) { this . setState ( { selectedFolder : null , foldersLoading : false } ) ; console . error ( error ) ; } } ; private _addSubFolder = async ( newFolder ) : Promise < void > => { if ( newFolder ) { if ( ! this . _allFolders . some ( f => f . Name === newFolder . Name ) ) { this . _allFolders . push ( newFolder ) ; this . setState ( { folders : this . _allFolders } ) ; } } } ; }