Skip to content
Snippets Groups Projects
experiment-tools-service.js 6.38 KiB
Newer Older
import FlexLayout from 'flexlayout-react';

import DescriptionIcon from '@material-ui/icons/Description';
import ListAltIcon from '@material-ui/icons/ListAlt';
const appConfig = window.appConfig;
import NrpCoreDashboard from '../nrp-core-dashboard/nrp-core-dashboard';
import TransceiverFunctionEditor from '../tf-editor/tf-editor';
import XpraView from '../xpra/xpra-view';
import { SIM_TOOL } from '../constants';


let _instance = null;
const SINGLETON_ENFORCER = Symbol();

/**
 * Service handling server resources for simulating experiments.
 */
Sandro Weber's avatar
Sandro Weber committed
class ExperimentToolsService {
  constructor(enforcer) {
    if (enforcer !== SINGLETON_ENFORCER) {
      throw new Error('Use ' + this.constructor.name + '.instance');
    }

    this.tools = new Map();
Sandro Weber's avatar
Sandro Weber committed
    for (const toolEntry in ExperimentToolsService.TOOLS) {
      this.registerToolConfig(ExperimentToolsService.TOOLS[toolEntry]);
    }
    this.registerToolConfig(NrpCoreDashboard.CONSTANTS.TOOL_CONFIG);
    this.registerToolConfig(XpraView.CONSTANTS.TOOL_CONFIG);
  }

  static get instance() {
    if (_instance == null) {
Sandro Weber's avatar
Sandro Weber committed
      _instance = new ExperimentToolsService(SINGLETON_ENFORCER);
  setFlexLayoutModel(model) {
    this.flexLayoutModel = model;
  }

  registerToolConfig(toolConfig) {
    let id = toolConfig.flexlayoutNode.component;
    if (this.tools.has(id)) {
      console.warn('SimulationToolsService.registerToolConfig() - tool with ID ' + id + ' already exists');
      return;
    }

    this.tools.set(id, toolConfig);
  }

  flexlayoutNodeFactory(node) {
    var component = node.getComponent();
    let toolConfig = this.tools.get(component);
    if (toolConfig && toolConfig.flexlayoutFactoryCb) {
      return toolConfig.flexlayoutFactoryCb();
    }
    else {
      console.error('tool config for "' + component + '" is missing a callback for creating a flex-layout window!');
  }

  startToolDrag(toolConfig, layoutReference) {
    let instances = this.getComponentInstanceList(
      toolConfig.flexlayoutNode.component,
      layoutReference.current.previousModel);
    if (toolConfig.singleton && instances.length > 0) {
      layoutReference.current.doAction(FlexLayout.Actions.selectTab(instances[0].getId()));
    else {
      layoutReference.current.addTabWithDragAndDrop(toolConfig.flexlayoutNode.name, toolConfig.flexlayoutNode);
  addTool(toolConfig, layoutReference) {
    let instances = this.getComponentInstanceList(
      toolConfig.flexlayoutNode.component,
      layoutReference.current.previousModel);
    if (toolConfig.singleton && instances.length > 0) {
      layoutReference.current.doAction(FlexLayout.Actions.selectTab(instances[0].getId()));
    }
    else {
      layoutReference.current.addTabToActiveTabSet(toolConfig.flexlayoutNode);
    }
  getComponentInstanceList(flexLayoutComponent, flexLayoutModel) {
    let list = [];
    flexLayoutModel.visitNodes((node, level) => {
      if (node._attributes.component === flexLayoutComponent) {
        list.push(node);
      }
    });
    return list;
ExperimentToolsService.CONSTANTS = Object.freeze({
  /*CATEGORY: {
    EXTERNAL_IFRAME: 'EXTERNAL_IFRAME',
    REACT_COMPONENT: 'REACT_COMPONENT'
  },
  TOOL_TYPE: {
    FLEXLAYOUT_TAB: 'flexlayout-tab',
    EXTERNAL_TAB: 'external-tab'
  }*/
});

Sandro Weber's avatar
Sandro Weber committed
ExperimentToolsService.TOOLS = Object.freeze({
  // NEST_DESKTOP: {
  //   singleton: true,
  //   type: ExperimentToolsService.CONSTANTS.TOOL_TYPE.FLEXLAYOUT_TAB,
  //   flexlayoutNode: {
  //     'name': 'NEST Desktop',
  //     'component': 'nest-desktop'
  //   },
  //   flexlayoutFactoryCb: () =>  {
  //     return <iframe src='http://localhost:8000' title='NEST Desktop' />;
  //   },
  //   getIcon: () => {
  //     return <div>
  //       <img src={'https://www.nest-simulator.org/wp-content/uploads/2015/03/nest_logo.png'}
  //         alt="NEST Desktop"
  //         style={{width: 40+ 'px', height: 20 + 'px'}} />
  //     </div>;
  //   }
  // },
  TEST_NRP_CORE_DOCU: {
    singleton: false,
    type: SIM_TOOL.TOOL_TYPE.FLEXLAYOUT_TAB,
    flexlayoutNode: {
      'name': 'NRP-Core Docs',
      'component': 'nrp-core-docu'
    flexlayoutFactoryCb: () => {
      return <iframe src='https://hbpneurorobotics.bitbucket.io/index.html'
        title='NRP-Core Documentation' />;
    },
    getIcon: () => {
      return <DescriptionIcon/>;
  /*XPRA_EXTERNAL_TAB: {
    singleton: true,
    type: ExperimentToolsService.CONSTANTS.TOOL_TYPE.EXTERNAL_TAB,
    flexlayoutNode: {
      'name': 'Xpra',
      'component': 'xpra-external'
    },
    getIcon: () => {
      return <div>
        <a href='http://localhost:9000/xpra/index.html' target='_blank' rel="noreferrer">
          <img src={'https://www.xpra.org/icons/xpra-logo.png'}
            alt="Xpra"
            style={{width: 40+ 'px', height: 20 + 'px'}} />
        </a>
      </div>;
    }
  },*/
  /*XPRA: {
    singleton: true,
    type: ExperimentToolsService.CONSTANTS.TOOL_TYPE.FLEXLAYOUT_TAB,
    flexlayoutNode: {
      'name': 'Server Videostream (Xpra)',
      'component': 'xpra'
    },
    flexlayoutFactoryCb: () =>  {
      return <XpraView />;
    },
    getIcon: () => {
      return <OndemandVideoIcon />;
    },
    isShown: () => {
      const xpra = ExperimentWorkbenchService.instance.xpraUrls;
      return xpra && xpra.length > 0;
    }
  },*/
  TRANSCEIVER_FUNCTIONS_EDITOR: {
    singleton: true,
    type: SIM_TOOL.TOOL_TYPE.FLEXLAYOUT_TAB,
    flexlayoutNode: {
      'name': 'Edit experiment files',
      'component': 'TransceiverFunctionEditor'
    flexlayoutFactoryCb: () => {
      return <TransceiverFunctionEditor />;
    },
    getIcon: () => {
      return <ListAltIcon/>;
  },
  NEST_DESKTOP: {
    singleton: true,
    type: SIM_TOOL.TOOL_TYPE.FLEXLAYOUT_TAB,
    flexlayoutNode: {
      'name': 'NEST Desktop',
      'component': 'nest-desktop'
    },
    flexlayoutFactoryCb: () =>  {
      return <iframe src={appConfig.nestDesktop.url} title='NEST Desktop' />;
    },
    getIcon: () => {
      return <div>
        <img src={'https://www.nest-simulator.org/wp-content/uploads/2015/03/nest_logo.png'}
          alt="NEST Desktop"
          style={{width: 40+ 'px', height: 20 + 'px'}} />
      </div>;
    },
    isShown: () => {
      return appConfig && appConfig.nestDesktop && appConfig.nestDesktop.enabled;
    }
Sandro Weber's avatar
Sandro Weber committed
export default ExperimentToolsService;