Source: reducers/settingsReducers.js

  1. /**
  2. * @module react-cmf/lib/reducers/settingsReducers
  3. */
  4. /* eslint no-underscore-dangle: ["error", {"allow": ["_ref"] }] */
  5. import get from 'lodash/get';
  6. import invariant from 'invariant';
  7. import CONSTANTS from '../constant';
  8. export const defaultState = {
  9. initialized: false,
  10. contentTypes: {},
  11. actions: {},
  12. props: {},
  13. routes: {},
  14. };
  15. /**
  16. * if an object try to find _ref property and resolve it
  17. */
  18. export function attachRef(refs, obj) {
  19. if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
  20. return obj;
  21. }
  22. let props = { ...obj };
  23. if (props._ref) {
  24. invariant(refs[props._ref], `CMF/Settings: Reference '${props._ref}' not found`);
  25. props = { ...refs[props._ref], ...obj };
  26. delete props._ref;
  27. }
  28. return props;
  29. }
  30. export function attachRefs(refs, props) {
  31. const attachedProps = attachRef(refs, props);
  32. Object.keys(attachedProps).forEach(key => {
  33. attachedProps[key] = attachRef(refs, attachedProps[key]);
  34. });
  35. return attachedProps;
  36. }
  37. /**
  38. * attach reference to produce a ready to use freezed object
  39. * @param {object} originalSettings the full settings with `props` and `ref` attribute
  40. * @return {object} frozen settings with ref computed
  41. */
  42. function prepareSettings({ views, props, ref, ...rest }) {
  43. const settings = { props: {}, ...rest };
  44. if (views) {
  45. if (process.env.NODE_ENV === 'development') {
  46. // eslint-disable-next-line no-console
  47. console.warn('settings.view is deprecated, please use settings.props');
  48. }
  49. Object.keys(views).forEach(id => {
  50. settings.props[id] = attachRefs(ref, views[id]);
  51. });
  52. }
  53. if (props) {
  54. Object.keys(props).forEach(id => {
  55. settings.props[id] = attachRefs(ref, props[id]);
  56. });
  57. }
  58. if (typeof settings.freeze === 'function') {
  59. settings.freeze();
  60. }
  61. return settings;
  62. }
  63. /**
  64. * handle actions related to the settings
  65. * @param {object} state initial state
  66. * @param {object} action redux aciton
  67. * @return {object} new state
  68. */
  69. export function settingsReducers(state = defaultState, action) {
  70. switch (action.type) {
  71. case CONSTANTS.REQUEST_OK:
  72. return { ...state, initialized: true, ...prepareSettings(action.settings) };
  73. case CONSTANTS.REQUEST_KO:
  74. // eslint-disable-next-line no-console
  75. console.error(`Settings can't be loaded ${get(action, 'error.message')}`, action.error);
  76. return state;
  77. default:
  78. return state;
  79. }
  80. }
  81. export default settingsReducers;