Skip to content
Snippets Groups Projects
Select Git revision
  • 7bfadd247d49a6d8ee7d69752490c34b04bfb451
  • mui5-tetras-main-stable default protected
  • mui5-tetras-main-old-stable
  • preprod protected
  • 75-dernieres-ameliorations-avant-workshop-du-7-02
  • wip-fix-xywh
  • wip-positionement-annot
  • wip-surface-transformer
  • uploads-file
  • 69-la-video-demare-quand-on-fait-glisser-le-slider-et-le-clic-creer-un-decalage-entre-le-player
  • 61-recettage-des-outils-d-annotation
  • gestion_multiple_ouverture_pannel_annotation
  • autorisation_un_pannel_annotation
  • autorisation_un_pannel_edition_annotation
  • récupération_temps_video
  • save-shapes-and-position
  • fix-error-create-annotation-pannel
  • time-saving-on-annotation
  • tetras-main protected
  • fix-poc-mirador
  • tetras-antho-test
21 results

index.js

Blame
  • WorkspaceMosaic.js 5.14 KiB
    import React from 'react';
    import PropTypes from 'prop-types';
    import {
      MosaicWithoutDragDropContext, MosaicWindow, getLeaves, createBalancedTreeFromLeaves,
    } from 'react-mosaic-component';
    import 'react-mosaic-component/react-mosaic-component.css';
    import difference from 'lodash/difference';
    import isEqual from 'lodash/isEqual';
    import classNames from 'classnames';
    import MosaicRenderPreview from '../containers/MosaicRenderPreview';
    import Window from '../containers/Window';
    import MosaicLayout from '../lib/MosaicLayout';
    
    /**
     * Represents a work area that contains any number of windows
     * @memberof Workspace
     * @private
     */
    export class WorkspaceMosaic extends React.Component {
      /**
       */
      constructor(props) {
        super(props);
    
        this.tileRenderer = this.tileRenderer.bind(this);
        this.mosaicChange = this.mosaicChange.bind(this);
        this.determineWorkspaceLayout = this.determineWorkspaceLayout.bind(this);
        this.zeroStateView = <div />;
        this.windowPaths = {};
        this.toolbarControls = [];
        this.additionalControls = [];
      }
    
      /** */
      componentDidMount() {
        const { updateWorkspaceMosaicLayout } = this.props;
    
        const newLayout = this.determineWorkspaceLayout();
        if (newLayout) updateWorkspaceMosaicLayout(newLayout);
      }
    
      /** */
      componentDidUpdate(prevProps) {
        const { windowIds, layout, updateWorkspaceMosaicLayout } = this.props;
        const prevWindows = prevProps.windowIds;
        // Handles when Windows are added (not via Add Resource UI) Could be a workspace import
        if (!windowIds.every(e => prevWindows.includes(e))) {
          const newLayout = this.determineWorkspaceLayout();
          if (!isEqual(newLayout, layout)) updateWorkspaceMosaicLayout(newLayout);
          return;
        }
    
        // Handles when Windows are removed from the state
        if (!prevWindows.every(e => windowIds.includes(e))) {
          // There are no more remaining Windows, just return an empty layout
          if (windowIds.length === 0) {
            updateWorkspaceMosaicLayout(null);
            return;
          }
    
          const removedWindows = difference(prevWindows, windowIds);
          const newLayout = new MosaicLayout(layout);
          newLayout.removeWindows(removedWindows, this.windowPaths);
          updateWorkspaceMosaicLayout(newLayout.layout);
        }
      }
    
      /**
       * bookkeepPath - used to book keep Window's path's
       * @param  {String} windowId   [description]
       * @param  {Array} path [description]
       */
      bookkeepPath(windowId, path) {
        this.windowPaths[windowId] = path;
      }
    
      /**
       * Used to determine whether or not a "new" layout should be autogenerated.
       */
      determineWorkspaceLayout() {
        const { windowIds, layout } = this.props;
        const leaveKeys = getLeaves(layout);
        // Windows were added
        if (!windowIds.every(e => leaveKeys.includes(e))) {
          // No current layout, so just generate a new one
          if (leaveKeys.length < 2) {
            return createBalancedTreeFromLeaves(windowIds);
          }
          // Add new windows to layout
          const addedWindows = difference(windowIds, leaveKeys);
          const newLayout = new MosaicLayout(layout);
          newLayout.addWindows(addedWindows);
          return newLayout.layout;
        }
        // Windows were removed (perhaps in a different Workspace). We don't have a
        // way to reconfigure.. so we have to random generate
        if (!leaveKeys.every(e => windowIds.includes(e))) {
          return createBalancedTreeFromLeaves(windowIds);
        }
        return layout;
      }
    
      /** */
      static renderPreview(mosaicProps) {
        return (
          <div className="mosaic-preview" aria-hidden>
            <MosaicRenderPreview windowId={mosaicProps.windowId} />
          </div>
        );
      }
    
      /**
       * Render a tile (Window) in the Mosaic.
       */
      tileRenderer(id, path) {
        const { windowIds, workspaceId } = this.props;
        if (!windowIds.includes(id)) return null;
        this.bookkeepPath(id, path);
        return (
          <MosaicWindow
            toolbarControls={this.toolbarControls}
            additionalControls={this.additionalControls}
            path={path}
            windowId={id}
            renderPreview={WorkspaceMosaic.renderPreview}
          >
            <Window
              key={`${id}-${workspaceId}`}
              windowId={id}
            />
          </MosaicWindow>
        );
      }
    
      /**
       * Update the redux store when the Mosaic is changed.
       */
      mosaicChange(newLayout) {
        const { updateWorkspaceMosaicLayout } = this.props;
        updateWorkspaceMosaicLayout(newLayout);
      }
    
      /**
       */
      render() {
        const { layout, classes } = this.props;
        return (
          <MosaicWithoutDragDropContext
            renderTile={this.tileRenderer}
            initialValue={layout || this.determineWorkspaceLayout()}
            onChange={this.mosaicChange}
            className={classNames('mirador-mosaic', classes.root)}
            zeroStateView={this.zeroStateView}
          />
        );
      }
    }
    
    WorkspaceMosaic.propTypes = {
      classes: PropTypes.objectOf(PropTypes.string).isRequired,
      layout: PropTypes.oneOfType(
        [PropTypes.object, PropTypes.string],
      ), // eslint-disable-line react/forbid-prop-types
      updateWorkspaceMosaicLayout: PropTypes.func.isRequired,
      windowIds: PropTypes.arrayOf(PropTypes.string),
      workspaceId: PropTypes.string.isRequired,
    };
    
    WorkspaceMosaic.defaultProps = {
      layout: undefined,
      windowIds: [],
    };