import * as React from "react" import * as PropTypes from "prop-types" import {getContext, InferableComponentEnhancerWithProps} from "recompose" import * as Utils from "./Utils" import { NotificationManager, Notifier} from "./NotificationManager" import { ConsoleErrorHandler, ErrorHandler } from "./ErrorHandler" import { XRM } from "./xrm" export * from "./NotificationManager" export interface DynamicsContext { xrm: XRM | null notifier: Notifier errorHandler: ErrorHandler } export interface DynamicsProps { xrm?: XRM | null notifier?: Notifier errorHandler?: ErrorHandler } /** Not used yet. */ export const dynamicsShape = PropTypes.shape({ notifier: PropTypes.object, xrm: PropTypes.object, errorHandler: PropTypes.object }) /** * Render the first child only. Places Xrm and a NotificationManager into the context. * Declare a child's use of the context: * ``` * class Foo extends React.Component { * public static contextTypes = { * Xrm: PropTypes.object, // can use isRequired * notifier: PropTypes.instanceOf(Object) // can use isRequired * } * constructor(props, context) { * super(props, context); * ... * } * ... * ``` * You can access the context using `this.context.notifier.add(..)`. Instead of retyping * the contextTypes in the child, you can use `public static contextTypes { ...Dynamics.childContextTypes }`. * * The component is stateless as only the children define the render. * * TODO: Notifier only works on forms, make more general so it works in non-forms. */ export class Dynamics

extends React.Component { constructor(props: P, context: any) { super(props, context) } private defaultErrorHandler: ErrorHandler = new ConsoleErrorHandler() private defaultNotifier: Notifier = new NotificationManager(() => this.getXrm()) public getChildContext(): DynamicsContext { return { notifier: this.notifier, xrm: this.getXrm(), errorHandler: this.errorHandler, } } /** Get Xrm from the props or the global environment window.parent. */ protected getXrm = (): XRM | null => { //console.log("Dyanmics.getXrm()", this) if(this.props && typeof this.props.xrm !== "undefined" && this.props.xrm !== null) return this.props.xrm! return Utils.getXrm() } get notifier(): Notifier { return (this.props && this.props.notifier) ? this.props.notifier! as Notifier: this.defaultNotifier } get errorHandler(): ErrorHandler { return this.props.errorHandler ? (this.props.errorHandler as ErrorHandler): this.defaultErrorHandler } public static childContextTypes = { notifier: PropTypes.object, xrm: PropTypes.object, errorHandler: PropTypes.object } render() { const { children } = this.props; return React.Children.only(children) } } /** Use this to compose your component with Xrm and NotificationManager * in the props. * * const YourComponent = ({notificationManager, Xrm, ...rest}) => { * console.log(notifier, Xrm); // to prove that it is there. * } * export default withDynamics(YourComponent) * ``` */ export const withDynamics = getContext( { notifier: PropTypes.instanceOf(NotificationManager), xrm: PropTypes.object, errorHandler: PropTypes.object } ) export default Dynamics