application/components/layout/root.js
import React from 'react';
import uuid from 'uuid';
import Immutable from 'immutable';
import Events from './../../util/events';
/**
 * The idea here is you generate a unique ID and a component
 * then emit an addRootComponent event with the id and component
 * and it is injected here.
 *
 * It's really quite hacky but it works. Something like:
 *
 * <code>
 *     const myComponent = <SomeThing />;
 *     events.emit('addRootComponent', myId, myComponent);
 *
 *     // then to remove
 *     events.emit('removeRootComponent', myId);
 * </code>
 */
class RootExtension extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            components: []
        }
    }
    componentWillMount() {
        Events.listen('addRootComponent', this.onAdd.bind(this));
        Events.listen('removeRootComponent', this.onRemove.bind(this));
    }
    componentWillUnmount() {
        Events.unlisten('addRootComponent', this.onAdd.bind(this));
        Events.unlisten('removeRootComponent', this.onRemove.bind(this));
    }
    onAdd(id, component, callback) {
        let components = this.state.components;
        for (let comp in components) {
            if (components[comp].uuid === id) {
                return;
            }
        }
        components.push({'component': component, 'uuid': id});
        this.setState({'components': components});
        if (callback) {
            callback(id);
        }
    }
    onRemove(id) {
        let components = this.state.components;
        let newComponents = [];
        for (let comp in components) {
            if (components[comp].uuid === id) {
                continue;
            }
            newComponents.push(components[comp]);
        }
        this.setState({'components': newComponents});
    }
    render() {
        return (
            <div>
                {this.state.components.map((child, i) => {
                    return <div key={child.uuid}>{child.component}</div>;
                })}
            </div>
        );
    }
}
export default RootExtension;