Skip to content
Snippets Groups Projects
ConnectedTrackChange.js 3.52 KiB
Newer Older
chris's avatar
chris committed
/* eslint react/prop-types: 0 */
import React, { useContext, useMemo, useState, useEffect } from 'react';
chris's avatar
chris committed
import styled from 'styled-components';
chris's avatar
chris committed
import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core';
import { last, maxBy } from 'lodash';
import { TextSelection } from 'prosemirror-state';
chris's avatar
chris committed
import TrackChangesBox from './ui/trackChanges/TrackChangesBox';
import acceptTrackChange from './ui/trackChanges/AcceptTrackChange';
import rejectTrackChange from './ui/trackChanges/RejectTrackChange';
chris's avatar
chris committed

const ConnectedTrackChangeStyled = styled.div`
  margin-left: ${props => (props.active ? `${-20}px` : `${50}px`)};
  width: 205px;
chris's avatar
chris committed
  @media (max-width: 600px) {
    margin-left: 15px;
  }
`;

export default ({ trackChangeId, top, recalculateTops, trackChange }) => {
chris's avatar
chris committed
  const context = useContext(WaxContext);
chris's avatar
chris committed
  const { app, activeView, pmViews } = context;
  const user = app.config.get('user');
  const [isActive, setIsActive] = useState(false);
  const { state, dispatch } = activeView;
  const viewId = trackChange.attrs
    ? trackChange.attrs.viewid
    : trackChange.node.attrs.viewid;
chris's avatar
chris committed

chris's avatar
chris committed
  const styles = {
    top: `${top}px`,
  };

chris's avatar
chris committed
  const trakChangePlugin = app.PmPlugins.get('trackChangePlugin');
chris's avatar
chris committed
  const activeTrackChange = trakChangePlugin.getState(activeView.state)
    .trackChange;
  const onClickBox = trackData => {
chris's avatar
chris committed
    if (trackData.node) return focusOnBlcock(trackData);

chris's avatar
chris committed
    if (viewId !== 'main') context.updateView({}, viewId);

    const allTracksWithSameId = DocumentHelpers.findAllMarksWithSameId(
chris's avatar
chris committed
      pmViews[viewId].state,
      trackData,
    );
    const maxPos = maxBy(allTracksWithSameId, 'pos');
    maxPos.pos += last(allTracksWithSameId).node.nodeSize;

chris's avatar
chris committed
    pmViews[viewId].dispatch(
      pmViews[viewId].state.tr.setSelection(
        new TextSelection(pmViews[viewId].state.tr.doc.resolve(maxPos.pos - 1)),
chris's avatar
chris committed
    pmViews[viewId].focus();
chris's avatar
chris committed
  const focusOnBlcock = trackData => {
chris's avatar
chris committed
    pmViews[viewId].dispatch(
      pmViews[viewId].state.tr.setSelection(
        new TextSelection(
          pmViews[viewId].state.tr.doc.resolve(trackData.pos + 1),
        ),
chris's avatar
chris committed
      ),
    );

chris's avatar
chris committed
    pmViews[viewId].focus();
chris's avatar
chris committed
    return true;
  };

  useEffect(() => {
    setIsActive(false);
chris's avatar
chris committed
    recalculateTops();
    if (activeTrackChange && trackChangeId === activeTrackChange.attrs.id) {
      setIsActive(true);
    }
  }, [activeTrackChange]);
chris's avatar
chris committed

  const onClickAccept = () => {
chris's avatar
chris committed
    const acceptConfig = app.config.get('config.AcceptTrackChangeService');
chris's avatar
chris committed
    acceptTrackChange(
      dispatch,
      user,
      activeTrackChange,
      acceptConfig,
      context,
      trackChange,
    );
chris's avatar
chris committed
    pmViews[viewId].focus();
  };

  const onClickReject = () => {
chris's avatar
chris committed
    const rejectConfig = app.config.get('config.RejectTrackChangeService');
chris's avatar
chris committed
    rejectTrackChange(
      dispatch,
      user,
      activeTrackChange,
      rejectConfig,
      context,
      trackChange,
    );
chris's avatar
chris committed
    pmViews[viewId].focus();
chris's avatar
chris committed
  const MemorizedTrackChange = useMemo(
    () => (
      <ConnectedTrackChangeStyled
chris's avatar
chris committed
        data-box={trackChangeId}
        style={styles}
      >
        <TrackChangesBox
chris's avatar
chris committed
          key={trackChangeId}
          onClickAccept={onClickAccept}
          onClickBox={onClickBox}
          onClickReject={onClickReject}
chris's avatar
chris committed
          recalculateTops={recalculateTops}
          trackChangeId={trackChangeId}
          trackData={trackChange}
chris's avatar
chris committed
        />
      </ConnectedTrackChangeStyled>
    ),
chris's avatar
chris committed
  );
  return <>{MemorizedTrackChange}</>;
};