UNPKG

@talend/react-containers

Version:

Provide connected components aka containers for @talend/react-cmf based on @talend/react-components.

181 lines (175 loc) 6.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.mapStateToProps = mapStateToProps; exports.mergeProps = mergeProps; var _reactCmf = _interopRequireWildcard(require("@talend/react-cmf")); var _constants = require("./constants"); var _SidePanel = _interopRequireWildcard(require("./SidePanel.container")); var _lodash = require("lodash"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const cache = {}; /** * return the cache structure to support one cache per componentId * @param componentId used to create entry in the cache * @param currentRoute used as cache key * @param actions the current actions used as cacheKey by reference */ function getCache(componentId = 'default', currentRoute, actions) { if (!cache[componentId]) { cache[componentId] = {}; } if (cache[componentId].route !== currentRoute || cache[componentId].actions !== actions) { // invalidate the cache cache[componentId] = { route: currentRoute, actions }; } return cache[componentId]; } /** * This function check if our current action point to a route which is the parent of the current * @param {string} actionPath the path of the action * @param {string} currentPath the pathname in the browser location */ function isBasePathOf(actionPath, currentPath) { const length = actionPath.length; if (currentPath.length + 1 === length) { return `${currentPath}/` === actionPath; } if (currentPath.length === length) { return currentPath === actionPath; } if (currentPath.length < length) { return false; } return actionPath === currentPath.slice(0, length) && ['/', '#'].includes(currentPath[length]); } /** * This function use on each action the attribute href to build the onClick * @param {Array} actions the list of all Action props you want. * @return a new actions Array ready to be used by the SidePanel */ function getActionsWrapped(actions) { return actions.map(action => { if (action.href && !action.onClick && !action.onClickDispatch && !action.onClickActionCreator) { return { ...action, onClick: event => { if (!event.metaKey && !event.ctrlKey) { event.preventDefault(); event.stopPropagation(); } }, onClickDispatch: { type: _constants.ACTION_TYPE_LINK, cmf: { routerPush: action.href } } }; } return action; }); } function getSelectedAction(currentRoute, actions) { const getFullPath = href => { if (!window.basename || window.basename === '/' || href.startsWith(window.basename)) { return href; } return `${window.basename || ''}${href}`.replaceAll('//', '/'); }; return actions.find(action => action.href && isBasePathOf(getFullPath(action.href), currentRoute)); } /** * DEPRECATED: This is kept to not create any breaking change. * This function use the deprecated api `cmf.action.getActionInfo` * @param {string} id the action id you want to get in your settings * @param {string} currentRoute the pathname in the browser location * @param {Object} state redux state to create fake context for getActionInfo * @return a new actions Array ready to be used by the SidePanel */ function getAction(id, currentRoute, state) { const action = { actionId: id }; const info = _reactCmf.default.action.getActionInfo({ registry: _reactCmf.default.registry.getRegistry(), store: { getState: () => state } }, id); action.label = info.label; action.id = info.id; const route = (0, _lodash.get)(info, 'payload.cmf.routerReplace', (0, _lodash.get)(info, 'payload.cmf.routerPush', (0, _lodash.get)(info, 'href'))); if (route && isBasePathOf(route, currentRoute)) { action.active = true; } return action; } /** * This function take care of perfomance to ensure we give the same array of actions * if we are on the same route for the same component with the same props * @param {Object} state the redux state * @param {Object} ownProps the props applied to the current component instance * @param {string} currentRoute the pathname in the browser location * @return {Array} array of actions ready for the sidepanel and cached to keep good performance */ function getActions(state, ownProps, currentRoute) { if (ownProps.actions) { let actions = ownProps.actions; if (window.basename && window.basename !== '/') { actions = ownProps.actions.map(action => ({ ...action, href: `${window.basename}${action.href}`.replaceAll('//', '/') })); } const cacheAction = getCache(ownProps.componentId, currentRoute, actions); if (!cacheAction.value) { cacheAction.value = getActionsWrapped(actions); } return cacheAction.value; } else if (ownProps.actionIds) { const cacheAction = getCache(ownProps.componentId, currentRoute, ownProps.actionIds); if (!cacheAction.value) { cacheAction.value = ownProps.actionIds.map(id => getAction(id, currentRoute, state)); } return cacheAction.value; } return undefined; } function mapStateToProps(state, ownProps) { const props = {}; const currentRoute = window.location.pathname; props.actions = getActions(state, ownProps, currentRoute); if (ownProps.actions) { props.selected = getSelectedAction(currentRoute, props.actions); } return props; } function mergeProps(stateProps, dispatchProps, ownProps) { const props = { ...ownProps, ...stateProps, ...dispatchProps }; if (props.actionIds) { delete props.actionIds; } return props; } var _default = exports.default = (0, _reactCmf.cmfConnect)({ defaultState: _SidePanel.DEFAULT_STATE, omitCMFProps: true, withComponentRegistry: true, withDispatch: true, withDispatchActionCreator: true, withComponentId: true, keepComponentState: true, mapStateToProps, mergeProps })(_SidePanel.default); //# sourceMappingURL=SidePanel.connect.js.map