/** * Created by rburson on 12/23/15. */ import * as React from 'react' import { CvState, CvProps, CvBaseMixin, CvEvent, CvEventRegistry, CvEventType, CvNavigationResult, CvResourceManager, CvMessage, CvMessageType, CvNavigationResultUtil } from './catreact-core' import { NavRequest, NavRequestUtil, Try } from 'catavolt-sdk' export interface CvNavigationState extends CvState { visible: boolean; navRequest:NavRequest; } export interface CvNavigationProps extends CvProps { /** * The result of a navigation. Should not be used if the navigationId property is provided */ navigationResult?:CvNavigationResult; /** * The cache identifier of the result of a Navigation. Should not be used if the navigationResult is provided. */ navigationId?:string; /** * Setting persistent true, allows this component to remain visible, even after another, new Navigation has * taken place. This is useful for single page apps where components may be coresident. */ persistent?: boolean, /** * Allows for one Navigation component to target another, when coresident on the page. */ targetId?: string, } /* *************************************************** * Render a NavRequest *************************************************** */ export var CvNavigation = React.createClass({ mixins: [CvBaseMixin], componentDidMount: function () { if(this.props.navigationResult) { this.setState({navRequest: this.props.navigationResult.navRequest, visible:true}); } else if(this.props.navigationId){ this._handleRetrieveNavigation(this.props.navigationId); } (this.eventRegistry() as CvEventRegistry).subscribe(this._navListener, CvEventType.NAVIGATION); }, componentWillUnmount: function() { (this.eventRegistry() as CvEventRegistry).unsubscribe(this._navListener); }, componentWillReceiveProps: function(nextProps) { if(nextProps.navigationResult) { this.setState({navRequest: nextProps.navigationResult.navRequest, visible:true}); } else if(nextProps.navigationId) { this._handleRetrieveNavigation(nextProps.navigationId); } }, getChildContext: function () { const ctx = this.getDefaultChildContext(); ctx.cvContext.scopeCtx.scopeObj = this.state.navRequest; return ctx; }, getDefaultProps: function() { return {persistent: false, targetId: null, navigationResult: null, navigationId: null}; }, getInitialState: function () { return {visible: false, navRequest: null} }, render: function () { if (this.state.visible && this.state.navRequest) { if(this.props.renderer) { return this.props.renderer(this.getChildContext().cvContext); }else if (React.Children.count(this.props.children) > 0) { return this.props.children } else { return null; } } else { return null; } }, _handleRetrieveNavigation: function(navigationId:string) { const event:CvEvent = this.eventRegistry().getEventByKey(navigationId); if(!event) { const {redirection, actionSource} = CvResourceManager.deserializeRedirection(navigationId); NavRequestUtil.fromRedirection(redirection, actionSource, this.catavolt().sessionContextTry.success).onComplete((navRequestTry:Try) => { if(navRequestTry.isSuccess) { CvNavigationResultUtil.publishNavigation(this.catavolt(), this.eventRegistry(), navRequestTry.success, (actionSource as any).actionId, (actionSource as any).workbenchId , null, null, false, false); this.setState({navRequest:navRequestTry.success, visible: true}); } else { const event:CvEvent = {type:CvEventType.MESSAGE, eventObj:{message:'Navigation failed', messageObj:navRequestTry.failure, type: CvMessageType.ERROR}} this.eventRegistry().publish(event, false); } }); } else { this.setState({navRequest:event.eventObj.navRequest, visible: true}); } }, _navListener: function(navEvent:CvEvent) { const navRequest = navEvent.eventObj.navRequest; if (navRequest && this.isMounted()) { if (navEvent.eventObj.navTarget) { if (this.props.targetId === navEvent.eventObj.navTarget) { this.setState({navRequest: navRequest, visible: true}) } else { if (!this.props.persistent) this.setState({visible: false}); } } } }, });