Source: action.js

import get from 'lodash/get';
import deprecated from './deprecated';
import actionCreatorAPI from './actionCreator';

/**
 * This module is DEPRECATED and will be removed in future version.
 * it provide low level api to register and handle action in a CMF App.
 * @module react-cmf/lib/action
 * @see module:react-cmf/lib/Dispatcher
 */

/**
 * get the global actions registered in the settings
 * @param  {object} context
 * @return {object} actions with key === action id
 */
function getActionsById(context) {
	const state = context.store.getState();
	return get(state, 'cmf.settings.actions', {});
}

/**
 * return actions registered for a given content type
 * @param  {object} context
 * @param  {String} contentType
 * @param  {String} category
 * @return {Array} actions
 */
function getContentTypeActions(context, contentType, category) {
	const state = context.store.getState();
	return get(state, `cmf.settings.contentTypes[${contentType}.actions[${category}]`, []);
}

/**
 * Return information available about this action
 * @param  {object} context
 * @param  {String} id
 * @return {object}
 */
function getActionInfo(context, id) {
	const action = getActionsById(context)[id];
	if (!action) {
		throw new Error(`action not found id: ${id}`);
	}
	return { ...action };
}

/**
 * Return the action object ready to be dispatched
 * This is supposed to be used outside of content type
 * @param  {object} context
 * @param  {String|Object} action or the action
 * @param  {object} event event which have trigger this action
 * @param  {object} data data attached to the action
 */
function getActionObject(context, action, event, data) {
	let actionInfo;
	if (typeof action === 'string') {
		actionInfo = getActionInfo(context, action);
	} else {
		actionInfo = action;
	}
	if (actionInfo.actionCreator) {
		const actionCreator = actionCreatorAPI.get(context, actionInfo.actionCreator);
		return actionCreator(event, data, {
			store: context.store,
			getState: context.store.getState,
			registry: context.registry,
			actionInfo,
		});
	}
	return { ...actionInfo.payload, event, data, context };
}

/**
 * return every props name that start with 'on'
 * @param  {object} props react props
 * @return {Array}       of string
 */
function getOnProps(props) {
	return Object.keys(props).filter(
		name => ({}).hasOwnProperty.call(props, name) && /^on.+/.test(name),
	);
}

/**
 * create a map dispatchable action function expecting event object, props, and context information
 * merge this map with non event properties
 * @param  {Function} dispatch the dispatch function
 * @param  {object} props    props object containing maybe on(event) with string
 *                           or action creator function]
 * @return {object}          the connected object
 * @throws if an action is unknown in configuration, throw
 */
function mapDispatchToProps(dispatch, props) {
	const resolvedActions = {};
	getOnProps(props).forEach(name => {
		resolvedActions[name] = (event, data, context) => {
			let action = props[name];
			if (typeof action === 'string') {
				action = getActionObject(context, action, event, data);
			}
			dispatch(action);
		};
	});
	return { ...props, ...resolvedActions };
}

const registerActionCreator = deprecated(
	(id, actionCreator, context) => actionCreatorAPI.register(id, actionCreator, context),
	'stop use cmf.action.registerActionCreator. please use cmf.actionCreator.register',
);

const getActionCreatorFunction = deprecated(
	(context, id) => actionCreatorAPI.get(context, id),
	'stop use cmf.action.getActionCreatorFunction. please use cmf.actionCreator.get',
);

export default {
	getActionsById,
	getActionCreatorFunction,
	getActionInfo,
	getActionObject,
	getContentTypeActions,
	getOnProps,
	mapDispatchToProps,
	registerActionCreator,
};