import * as React from 'react' ; import * as ReactDom from 'react-dom' ; import { Version , Guid , UrlQueryParameterCollection , DisplayMode } from '@microsoft/sp-core-library' ; import { IPropertyPaneConfiguration , IPropertyPanePage , IPropertyPaneField , PropertyPaneTextField } from '@microsoft/sp-property-pane' ; import * as commonStrings from 'CommonStrings' ; import * as webPartStrings from 'SearchVerticalsWebPartStrings' ; import { ISearchVerticalsContainerProps } from './components/ISearchVerticalsContainerProps' ; import { ISearchVerticalsWebPartProps } from './ISearchVerticalsWebPartProps' ; import { TextField , ITextFieldProps , Dropdown , IDropdownProps , Checkbox } from 'office-ui-fabric-react' ; import SearchVerticalsContainer from './components/SearchVerticalsContainer' ; import { ComponentType } from '../../common/ComponentType' ; import { IDynamicDataCallables , IDynamicDataPropertyDefinition } from '@microsoft/sp-dynamic-data' ; import { IDataVerticalSourceData } from '../../models/dynamicData/IDataVerticalSourceData' ; import { TokenService } from '../../services/tokenService/TokenService' ; import { ITokenService , IDataVertical } from '@pnp/modern-search-extensibility' ; import { BaseWebPart } from '../../common/BaseWebPart' ; import { PageOpenBehavior } from '../../helpers/UrlHelper' ; import { IDataVerticalConfiguration } from '../../models/common/IDataVerticalConfiguration' ; import commonStyles from '../../styles/Common.module.scss' ; export default class DataVerticalsWebPart extends BaseWebPart < ISearchVerticalsWebPartProps > implements IDynamicDataCallables { /**
     * Dynamically loaded components for property pane
     */ private _propertyFieldCollectionData : any = null ; private _propertyPanePropertyEditor = null ; private _customCollectionFieldType : any = null ; private _placeholderComponent : any = null ; /**
     * The current selected vertical
     */ private _selectedVertical : IDataVertical ; /**
     * The token service instance
     */ private tokenService : ITokenService ; public constructor ( ) { super ( ) ; this . onVerticalSelected = this . onVerticalSelected . bind ( this ) ; } protected async onInit ( ) { this . initializeProperties ( ) ; await this . initializeBaseWebPart ( ) ; this . initializeWebPartServices ( ) ; this . context . dynamicDataSourceManager . initializeSource ( this ) ; if ( this . displayMode === DisplayMode . Edit ) { const { Placeholder } = await import ( '@pnp/spfx-controls-react/lib/Placeholder' ) ; this . _placeholderComponent = Placeholder ; } } public render ( ) { let renderRootElement = null ; let defaultSelectedKey = undefined ; if ( this . properties . defaultVerticalQueryStringParam ) { const queryParms = new UrlQueryParameterCollection ( window . location . href . toLowerCase ( ) ) ; const defaultQueryVal = queryParms . getValue ( this . properties . defaultVerticalQueryStringParam . toLowerCase ( ) ) ; if ( defaultQueryVal ) { const defaultSelected = this . properties . verticals . filter ( v => v . tabName . toLowerCase ( ) == decodeURIComponent ( defaultQueryVal ) ) ; if ( defaultSelected . length === 1 ) { defaultSelectedKey = defaultSelected [ 0 ] . key ; } } } else { const pagename = window . location . pathname . toLowerCase ( ) ; const defaultSelected = this . properties . verticals . filter ( v => v . isLink && v . linkUrl . toLowerCase ( ) . indexOf ( pagename ) > - 1 ) ; if ( defaultSelected . length === 1 ) { defaultSelectedKey = defaultSelected [ 0 ] . key ; } } if ( this . displayMode === DisplayMode . Edit && this . properties . verticals . length === 0 ) { const placeholder = React . createElement ( this . _placeholderComponent , { iconName : 'Sections' , iconText : webPartStrings . General . PlaceHolder . IconText , description : webPartStrings . General . PlaceHolder . Description , buttonLabel : webPartStrings . General . PlaceHolder . ConfigureBtnLabel , onConfigure : ( ) => { this . context . propertyPane . openDetails ( ) ; } } ) ; renderRootElement = placeholder ; } else { renderRootElement = React . createElement ( SearchVerticalsContainer , { verticals : this . properties . verticals , webPartTitleProps : { displayMode : this . displayMode , title : this . properties . title , updateProperty : ( value ) => { this . properties . title = value ; } , className : commonStyles . wpTitle } , tokenService : this . tokenService , themeVariant : this . _themeVariant , onVerticalSelected : this . onVerticalSelected . bind ( this ) , defaultSelectedKey : defaultSelectedKey } as ISearchVerticalsContainerProps ) ; } ReactDom . render ( renderRootElement , this . domElement ) ; } public getPropertyDefinitions ( ) { return [ { id : ComponentType . SearchVerticals , title : this . properties . title ? `${ this . properties . title } - ${ this . instanceId }` : `${ webPartStrings . General . WebPartDefaultTitle } - ${ this . instanceId }` } ] ; } public getPropertyValue ( propertyId ) { switch ( propertyId ) { case ComponentType . SearchVerticals : return { selectedVertical : this . _selectedVertical , verticalsConfiguration : this . properties . verticals , } as IDataVerticalSourceData ; default : throw new Error ( 'Bad property id' ) ; } } protected onPropertyPaneFieldChanged ( propertyPath ) { if ( propertyPath . localeCompare ( 'verticals' ) === 0 ) { this . properties . verticals = this . properties . verticals . map ( vertical => { vertical . key = vertical . key ? vertical . key : Guid . newGuid ( ) . toString ( ) ; return vertical ; } ) ; } } protected onDispose ( ) { ReactDom . unmountComponentAtNode ( this . domElement ) ; } protected get dataVersion ( ) : Version { return Version . parse ( '1.0' ) ; } protected getPropertyPaneConfiguration ( ) { let propertyPanePages = [ ] ; propertyPanePages . push ( { groups : [ { groupName : webPartStrings . PropertyPane . SearchVerticalsGroupName , groupFields : this . _getVerticalsConfguration ( ) } ] , displayGroupsAsAccordion : true } ) ; propertyPanePages . push ( { displayGroupsAsAccordion : true , groups : [ ... this . getPropertyPaneWebPartInfoGroups ( ) , { groupName : commonStrings . PropertyPane . InformationPage . ImportExport , groupFields : [ this . _propertyPanePropertyEditor ( { webpart : this , key : 'propertyEditor' } ) ] } ] } ) ; return { pages : propertyPanePages } ; } protected async onPropertyPaneConfigurationStart ( ) { await this . loadPropertyPaneResources ( ) ; } protected async loadPropertyPaneResources ( ) { const { PropertyFieldCollectionData , CustomCollectionFieldType } = await import ( '@pnp/spfx-property-controls/lib/PropertyFieldCollectionData' ) ; this . _propertyFieldCollectionData = PropertyFieldCollectionData ; this . _customCollectionFieldType = CustomCollectionFieldType ; const { PropertyPanePropertyEditor } = await import ( '@pnp/spfx-property-controls/lib/PropertyPanePropertyEditor' ) ; this . _propertyPanePropertyEditor = PropertyPanePropertyEditor ; } private _getVerticalsConfguration ( ) { let settingFields = [ this . _propertyFieldCollectionData ( 'verticals' , { manageBtnLabel : webPartStrings . PropertyPane . Verticals . ButtonLabel , key : 'verticals' , panelHeader : webPartStrings . PropertyPane . Verticals . PanelHeader , panelDescription : webPartStrings . PropertyPane . Verticals . PanelDescription , enableSorting : true , label : webPartStrings . PropertyPane . Verticals . PropertyLabel , value : this . properties . verticals , fields : [ { id : 'tabName' , title : webPartStrings . PropertyPane . Verticals . Fields . TabName , type : this . _customCollectionFieldType . string , placeholder : "ex: 'SharePoint'" , required : true } , { id : 'iconName' , title : webPartStrings . PropertyPane . Verticals . Fields . IconName , type : this . _customCollectionFieldType . string , placeholder : "ex: 'Document'" , required : false } , { id : 'tabValue' , title : webPartStrings . PropertyPane . Verticals . Fields . TabValue , type : this . _customCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item ) => { return ( React . createElement ( "div" , null , React . createElement ( TextField , { defaultValue : value , disabled : ! item . isLink ? false : true , onChange : ( ev , newValue ) => { onUpdate ( field . id , newValue ) ; } } as ITextFieldProps ) ) ) ; } } , { id : 'isLink' , title : webPartStrings . PropertyPane . Verticals . Fields . IsLink , type : this . _customCollectionFieldType . boolean , required : false } , { id : 'linkUrl' , title : webPartStrings . PropertyPane . Verticals . Fields . LinkUrl , type : this . _customCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item ) => { return ( React . createElement ( "div" , null , React . createElement ( TextField , { defaultValue : value , disabled : item . isLink ? false : true , placeholder : 'https://...' , onChange : ( ev , newValue ) => { onUpdate ( field . id , newValue ) ; } } as ITextFieldProps ) ) ) ; } } , { id : 'openBehavior' , title : webPartStrings . PropertyPane . Verticals . Fields . OpenBehavior , type : this . _customCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item ) => { return ( React . createElement ( "div" , null , React . createElement ( Dropdown , { options : [ { key : PageOpenBehavior . NewTab , text : commonStrings . General . NewTabOpenBehavior } , { key : PageOpenBehavior . Self , text : commonStrings . General . SameTabOpenBehavior } , ] , disabled : item . isLink ? false : true , defaultSelectedKey : item . openBehavior , onChange : ( ev , option ) => onUpdate ( field . id , option . key ) , } as IDropdownProps ) ) ) ; } } , { id : 'showLinkIcon' , title : webPartStrings . PropertyPane . Verticals . Fields . ShowLinkIcon , type : this . _customCollectionFieldType . custom , onCustomRender : ( field , value , onUpdate , item , itemId ) => { return ( React . createElement ( "div" , null , React . createElement ( Checkbox , { key : itemId , checked : value , disabled : item . isLink ? false : true , onChange : ( evt , checked ) => { onUpdate ( field . id , checked ) ; } } ) ) ) ; } , required : false } , ] } ) , PropertyPaneTextField ( 'defaultVerticalQueryStringParam' , { label : webPartStrings . PropertyPane . Verticals . DefaultVerticalQueryStringParamLabel , description : webPartStrings . PropertyPane . Verticals . DefaultVerticalQueryStringParamDescription } ) ] ; return settingFields ; } private initializeWebPartServices ( ) { this . tokenService = this . context . serviceScope . consume < ITokenService > ( TokenService . ServiceKey ) ; } /**
     * Initializes required Web Part properties
     */ private initializeProperties ( ) { this . properties . verticals = this . properties . verticals ? this . properties . verticals : [ ] ; if ( this . properties . defaultVerticalQueryStringParam === undefined ) { this . properties . defaultVerticalQueryStringParam = 'v' ; } } private async onVerticalSelected ( itemKey ) { const verticals = this . properties . verticals . filter ( vertical => { return vertical . key === itemKey ; } ) ; if ( verticals . length > 0 ) { const tabValue = await this . tokenService . resolveTokens ( verticals [ 0 ] . tabValue ) ; this . _selectedVertical = { key : verticals [ 0 ] . key , name : verticals [ 0 ] . tabName , value : tabValue } ; } else { this . _selectedVertical = undefined ; } this . context . dynamicDataSourceManager . notifyPropertyChanged ( ComponentType . SearchVerticals ) ; } }