huridocs/uwazi

View on GitHub
app/react/Viewer/actions/documentActions.js

Summary

Maintainability
A
0 mins
Test Coverage
A
94%
import { omit } from 'lodash';
import api from 'app/utils/api';
import referencesAPI from 'app/Viewer/referencesAPI';
import * as types from 'app/Viewer/actions/actionTypes';
import * as connectionsTypes from 'app/Connections/actions/actionTypes';
import { entityDefaultDocument } from 'shared/entityDefaultDocument';

import { actions } from 'app/BasicReducer';
import { actions as formActions } from 'react-redux-form';
import { documentsApi } from 'app/Documents';
import { notificationActions } from 'app/Notifications';
import { removeDocument, unselectAllDocuments } from 'app/Library/actions/libraryActions';
import { actions as relationshipActions } from 'app/Relationships';
import { RequestParams } from 'app/utils/RequestParams';
import { closePanel as closeConnectionPanel } from 'app/Connections/actions/uiActions.js';
import { saveEntityWithFiles } from '../../Library/actions/saveEntityWithFiles';
import * as selectionActions from './selectionActions';
import * as uiActions from './uiActions';
import { sortTextSelections } from '../utils/sortTextSelections';
import EntitiesApi from '../../Entities/EntitiesAPI';

function getEntityDoc(entity, filename, defaultLanguage) {
  let docByFilename = entity.documents.find(d => d.filename === filename);
  docByFilename = docByFilename !== undefined ? docByFilename : {};

  const defaultDoc = entityDefaultDocument(entity.documents, entity.language, defaultLanguage);

  return filename ? docByFilename : defaultDoc;
}

const dispatchUpdatedDocument = (dispatch, doc, updatedDoc, entityFileId) => {
  dispatch(notificationActions.notify('Document updated', 'success'));
  dispatch({ type: types.VIEWER_UPDATE_DOCUMENT, doc });
  dispatch(formActions.reset('documentViewer.sidepanel.metadata'));
  const defaultDoc = updatedDoc.entity.documents.find(document => document._id === entityFileId);
  dispatch(actions.update('viewer/doc', { ...updatedDoc.entity, defaultDoc }));
  dispatch(relationshipActions.reloadRelationships(updatedDoc.entity.sharedId));
};

export function setDocument(document, html) {
  return {
    type: types.SET_DOCUMENT,
    document,
    html,
  };
}

export function resetDocumentViewer() {
  return {
    type: types.RESET_DOCUMENT_VIEWER,
  };
}

export function loadDefaultViewerMenu() {
  return {
    type: types.LOAD_DEFAULT_VIEWER_MENU,
  };
}
export function saveDocument(doc, fileID) {
  const updateDoc = omit(doc, 'fullText', 'defaultDoc');
  return async (dispatch, getState) => {
    const extractredMetadata = getState().documentViewer.metadataExtraction.toJS();
    const entityFileId = fileID || getState().documentViewer.doc.toJS().defaultDoc._id;
    updateDoc.__extractedMetadata = { fileID: entityFileId, ...extractredMetadata };
    const updatedDoc = await saveEntityWithFiles(updateDoc, dispatch);

    dispatchUpdatedDocument(dispatch, doc, updatedDoc, entityFileId);
    return updateDoc;
  };
}

export function saveToc(toc, fileId) {
  return async (dispatch, getState) => {
    const currentDoc = getState().documentViewer.doc.toJS();
    dispatch(formActions.reset('documentViewer.sidepanel.metadata'));
    dispatch(actions.set('documentViewer/tocBeingEdited', false));

    const updatedFile = (await api.post('files', new RequestParams({ toc, _id: fileId }))).json;
    const doc = {
      ...currentDoc,
      defaultDoc: updatedFile,
      documents: currentDoc.documents.map(d => {
        if (d._id === updatedFile._id) {
          return updatedFile;
        }
        return d;
      }),
    };

    dispatch(notificationActions.notify('Document updated', 'success'));
    dispatch({ type: types.VIEWER_UPDATE_DOCUMENT, doc });
    dispatch(formActions.reset('documentViewer.sidepanel.metadata'));
    dispatch(actions.set('viewer/doc', doc));
  };
}

export function deleteDocument(doc) {
  return async dispatch => {
    await documentsApi.delete(new RequestParams({ sharedId: doc.sharedId }));
    dispatch(notificationActions.notify('Document deleted', 'success'));
    dispatch(resetDocumentViewer());
    dispatch(removeDocument(doc));
    await dispatch(unselectAllDocuments());
  };
}

export async function getDocument(requestParams, defaultLanguage, filename) {
  const [entity] = await EntitiesApi.get(requestParams.add({ omitRelationships: true }));

  entity.defaultDoc = getEntityDoc(entity, filename, defaultLanguage);
  return entity;
}

export function loadTargetDocument(sharedId) {
  return (dispatch, getState) =>
    getDocument(new RequestParams({ sharedId }), getState().locale).then(entity => {
      dispatch(actions.set('viewer/targetDoc', entity));
      return referencesAPI
        .get(new RequestParams({ sharedId, file: entity.defaultDoc._id, onlyTextReferences: true }))
        .then(references => {
          dispatch(actions.set('viewer/targetDocReferences', references));
        });
    });
}

export function reloadDocument(sharedId) {
  return (dispatch, getState) =>
    Promise.all([
      getDocument(new RequestParams({ sharedId }), getState().locale),
      referencesAPI.get(new RequestParams({ sharedId })),
    ]).then(([targetDoc, references]) => {
      dispatch(actions.set('viewer/doc', targetDoc));
      dispatch(actions.set('viewer/references', references));
    });
}

export function cancelTargetDocument() {
  return dispatch => {
    dispatch({ type: connectionsTypes.CANCEL_RANGED_CONNECTION });
    dispatch(actions.unset('viewer/targetDoc'));
    dispatch(actions.unset('viewer/targetDocReferences'));
    dispatch(selectionActions.unsetTargetSelection());
    dispatch(uiActions.openPanel('viewMetadataPanel'));
  };
}

export function editToc(toc) {
  return dispatch => {
    dispatch(closeConnectionPanel());
    dispatch(actions.set('documentViewer/tocBeingEdited', true));
    dispatch(formActions.load('documentViewer.tocForm', toc));
    dispatch(uiActions.openPanel('viewMetadataPanel'));
    dispatch(actions.set('viewer.sidepanel.tab', 'toc'));
  };
}

export function leaveEditMode() {
  return dispatch => {
    dispatch(actions.set('documentViewer/tocBeingEdited', false));
    dispatch(formActions.reset('documentViewer.sidepanel.metadata'));
  };
}

export function removeFromToc(tocElement) {
  return (dispatch, getState) => {
    const state = getState();
    let toc = state.documentViewer.tocForm;

    toc = toc.filter(entry => entry !== tocElement);

    dispatch(formActions.load('documentViewer.tocForm', toc));
  };
}

export function indentTocElement(tocElement, indentation) {
  return (dispatch, getState) => {
    const state = getState();
    const toc = state.documentViewer.tocForm.map(entry => ({
      ...entry,
      ...(entry === tocElement ? { indentation } : {}),
    }));

    dispatch(formActions.load('documentViewer.tocForm', toc));
  };
}

export function addToToc(textSelectedObject, currentToc) {
  return (dispatch, getState) => {
    const state = getState();
    let toc = state.documentViewer.tocForm.concat();
    if (!toc.length) {
      toc = currentToc;
    }
    const tocElement = {
      selectionRectangles: textSelectedObject.sourceRange.selectionRectangles,
      label: textSelectedObject.sourceRange.text,
      indentation: 0,
    };

    toc.push(tocElement);
    toc = toc.sort(sortTextSelections);
    dispatch(editToc(toc));
  };
}