import * as React from 'react' ; import { Dropdown , IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown' ; import { Async } from 'office-ui-fabric-react/lib/Utilities' ; import { Label } from 'office-ui-fabric-react/lib/Label' ; import { IPropertyFieldListPickerHostProps , IPropertyFieldListPickerHostState , ISPList , ISPLists } from './IPropertyFieldListPickerHost' ; import SPListPickerService from '../../services/SPListPickerService' ; import FieldErrorMessage from '../errorMessage/FieldErrorMessage' ; import * as telemetry from '../../common/telemetry' ; import { IPropertyFieldList } from './IPropertyFieldListPicker' ; import { setPropertyValue } from '../../helpers/GeneralHelper' ; const EMPTY_LIST_KEY = 'NO_LIST_SELECTED' ; /**
 * Renders the controls for PropertyFieldListPicker component
 */ export default class PropertyFieldListPickerHost extends React . Component < IPropertyFieldListPickerHostProps , IPropertyFieldListPickerHostState > { private latestValidateValue : string ; private async : Async ; private delayedValidate : ( value : string ) => void ; /**
     * Constructor method
     */ constructor ( props ) { super ( props ) ; telemetry . track ( 'PropertyFieldListPicker' , { disabled : props . disabled } ) ; this . state = { loadedLists : { value : [ ] } , results : [ ] , errorMessage : '' } ; this . async = new Async ( this ) ; this . validate = this . validate . bind ( this ) ; this . onChanged = this . onChanged . bind ( this ) ; this . notifyAfterValidate = this . notifyAfterValidate . bind ( this ) ; this . delayedValidate = this . async . debounce ( this . validate , this . props . deferredValidationTime ) ; } public componentDidMount ( ) { this . loadLists ( ) ; } public componentDidUpdate ( prevProps , prevState ) { if ( this . props . baseTemplate !== prevProps . baseTemplate || this . props . webAbsoluteUrl !== prevProps . webAbsoluteUrl ) { this . loadLists ( ) ; } } /**
     * Loads the list from SharePoint current web site, or target site if specified by webRelativeUrl
     */ private async loadLists ( ) { const { context , selectedList } = this . props ; const listService = new SPListPickerService ( this . props , context ) ; const listsToExclude = this . props . listsToExclude || [ ] ; const options = [ ] ; let selectedListKey = '' ; if ( selectedList ) { selectedListKey = typeof selectedList === 'string' ? selectedList : selectedList . id ; } let selectedKey ; const response = await listService . getLibs ( ) ; response . value . forEach ( ( list ) => { if ( selectedListKey === list . Id ) { selectedKey = list . Id ; } if ( listsToExclude . indexOf ( list . Title ) === - 1 && listsToExclude . indexOf ( list . Id ) === - 1 ) { options . push ( { key : list . Id , text : list . Title } ) ; } } ) ; options . unshift ( { key : EMPTY_LIST_KEY , text : '' } ) ; this . setState ( { loadedLists : response , results : options , selectedKey : selectedKey } ) ; } /**
     * Raises when a list has been selected
     */ private onChanged ( option , index ? ) { const newValue = option . key as string ; this . delayedValidate ( newValue ) ; } /**
     * Validates the new custom field value
     */ private validate ( value ) { if ( this . props . onGetErrorMessage === null || this . props . onGetErrorMessage === undefined ) { this . notifyAfterValidate ( value ) ; return ; } if ( this . latestValidateValue === value ) { return ; } this . latestValidateValue = value ; const errResult = this . props . onGetErrorMessage ( value || '' ) ; if ( typeof errResult !== 'undefined' ) { if ( typeof errResult === 'string' ) { if ( errResult === '' ) { this . notifyAfterValidate ( value ) ; } this . setState ( { errorMessage : errResult } ) ; } else { errResult . then ( ( errorMessage ) => { if ( ! errorMessage ) { this . notifyAfterValidate ( value ) ; } this . setState ( { errorMessage : errorMessage } ) ; } ) ; } } else { this . notifyAfterValidate ( value ) ; } } /**
     * Notifies the parent Web Part of a property value change
     */ private notifyAfterValidate ( newValue ) { const { onPropertyChange , targetProperty , selectedList , includeListTitleAndUrl , properties , onChange } = this . props ; const { results , loadedLists } = this . state ; let propValue ; if ( includeListTitleAndUrl ) { if ( newValue === EMPTY_LIST_KEY ) { propValue = undefined ; } else { const spList = loadedLists . value . filter ( l => l . Id === newValue ) [ 0 ] ; propValue = { id : newValue , title : spList . Title , url : spList . RootFolder . ServerRelativeUrl } ; } } else { propValue = newValue === EMPTY_LIST_KEY ? '' : newValue ; } const options = this . state . results . map ( option => { if ( option . selected ) { option . selected = false ; } return option ; } ) ; const selectedKey = newValue ; this . setState ( { selectedKey : selectedKey , results : options } ) ; if ( onPropertyChange && propValue !== null ) { setPropertyValue ( properties , targetProperty , propValue ) ; onPropertyChange ( targetProperty , selectedList , propValue ) ; if ( typeof onChange !== 'undefined' && onChange !== null ) { onChange ( targetProperty , propValue ) ; } } } /**
     * Called when the component will unmount
     */ public componentWillUnmount ( ) { if ( typeof this . async !== 'undefined' ) { this . async . dispose ( ) ; } } /**
     * Renders the SPListpicker controls with Office UI Fabric
     */ public render ( ) { return ( < div > { this . props . label && < Label > { this . props . label } < /Label>} < Dropdown disabled = { this . props . disabled } label = '' onChanged = { this . onChanged } options = { this . state . results } selectedKey = { this . state . selectedKey } / > < FieldErrorMessage errorMessage = { this . state . errorMessage } /> < /div>); } }