"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.assignNodeProperties = assignNodeProperties; exports.elementsReducer = void 0; var _reduxActions = require("redux-actions"); var _objectPathImmutable = _interopRequireDefault(require("object-path-immutable")); var _lodash = require("lodash"); var actions = _interopRequireWildcard(require("../actions/elements")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ const { assign, push, del, set } = _objectPathImmutable.default; const getLocation = type => type === 'group' ? 'groups' : 'elements'; const firstOccurrence = (element, index, array) => array.indexOf(element) === index; const getLocationFromIds = (workpadState, pageId, nodeId) => { const page = workpadState.pages.find(p => p.id === pageId); const groups = page == null ? [] : page.groups || []; return groups.find(e => e.id === nodeId) ? 'groups' : 'elements'; }; function getPageIndexById(workpadState, pageId) { return (0, _lodash.get)(workpadState, 'pages', []).findIndex(page => page.id === pageId); } function getNodeIndexById(page, nodeId, location) { return page[location].findIndex(node => node.id === nodeId); } function assignNodeProperties(workpadState, pageId, nodeId, props) { const pageIndex = getPageIndexById(workpadState, pageId); const location = getLocationFromIds(workpadState, pageId, nodeId); const nodesPath = `pages.${pageIndex}.${location}`; const nodeIndex = (0, _lodash.get)(workpadState, nodesPath, []).findIndex(node => node.id === nodeId); if (pageIndex === -1 || nodeIndex === -1) { return workpadState; } return assign(workpadState, `${nodesPath}.${nodeIndex}`, props); } function moveNodeLayer(workpadState, pageId, nodeId, movement, location) { const pageIndex = getPageIndexById(workpadState, pageId); const nodeIndex = getNodeIndexById(workpadState.pages[pageIndex], nodeId, location); const nodes = (0, _lodash.get)(workpadState, ['pages', pageIndex, location]); const from = nodeIndex; const to = function () { if (movement < Infinity && movement > -Infinity) { return nodeIndex + movement; } if (movement === Infinity) { return nodes.length - 1; } if (movement === -Infinity) { return 0; } throw new Error('Invalid element layer movement'); }(); if (to > nodes.length - 1 || to < 0) { return workpadState; } // Common const newNodes = nodes.slice(0); newNodes.splice(to, 0, newNodes.splice(from, 1)[0]); return set(workpadState, `pages.${pageIndex}.${location}`, newNodes); } const trimPosition = ({ left, top, width, height, angle, parent }) => ({ left, top, width, height, angle, parent }); const trimElement = ({ id, position, expression, filter }) => ({ id, position: trimPosition(position), ...(position.type !== 'group' && { expression }), ...(filter !== void 0 && { filter }) }); const getPageWithElementId = (workpad, elementId) => { const matchingPage = workpad.pages.find(page => page.elements.map(element => element.id).includes(elementId)); if (matchingPage) { return matchingPage.id; } return undefined; }; const elementsReducer = (0, _reduxActions.handleActions)({ // TODO: This takes the entire element, which is not necessary, it could just take the id. [actions.setExpression]: (workpadState, { payload }) => { const { expression, pageId, elementId } = payload; return assignNodeProperties(workpadState, pageId, elementId, { expression }); }, [actions.setFilter]: (workpadState, { payload }) => { const { filter, elementId } = payload; const pageId = getPageWithElementId(workpadState, elementId); return assignNodeProperties(workpadState, pageId, elementId, { filter }); }, [actions.setMultiplePositions]: (workpadState, { payload }) => payload.repositionedElements.reduce((previousWorkpadState, { position, pageId, elementId }) => assignNodeProperties(previousWorkpadState, pageId, elementId, { position: trimPosition(position) }), workpadState), [actions.elementLayer]: (workpadState, { payload: { pageId, elementId, movement } }) => { const location = getLocationFromIds(workpadState, pageId, elementId); return moveNodeLayer(workpadState, pageId, elementId, movement, location); }, [actions.addElement]: (workpadState, { payload: { pageId, element } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; } if ( // don't add a group that is already persisted workpadState.pages[pageIndex][getLocation(element.position.type)].find(e => e.id === element.id)) { return workpadState; } return push(workpadState, `pages.${pageIndex}.${getLocation(element.position.type)}`, trimElement(element)); }, [actions.insertNodes]: (workpadState, { payload: { pageId, elements } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; } return elements.reduce((state, element) => push(state, `pages.${pageIndex}.${getLocation(element.position.type)}`, trimElement(element)), workpadState); }, [actions.removeElements]: (workpadState, { payload: { pageId, elementIds } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; } const nodeIndices = elementIds.filter(firstOccurrence).map(nodeId => { const location = getLocationFromIds(workpadState, pageId, nodeId); return { location, index: getNodeIndexById(workpadState.pages[pageIndex], nodeId, location) }; }).sort((a, b) => b.index - a.index); // deleting from end toward beginning, otherwise indices will become off - todo fuse loops! return nodeIndices.reduce((state, { location, index }) => { return del(state, `pages.${pageIndex}.${location}.${index}`); }, workpadState); } }, {}); exports.elementsReducer = elementsReducer;