@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
JavaScript
;
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