You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

reducer.js 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // @flow
  2. import _ from 'lodash';
  3. import { ReducerRegistry } from '../base/redux';
  4. import {
  5. INIT_SEARCH,
  6. UPDATE_STATS,
  7. INIT_REORDER_STATS
  8. } from './actionTypes';
  9. /**
  10. * The initial state of the feature speaker-stats.
  11. *
  12. * @type {Object}
  13. */
  14. const INITIAL_STATE = {
  15. stats: {},
  16. pendingReorder: true,
  17. criteria: null
  18. };
  19. ReducerRegistry.register('features/speaker-stats', (state = _getInitialState(), action) => {
  20. switch (action.type) {
  21. case INIT_SEARCH:
  22. return _updateCriteria(state, action);
  23. case UPDATE_STATS:
  24. return _updateStats(state, action);
  25. case INIT_REORDER_STATS:
  26. return _initReorderStats(state);
  27. }
  28. return state;
  29. });
  30. /**
  31. * Gets the initial state of the feature speaker-stats.
  32. *
  33. * @returns {Object}
  34. */
  35. function _getInitialState() {
  36. return INITIAL_STATE;
  37. }
  38. /**
  39. * Reduces a specific Redux action INIT_SEARCH of the feature
  40. * speaker-stats.
  41. *
  42. * @param {Object} state - The Redux state of the feature speaker-stats.
  43. * @param {Action} action - The Redux action INIT_SEARCH to reduce.
  44. * @private
  45. * @returns {Object} The new state after the reduction of the specified action.
  46. */
  47. function _updateCriteria(state, { criteria }) {
  48. return _.assign(
  49. {},
  50. state,
  51. { criteria },
  52. );
  53. }
  54. /**
  55. * Reduces a specific Redux action UPDATE_STATS of the feature
  56. * speaker-stats.
  57. * The speaker stats order is based on the stats object properties.
  58. * When updating without reordering, the new stats object properties are reordered
  59. * as the last in state, otherwise the order would be lost on each update.
  60. * If there was already a pending reorder, the stats object properties already have
  61. * the correct order, so the property order is not changing.
  62. *
  63. * @param {Object} state - The Redux state of the feature speaker-stats.
  64. * @param {Action} action - The Redux action UPDATE_STATS to reduce.
  65. * @private
  66. * @returns {Object} - The new state after the reduction of the specified action.
  67. */
  68. function _updateStats(state, { stats }) {
  69. const finalStats = state.pendingReorder ? stats : state.stats;
  70. if (!state.pendingReorder) {
  71. // Avoid reordering the speaker stats object properties
  72. const finalKeys = Object.keys(stats);
  73. finalKeys.forEach(newStatId => {
  74. finalStats[newStatId] = _.clone(stats[newStatId]);
  75. });
  76. Object.keys(finalStats).forEach(key => {
  77. if (!finalKeys.includes(key)) {
  78. delete finalStats[key];
  79. }
  80. });
  81. }
  82. return _.assign(
  83. {},
  84. state,
  85. {
  86. stats: { ...finalStats },
  87. pendingReorder: false
  88. },
  89. );
  90. }
  91. /**
  92. * Reduces a specific Redux action INIT_REORDER_STATS of the feature
  93. * speaker-stats.
  94. *
  95. * @param {Object} state - The Redux state of the feature speaker-stats.
  96. * @private
  97. * @returns {Object} The new state after the reduction of the specified action.
  98. */
  99. function _initReorderStats(state) {
  100. return _.assign(
  101. {},
  102. state,
  103. { pendingReorder: true },
  104. );
  105. }