dashboard.js

/* eslint no-bitwise: ["error", { "allow": [">>", "^"] }] */
import Promise from 'promise-polyfill';
import 'jspolyfill-array.prototype.find';

import MapManager from './map/map-manager';
import WidgetManager from './widget/widget-manager';

import template from '../templates/dashboard.hbs';

import '../styles/dashboard.scss';

/**
 * The main class of GeoDashboard.
 */
class Dashboard {
  /**
   * @param {Object} config - Configuration object
   * @param {HTMLElement} config.container - Element where the dashboard will be placed
   * @param {Object} config.map - Map configuration
   * @param {Number[]} config.map.center - The initial center for the map
   * @param {Number} config.map.zoom - The initial zoom level
   * @param {Object} [config.map.mapParams] - Extra params for OpenLayers Map constructor
   * @param {Object} [config.map.viewParams] - Extra params for OpenLayers View constructor
   * @param {Filter[]} [config.filters] - Set of filters to apply to layers and widgets
   */
  constructor(config) {
    this.container = config.container;
    this.filters = config.filters || [];

    if (!window.Promise) {
      window.Promise = Promise;
    }

    /**
     * Dashboard MapManager
     * @member {MapManager}
     */
    this.mapManager = new MapManager(config.map);
    this.mapManager.dashboard = this;

    this.mapManager.on('mapchange', (event) => {
      this.extent = event.extent;
      this.widgetManager.refresh(this.extent);
    });

    /**
     * Dashboard WidgetManager
     * @member {WidgetManager}
     */
    this.widgetManager = new WidgetManager();
    this.widgetManager.dashboard = this;
  }

  /**
  * All filter strings joined by logical operator
  * @member {String}
  * @readonly
  */
  get filterString() {
    if (!this.filters || !this.filters.length) return null;
    let filter = this.filters[0].toString();
    for (let i = 1; i < this.filters.length; i++) {
      filter += ` ${this.filters[i].logicalOperator} ${this.filters[i]}`;
    }
    return filter;
  }

  /**
   * Creates the dashboard content and render map and widgets.
   */
  render() {
    this.container.insertAdjacentHTML('beforeend', template());
    this.mapManager.render(this.container.getElementsByClassName('map')[0]);
    this.widgetManager.container = this.container.getElementsByClassName('widget-panel')[0];
    this.widgetManager.render();
  }

  /**
   * Refresh all layers and widgets
   */
  refresh() {
    this.widgetManager.refresh(this.extent);
    this.mapManager.refresh();
  }

  /**
   * Adds base layer to the map
   * @param {BaseLayer} layer - The base layer to be added
   */
  addBaseLayer(layer) {
    this.mapManager.addBaseLayer(layer);
  }

  /**
   * Adds overlay layer to the map
   * @param {OverlayLayer} layer - The overlay layer to be added
   */
  addOverlayLayer(layer) {
    this.mapManager.addOverlayLayer(layer);
  }

  /**
   * Adds widget to the panel
   * @param {Widget} widget - The widget to be added
   */
  addWidget(widget) {
    this.widgetManager.addWidget(widget);
  }

  /**
   * Adds filter
   * @param {Filter} filter - The filter to be added
   */
  addFilter(filter) {
    this.filters.push(filter);
    this.refresh();
  }

  /**
   * Resets filters
   * @param {Filter[]} [filters] - New set of filters
   */
  resetFilters(filters = []) {
    this.filters = filters;
    this.refresh();
  }

  /**
   * Map center coordinates
   * @member {Number[]}
   */
  get mapCenter() {
    return this.mapManager.center;
  }

  set mapCenter(value) {
    this.mapManager.center = value;
  }

  /**
   * Map zoom level
   * @member {Number}
   */
  get mapZoom() {
    return this.mapManager.zoom;
  }

  set mapZoom(value) {
    this.mapManager.zoom = value;
  }

  /**
   * Centers map to definied feature
   * @param {Object} feature - Feature to center
   */
  centerMapToFeature(feature) {
    this.mapManager.centerToFeature(feature);
  }

  /**
   * Fits map to defined layer
   * @param {Layer} layer - Layer to fit in map
   */
  fitMapToLayer(layer) {
    this.mapManager.fitToLayer(layer);
  }

  /**
   * Displays feature popup with information
   * @param {Object} layer - Layer to show
   * @param {Object} feature - Feature to show
   */
  showFeaturePopup(layer, feature) {
    this.mapManager.showFeaturePopup(layer, feature);
  }

  /**
   * Generate random string to use as unique element ID
   */
  static uid() {
    return `gd${Math.random().toString(36).substring(7)}`;
  }
}

export default Dashboard;