Advertisement
Guest User

Untitled

a guest
Apr 30th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.74 KB | None | 0 0
  1. import { createAction, handleActions } from 'redux-actions';
  2. import { get, reduce, merge, mergeWith, isArray, omitBy, isEmpty, isEqual } from 'lodash/fp';
  3. import { reduce as reduceNonFP } from 'lodash';
  4.  
  5. import moment from 'moment';
  6. import HashId from '../utils/uid';
  7.  
  8. import {
  9. computedRecords,
  10. } from '../utils/data-transformer';
  11.  
  12. export const databaseRecordsSelector = moduleName => state => computedRecords(get(`database.${moduleName}`, state));
  13. export const rawRecordsSelector = moduleName => state => get(`database.${moduleName}`, state);
  14.  
  15. export const DB_ADD_OR_UPDATE_RECORD = 'database/addOrUpdateRecord';
  16. export const DB_ADD_OR_UPDATE_RECORDS = 'database/addOrUpdateRecords';
  17. export const DB_DELETE_RECORD = 'database/deleteRecord';
  18. export const DB_DELETE_RECORDS = 'database/deleteRecords';
  19.  
  20. export const dbAddOrUpdateRecord = createAction(DB_ADD_OR_UPDATE_RECORD);
  21. export const dbAddOrUpdateRecords = createAction(DB_ADD_OR_UPDATE_RECORDS);
  22. export const dbDeleteRecord = createAction(DB_DELETE_RECORD);
  23. export const dbDeleteRecords = createAction(DB_DELETE_RECORDS);
  24.  
  25.  
  26. const getId = attrs => (attrs.id ? attrs.id : HashId.generateUnique());
  27.  
  28. const mergeProcessor = (stateValue = [], actionCS) => {
  29. switch (actionCS.type) {
  30. case 'replace':
  31. return actionCS.value;
  32. case 'merge':
  33. if (isArray(stateValue) || isArray(actionCS.value)) {
  34. return [...stateValue, ...actionCS.value];
  35. }
  36. console.error("Can't merge changeset");
  37. break;
  38. default:
  39. return stateValue;
  40. }
  41. };
  42.  
  43. const isSame = (d1, d2) => (
  44. moment(d1).toString() === moment(d2).toString()
  45. );
  46.  
  47. const cleanUpRecord = ({ changeset, ...attrs }) => {
  48. const newChangeset = reduceNonFP(changeset, (result, value, key) => {
  49. if (attrs[key]) {
  50. if (moment(value).isValid()) {
  51. if (!isSame(value, attrs[key])) {
  52. return merge({ [key]: value }, result);
  53. }
  54. } else if (!isEqual(value, attrs[key])) {
  55. return merge({ [key]: value }, result);
  56. }
  57. } else {
  58. return merge({ [key]: value }, result);
  59. }
  60.  
  61. return result;
  62. }, {});
  63.  
  64. return {
  65. ...attrs,
  66. changeset: newChangeset,
  67. };
  68. };
  69.  
  70. const addOrUpdateRecord = (state, attrs) => {
  71. const module = attrs.moduleName;
  72. const recordId = getId(attrs);
  73. const stateModuleAttrs = get(`${module}.${recordId}`, state);
  74. const stateModuleChangeset = get(`${module}.${recordId}.changeset`, state);
  75.  
  76. const record = cleanUpRecord({
  77. ...stateModuleAttrs,
  78. ...attrs,
  79. changeset: mergeWith(
  80. mergeProcessor,
  81. stateModuleChangeset,
  82. attrs.changeset,
  83. ),
  84. });
  85.  
  86. return {
  87. ...state,
  88. [module]: {
  89. ...state[module],
  90. [recordId]: record,
  91. },
  92. };
  93. };
  94.  
  95. const deleteRecord = (state, attrs) => {
  96. const module = attrs.moduleName;
  97. const recordId = getId(attrs);
  98. const stateModuleAttrs = get(`${module}.${recordId}`, state);
  99.  
  100. return {
  101. ...state,
  102. [module]: {
  103. ...state[module],
  104. [recordId]: {
  105. ...stateModuleAttrs,
  106. deleted: true,
  107. },
  108. },
  109. };
  110. };
  111.  
  112. const filterEmptyChange = payload => (
  113. omitBy(({ changeset, ...others }) => (
  114. isEmpty(changeset) && isEmpty(others)
  115. ), payload)
  116. );
  117.  
  118. const addOrUpdateRecords = (state, { payload }) =>
  119. reduce((result, attrs) => addOrUpdateRecord(result, attrs), state, filterEmptyChange(payload));
  120.  
  121. const deleteRecords = (state, { payload }) =>
  122. reduce((result, attrs) => deleteRecord(result, attrs), state, filterEmptyChange(payload));
  123.  
  124. const database = handleActions({
  125. [DB_ADD_OR_UPDATE_RECORDS]: addOrUpdateRecords,
  126. [DB_ADD_OR_UPDATE_RECORD]: (state, { payload }) => addOrUpdateRecords(state, { payload: [payload] }),
  127. [DB_DELETE_RECORD]: (state, { payload }) => deleteRecords(state, { payload: [payload] }),
  128. [DB_DELETE_RECORDS]: deleteRecords,
  129. }, {});
  130.  
  131. export default { database };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement