reducer.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import produce from 'immer'
  21. import { ActionTypes } from './constants'
  22. import { VizActionType } from './actions'
  23. import { IVizState, ISlideFormed } from './types'
  24. import { LOCATION_CHANGE, LocationChangeAction } from 'connected-react-router'
  25. import { matchPortalPath, matchDisplaySlidePath } from 'utils/router'
  26. const initialState: IVizState = {
  27. portals: [],
  28. displays: [],
  29. portalDashboards: {},
  30. displaySlides: {},
  31. currentPortalId: 0,
  32. currentDisplay: null,
  33. currentSlide: null,
  34. loading: {
  35. portal: false,
  36. display: false,
  37. editing: false,
  38. dashboards: false,
  39. slides: false
  40. }
  41. }
  42. const vizReducer = (
  43. state = initialState,
  44. action: VizActionType | LocationChangeAction
  45. ) =>
  46. produce(state, (draft: IVizState) => {
  47. let displayId: number
  48. let slide: ISlideFormed
  49. let slides: ISlideFormed[]
  50. let slideId: number
  51. switch (action.type) {
  52. case ActionTypes.LOAD_PORTALS:
  53. draft.loading.portal = true
  54. break
  55. case ActionTypes.LOAD_PORTALS_SUCCESS:
  56. draft.portals = action.payload.result
  57. draft.loading.portal = false
  58. break
  59. case ActionTypes.LOAD_PORTALS_FAILURE:
  60. draft.loading.portal = false
  61. break
  62. case ActionTypes.ADD_PORTAL:
  63. draft.loading.editing = true
  64. break
  65. case ActionTypes.ADD_PORTAL_SUCCESS:
  66. draft.portals.unshift(action.payload.result)
  67. draft.loading.editing = false
  68. break
  69. case ActionTypes.ADD_PORTAL_FAILURE:
  70. draft.loading.editing = false
  71. break
  72. case ActionTypes.DELETE_PORTAL:
  73. break
  74. case ActionTypes.DELETE_PORTAL_SUCCESS:
  75. draft.portals = draft.portals.filter((g) => g.id !== action.payload.id)
  76. break
  77. case ActionTypes.DELETE_PORTAL_FAILURE:
  78. break
  79. case ActionTypes.EDIT_PORTAL:
  80. draft.loading.editing = true
  81. break
  82. case ActionTypes.EDIT_PORTAL_SUCCESS:
  83. draft.portals.splice(
  84. draft.portals.findIndex((g) => g.id === action.payload.result.id),
  85. 1,
  86. action.payload.result
  87. )
  88. draft.loading.editing = false
  89. break
  90. case ActionTypes.EDIT_PORTAL_FAILURE:
  91. draft.loading.editing = true
  92. break
  93. case ActionTypes.LOAD_PORTAL_DASHBOARDS:
  94. draft.loading.dashboards = true
  95. break
  96. case ActionTypes.LOAD_PORTAL_DASHBOARDS_SUCCESS:
  97. draft.portalDashboards[action.payload.portalId] =
  98. action.payload.dashboards
  99. draft.loading.dashboards = false
  100. if (!draft.currentPortalId) {
  101. draft.currentPortalId = action.payload.portalId
  102. }
  103. break
  104. case ActionTypes.LOAD_PORTAL_DASHBOARDS_FAILURE:
  105. delete draft.portalDashboards[action.payload.portalId]
  106. draft.loading.dashboards = false
  107. break
  108. case ActionTypes.ADD_DASHBOARD:
  109. draft.loading.editing = true
  110. break
  111. case ActionTypes.ADD_DASHBOARD_SUCCESS:
  112. draft.portalDashboards[action.payload.result.dashboardPortalId].push(
  113. action.payload.result
  114. )
  115. draft.loading.editing = false
  116. break
  117. case ActionTypes.ADD_DASHBOARD_FAILURE:
  118. draft.loading.editing = false
  119. break
  120. case ActionTypes.EDIT_DASHBOARD:
  121. draft.loading.editing = true
  122. break
  123. case ActionTypes.EDIT_DASHBOARD_SUCCESS:
  124. const { result, formType } = action.payload
  125. if (formType === 'edit') {
  126. result.forEach((r) => {
  127. draft.portalDashboards[r.dashboardPortalId].splice(
  128. draft.portalDashboards[r.dashboardPortalId].findIndex(
  129. (d) => d.id === r.id
  130. ),
  131. 1,
  132. r
  133. )
  134. })
  135. } else if (formType === 'move') {
  136. draft.portalDashboards[
  137. result[0].dashboardPortalId
  138. ] = draft.portalDashboards[result[0].dashboardPortalId].filter(
  139. (d) => result.findIndex(({ id }) => id === d.id) < 0
  140. )
  141. draft.portalDashboards[
  142. result[0].dashboardPortalId
  143. ] = draft.portalDashboards[result[0].dashboardPortalId].concat(result)
  144. }
  145. draft.loading.editing = false
  146. break
  147. case ActionTypes.EDIT_DASHBOARD_FAILURE:
  148. draft.loading.editing = false
  149. break
  150. case ActionTypes.DELETE_DASHBOARD_SUCCESS:
  151. draft.portalDashboards[
  152. action.payload.portalId
  153. ] = draft.portalDashboards[action.payload.portalId].filter(
  154. ({ id }) => id !== action.payload.id
  155. )
  156. break
  157. case ActionTypes.LOAD_DISPLAYS:
  158. draft.loading.display = true
  159. break
  160. case ActionTypes.LOAD_DISPLAYS_SUCCESS:
  161. draft.displays = action.payload.displays
  162. draft.loading.display = false
  163. break
  164. case ActionTypes.LOAD_DISPLAYS_FAILURE:
  165. draft.loading.display = false
  166. break
  167. case ActionTypes.ADD_DISPLAY:
  168. case ActionTypes.EDIT_DISPLAY:
  169. case ActionTypes.COPY_DISPLAY:
  170. draft.loading.editing = true
  171. break
  172. case ActionTypes.ADD_DISPLAY_SUCCESS:
  173. draft.displays.unshift(action.payload.result)
  174. draft.loading.editing = false
  175. break
  176. case ActionTypes.EDIT_DISPLAY_SUCCESS:
  177. draft.displays.splice(
  178. draft.displays.findIndex(({ id }) => id === action.payload.result.id),
  179. 1,
  180. action.payload.result
  181. )
  182. if (
  183. draft.currentDisplay &&
  184. action.payload.result.id === draft.currentDisplay.id
  185. ) {
  186. draft.currentDisplay = action.payload.result
  187. }
  188. draft.loading.editing = false
  189. break
  190. case ActionTypes.COPY_DISPLAY_SUCCESS:
  191. draft.displays.unshift(action.payload.display)
  192. break
  193. case ActionTypes.ADD_DISPLAY_FAILURE:
  194. case ActionTypes.EDIT_DISPLAY_FAILURE:
  195. case ActionTypes.COPY_DISPLAY_FAILURE:
  196. draft.loading.editing = false
  197. break
  198. case ActionTypes.DELETE_DISPLAY_SUCCESS:
  199. draft.displays = draft.displays.filter(
  200. (d) => d.id !== action.payload.id
  201. )
  202. break
  203. case ActionTypes.DELETE_DISPLAY_FAILURE:
  204. break
  205. case ActionTypes.UPDATE_CURRENT_DISPLAY:
  206. draft.currentDisplay = action.payload.display
  207. break
  208. case ActionTypes.LOAD_DISPLAY_SLIDES:
  209. draft.loading.slides = true
  210. break
  211. case ActionTypes.LOAD_DISPLAY_SLIDES_SUCCESS:
  212. draft.displaySlides[action.payload.display.id] = action.payload.slides
  213. draft.loading.slides = false
  214. break
  215. case ActionTypes.LOAD_DISPLAY_SLIDES_FAILURE:
  216. delete draft.displaySlides[action.payload.displayId]
  217. draft.loading.slides = false
  218. break
  219. case ActionTypes.ADD_SLIDE_SUCCESS:
  220. slide = action.payload.slide
  221. const { insertIdx, afterSlides } = action.payload
  222. displayId = slide.displayId
  223. draft.displaySlides[displayId].splice(insertIdx)
  224. draft.displaySlides[displayId].push(slide)
  225. draft.displaySlides[displayId] = draft.displaySlides[displayId].concat(
  226. afterSlides
  227. )
  228. break
  229. case ActionTypes.EDIT_SLIDES_SUCCESS:
  230. slides = action.payload.slides
  231. displayId = action.payload.displayId
  232. const editedSlideIds = slides.map(({ id }) => id)
  233. draft.displaySlides[displayId] = draft.displaySlides[displayId]
  234. .filter(({ id }) => !editedSlideIds.includes(id))
  235. .concat(slides)
  236. .sort((s1, s2) => s1.index - s2.index)
  237. if (editedSlideIds.includes(draft.currentSlide.id)) {
  238. draft.currentSlide = slides.find(
  239. ({ id }) => id === draft.currentSlide.id
  240. )
  241. }
  242. break
  243. case ActionTypes.DELETE_SLIDES_SUCCESS:
  244. displayId = action.payload.displayId
  245. action.payload.slideIds.forEach((deleteId) => {
  246. draft.displaySlides[displayId].splice(
  247. draft.displaySlides[displayId].findIndex(
  248. ({ id }) => id === deleteId
  249. ),
  250. 1
  251. )
  252. })
  253. break
  254. case LOCATION_CHANGE:
  255. const matchPortal = matchPortalPath(action.payload.location.pathname)
  256. if (matchPortal) {
  257. draft.currentPortalId = +matchPortal.params.portalId || 0
  258. break
  259. }
  260. const matchDisplaySlide = matchDisplaySlidePath(
  261. action.payload.location.pathname
  262. )
  263. if (matchDisplaySlide) {
  264. const nextDisplayId = +matchDisplaySlide.params.displayId
  265. const nextSlides = draft.displaySlides[nextDisplayId]
  266. if (nextSlides) {
  267. const nextSlideId = +matchDisplaySlide.params.slideId
  268. const nextSlide = nextSlides.find(({ id }) => id === nextSlideId)
  269. draft.currentSlide = nextSlide
  270. } else {
  271. draft.currentSlide = null
  272. }
  273. } else {
  274. draft.currentDisplay = null
  275. draft.currentSlide = null
  276. }
  277. break
  278. }
  279. })
  280. export { initialState as vizInitialState}
  281. export default vizReducer