<commit_before>import { generateId, isValidIdentifier } from 'xod-project';

import { addError } from '../messages/actions';
import { PROJECT_BROWSER_ERRORS } from '../messages/constants';
import * as ActionType from './actionTypes';
import { isPatchPathTaken } from './utils';
import { getCurrentPatchPath } from '../editor/selectors';

export const createProject = projectName => (dispatch) => {
  if (!isValidIdentifier(projectName)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.INVALID_PROJECT_NAME));
  }

  return dispatch({
    type: ActionType.PROJECT_CREATE,
    payload: {
      name: projectName,
      mainPatchPath: '@/main',
    },
  });
};

export const addNode = (typeId, position, patchPath) => (dispatch) => {
  const newNodeId = generateId();

  dispatch({
    type: ActionType.NODE_ADD,
    payload: {
      typeId,
      position,
      newNodeId,
      patchPath,
    },
  });

  return newNodeId;
};

export const deleteNode = id => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.NODE_DELETE,
    payload: {
      id,
      patchPath,
    },
  });
};

export const moveNode = (id, position) => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.NODE_MOVE,
    payload: {
      id,
      position,
      patchPath,
    },
  });
};

export const addLink = (pin1, pin2) => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.LINK_ADD,
    payload: {
      patchPath,
      pins: [pin1, pin2],
    },
  });
};

export const deleteLink = (id, patchPath) => ({
  type: ActionType.LINK_DELETE,
  payload: {
    id,
    patchPath,
  },
});

export const updateNodeProperty =
  (nodeId, propKind, propKey, propValue) => (dispatch, getState) => {
    const patchPath = getCurrentPatchPath(getState());

    dispatch({
      type: ActionType.NODE_UPDATE_PROPERTY,
      payload: {
        id: nodeId,
        kind: propKind,
        key: propKey,
        value: propValue,
        patchPath,
      },
    });
  };

export const openProject = project => ({
  type: ActionType.PROJECT_OPEN,
  payload: project,
});

export const importProject = json => ({
  type: ActionType.PROJECT_IMPORT,
  payload: json,
});

export const openWorkspace = libs => ({
  type: ActionType.PROJECT_OPEN_WORKSPACE,
  payload: libs,
});

export const undoPatch = patchPath => ({
  type: ActionType.PATCH_HISTORY_UNDO,
  payload: { patchPath },
});

export const redoPatch = patchPath => ({
  type: ActionType.PATCH_HISTORY_REDO,
  payload: { patchPath },
});

export const addPatch = baseName => (dispatch, getState) => {
  if (!isValidIdentifier(baseName)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.INVALID_PATCH_NAME));
  }

  const state = getState();
  const newPatchPath = `@/${baseName}`;

  if (isPatchPathTaken(state, newPatchPath)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.PATCH_NAME_TAKEN));
  }

  return dispatch({
    type: ActionType.PATCH_ADD,
    payload: {
      patchPath: newPatchPath,
    },
  });
};

export const renamePatch = (oldPatchPath, newBaseName) => (dispatch, getState) => {
  const newPatchPath = `@/${newBaseName}`; // TODO: prepare for '@@'?
  const state = getState();

  if (
    newPatchPath !== oldPatchPath &&
    isPatchPathTaken(state, newPatchPath)
  ) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.PATCH_NAME_TAKEN));
  }

  return dispatch({
    type: ActionType.PATCH_RENAME,
    payload: {<commit_msg>tweak(xod-client): make local path with an util from xod-project instead of hardcoding<commit_after>import { generateId, isValidIdentifier, getLocalPath } from 'xod-project';

import { addError } from '../messages/actions';
import { PROJECT_BROWSER_ERRORS } from '../messages/constants';
import * as ActionType from './actionTypes';
import { isPatchPathTaken } from './utils';
import { getCurrentPatchPath } from '../editor/selectors';

export const createProject = projectName => (dispatch) => {
  if (!isValidIdentifier(projectName)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.INVALID_PROJECT_NAME));
  }

  return dispatch({
    type: ActionType.PROJECT_CREATE,
    payload: {
      name: projectName,
      mainPatchPath: getLocalPath('main'),
    },
  });
};

export const addNode = (typeId, position, patchPath) => (dispatch) => {
  const newNodeId = generateId();

  dispatch({
    type: ActionType.NODE_ADD,
    payload: {
      typeId,
      position,
      newNodeId,
      patchPath,
    },
  });

  return newNodeId;
};

export const deleteNode = id => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.NODE_DELETE,
    payload: {
      id,
      patchPath,
    },
  });
};

export const moveNode = (id, position) => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.NODE_MOVE,
    payload: {
      id,
      position,
      patchPath,
    },
  });
};

export const addLink = (pin1, pin2) => (dispatch, getState) => {
  const patchPath = getCurrentPatchPath(getState());

  dispatch({
    type: ActionType.LINK_ADD,
    payload: {
      patchPath,
      pins: [pin1, pin2],
    },
  });
};

export const deleteLink = (id, patchPath) => ({
  type: ActionType.LINK_DELETE,
  payload: {
    id,
    patchPath,
  },
});

export const updateNodeProperty =
  (nodeId, propKind, propKey, propValue) => (dispatch, getState) => {
    const patchPath = getCurrentPatchPath(getState());

    dispatch({
      type: ActionType.NODE_UPDATE_PROPERTY,
      payload: {
        id: nodeId,
        kind: propKind,
        key: propKey,
        value: propValue,
        patchPath,
      },
    });
  };

export const openProject = project => ({
  type: ActionType.PROJECT_OPEN,
  payload: project,
});

export const importProject = json => ({
  type: ActionType.PROJECT_IMPORT,
  payload: json,
});

export const openWorkspace = libs => ({
  type: ActionType.PROJECT_OPEN_WORKSPACE,
  payload: libs,
});

export const undoPatch = patchPath => ({
  type: ActionType.PATCH_HISTORY_UNDO,
  payload: { patchPath },
});

export const redoPatch = patchPath => ({
  type: ActionType.PATCH_HISTORY_REDO,
  payload: { patchPath },
});

export const addPatch = baseName => (dispatch, getState) => {
  if (!isValidIdentifier(baseName)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.INVALID_PATCH_NAME));
  }

  const state = getState();
  const newPatchPath = getLocalPath(baseName);

  if (isPatchPathTaken(state, newPatchPath)) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.PATCH_NAME_TAKEN));
  }

  return dispatch({
    type: ActionType.PATCH_ADD,
    payload: {
      patchPath: newPatchPath,
    },
  });
};

export const renamePatch = (oldPatchPath, newBaseName) => (dispatch, getState) => {
  const newPatchPath = getLocalPath(newBaseName);
  const state = getState();

  if (
    newPatchPath !== oldPatchPath &&
    isPatchPathTaken(state, newPatchPath)
  ) {
    return dispatch(addError(PROJECT_BROWSER_ERRORS.PATCH_NAME_TAKEN));
  }

  return dispatch({
    type: ActionType.PATCH_RENAME,
    payload: {
{'fraction_non_alphanumeric': 0.13281682346430548, 'fraction_numerical': 0.0011068068622025456, 'mean_word_length': 3.5379786566227245, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '358119', 'n_tokens_mistral': 2341, 'n_tokens_neox': 2318, 'n_words': 499}