I've developed a SharePoint Bot using the Bot Framework (v4 NodeJS) and to ensure a consistent user experience, I've been looking at incorporating it into an Office UI Fabric React panel using the React DirectLine channel via an SPFX Application Customiser app.
The problem I'm running into is that I am receiving a couple of errors that I suspect are related; one is in the Developer tools console that says 'Cannot read property 'subscribe' of undefined'.
The other error is in the Fabric panel that says 'Render error. Please check the console or contact the Bot developer.'
BotPanel.tsx
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
import * as React from 'react';
import ReactWebChat from 'botframework-webchat';
import { DirectLine } from 'botframework-directlinejs';
export interface IPanelFooterExampleState {
showPanel: boolean;
}
export default class extends React.Component {
constructor(props) {
super(props);
new DirectLine({ token: 'DIRECT_LINE_TOKEN' });
}
public state = {
showPanel: false
};
public render() {
return (
<div>
<DefaultButton secondaryText="Ask SharePoint Bot" onClick={this._showPanel} text="Ask SharePoint Bot" />
<Panel
isOpen={this.state.showPanel}
type={PanelType.medium}
onDismiss={this._hidePanel}
isFooterAtBottom={true}
headerText="Ask SharePoint Bot"
closeButtonAriaLabel="Close"
onRenderFooterContent={this._onRenderFooterContent}
>
<span>
<ReactWebChat directLine={{ DirectLine }} />
</span>
</Panel>
</div>
);
}
private _onRenderFooterContent = (): JSX.Element => {
return (
<div>
<DefaultButton onClick={this._hidePanel}>End Conversation
</DefaultButton>
</div>
);
};
private _showPanel = () => {
this.setState({ showPanel: true });
};
private _hidePanel = () => {
this.setState({ showPanel: false });
};
}
BotPanelApplicationCustomizer.ts
import { override } from '@microsoft/decorators';
import {
BaseApplicationCustomizer,
PlaceholderContent,
PlaceholderName
} from '@microsoft/sp-application-base';
import * as React from 'react';
import * as ReactDom from 'react-dom';
import PanelFooterExample from './BotPanel';
const LOG_SOURCE: string = 'BotReactPanelApplicationCustomizer';
/**
* If your command set uses the ClientSideComponentProperties JSON input,
* it will be deserialized into the BaseExtension.properties object.
* You can define an interface to describe it.
*/
export interface IBotReactPanelApplicationCustomizerProperties {
// This is an example; replace with your own property
testMessage: string;
}
/** A Custom Action which can be run during execution of a Client Side Application */
export default class BotReactPanelApplicationCustomizer
extends BaseApplicationCustomizer<IBotReactPanelApplicationCustomizerProperties> {
@override
public onInit(): Promise<void> {
// render method of the webpart, actually calls Component
const topPlaceholder = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Top);
const element = React.createElement(PanelFooterExample);
// reactDom.render(element, this.domElement);
ReactDom.render(element, topPlaceholder.domElement);
return Promise.resolve();
}
}
I'm new to React, so still finding my feet with it. But I presume the Fabric components are required to be surfaced in a TSX file, the code for which, I've enclosed. I'm guessing I am missing a sequence which would connect the DirectLine and Panel together?
I'm hoping to have the Bot DirectLine channel surfaced in the Fabric panel to give users a consistent SharePoint experience.