reducer.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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 { DashboardActionType } from './actions'
  23. import { getInitialItemInfo, getGlobalControlInitialValues } from './util'
  24. import { DownloadTypes } from '../App/constants'
  25. import { LOCATION_CHANGE, LocationChangeAction } from 'connected-react-router'
  26. import { ActionTypes as VizActionTypes } from 'containers/Viz/constants'
  27. import { VizActionType } from '../Viz/actions'
  28. import { fieldGroupedSort } from 'containers/Widget/components/Config/Sort'
  29. import { IDashboardState, IDashboardSharePanelState } from './types'
  30. const defaultSharePanelState: IDashboardSharePanelState = {
  31. id: 0,
  32. type: 'dashboard',
  33. title: '',
  34. visible: false
  35. }
  36. const initialState: IDashboardState = {
  37. currentDashboard: null,
  38. currentDashboardLoading: false,
  39. currentDashboardShareToken: '',
  40. currentDashboardAuthorizedShareToken: '',
  41. currentDashboardPasswordShareToken: '',
  42. currentDashboardPasswordSharePassword: '',
  43. currentDashboardShareLoading: false,
  44. sharePanel: defaultSharePanelState,
  45. currentItems: null,
  46. currentItemsInfo: null,
  47. fullScreenPanelItemId: null,
  48. cancelTokenSources: []
  49. }
  50. const dashboardReducer = (
  51. state = initialState,
  52. action: VizActionType | DashboardActionType | LocationChangeAction
  53. ): IDashboardState =>
  54. produce(state, (draft) => {
  55. let drillHistory
  56. let targetItemInfo
  57. switch (action.type) {
  58. case VizActionTypes.EDIT_CURRENT_DASHBOARD:
  59. draft.currentDashboardLoading = true
  60. break
  61. case VizActionTypes.EDIT_CURRENT_DASHBOARD_SUCCESS:
  62. draft.currentDashboard = action.payload.result
  63. draft.currentDashboardLoading = false
  64. break
  65. case VizActionTypes.EDIT_CURRENT_DASHBOARD_FAILURE:
  66. draft.currentDashboardLoading = false
  67. break
  68. case ActionTypes.LOAD_DASHBOARD_DETAIL:
  69. draft.currentDashboardLoading = true
  70. break
  71. case ActionTypes.LOAD_DASHBOARD_DETAIL_SUCCESS:
  72. const { dashboard, widgets, formedViews, items } = action.payload
  73. const globalControlsInitialValue = getGlobalControlInitialValues(
  74. dashboard.config.filters,
  75. formedViews
  76. )
  77. draft.currentDashboardLoading = false
  78. draft.currentDashboard = dashboard
  79. draft.currentDashboardShareToken = ''
  80. draft.currentDashboardPasswordShareToken = ''
  81. draft.currentDashboardAuthorizedShareToken = ''
  82. draft.currentItems = items
  83. draft.currentItemsInfo = items.reduce((info, item) => {
  84. const relatedWidget = widgets.find((w) => w.id === item.widgetId)
  85. const initialItemInfo = getInitialItemInfo(relatedWidget, formedViews)
  86. const drillpathSetting =
  87. item.config && item.config.length ? JSON.parse(item.config) : void 0
  88. if (globalControlsInitialValue[item.id]) {
  89. const {
  90. globalFilters,
  91. globalVariables
  92. } = globalControlsInitialValue[item.id]
  93. initialItemInfo.queryConditions = {
  94. ...initialItemInfo.queryConditions,
  95. globalFilters,
  96. globalVariables,
  97. ...drillpathSetting
  98. }
  99. }
  100. info[item.id] = initialItemInfo
  101. return info
  102. }, {})
  103. break
  104. case ActionTypes.LOAD_DASHBOARD_DETAIL_FAILURE:
  105. draft.currentDashboardLoading = false
  106. break
  107. case ActionTypes.ADD_DASHBOARD_ITEMS_SUCCESS:
  108. draft.currentItems = (draft.currentItems || []).concat(
  109. action.payload.items
  110. )
  111. action.payload.items.forEach((item) => {
  112. const relatedWidget = action.payload.widgets.find(
  113. (w) => w.id === item.widgetId
  114. )
  115. draft.currentItemsInfo[item.id] = getInitialItemInfo(
  116. relatedWidget,
  117. action.payload.formedViews
  118. )
  119. })
  120. break
  121. case ActionTypes.ADD_DASHBOARD_ITEMS_FAILURE:
  122. break
  123. case ActionTypes.EDIT_DASHBOARD_ITEM_SUCCESS:
  124. draft.currentItems.splice(
  125. draft.currentItems.findIndex(
  126. ({ id }) => id === action.payload.result.id
  127. ),
  128. 1,
  129. action.payload.result
  130. )
  131. break
  132. case ActionTypes.EDIT_DASHBOARD_ITEM_FAILURE:
  133. break
  134. case ActionTypes.EDIT_DASHBOARD_ITEMS_SUCCESS:
  135. draft.currentItems = action.payload.items
  136. break
  137. case ActionTypes.EDIT_DASHBOARD_ITEMS_FAILURE:
  138. break
  139. case ActionTypes.DELETE_DASHBOARD_ITEM_SUCCESS:
  140. delete draft.currentItemsInfo[action.payload.id]
  141. draft.currentItems = draft.currentItems.filter(
  142. ({ id }) => id !== action.payload.id
  143. )
  144. break
  145. case ActionTypes.DELETE_DASHBOARD_ITEM_FAILURE:
  146. break
  147. case ActionTypes.CLEAR_CURRENT_DASHBOARD:
  148. draft.currentDashboard = null
  149. draft.currentItems = null
  150. draft.currentItemsInfo = null
  151. break
  152. case ActionTypes.LOAD_DASHBOARD_ITEM_DATA:
  153. draft.currentItemsInfo[action.payload.itemId].loading = true
  154. draft.currentItemsInfo[action.payload.itemId].errorMessage = ''
  155. draft.cancelTokenSources.push(action.payload.cancelTokenSource)
  156. break
  157. case ActionTypes.LOAD_DASHBOARD_ITEM_DATA_SUCCESS:
  158. // @TODO combine widget static filters with local filters
  159. const {
  160. tempFilters,
  161. linkageFilters,
  162. globalFilters,
  163. variables,
  164. linkageVariables,
  165. globalVariables,
  166. pagination,
  167. nativeQuery,
  168. customOrders
  169. } = action.payload.requestParams
  170. fieldGroupedSort(action.payload.result.resultList, customOrders)
  171. draft.currentItemsInfo[action.payload.itemId] = {
  172. ...draft.currentItemsInfo[action.payload.itemId],
  173. loading: false,
  174. datasource: action.payload.result,
  175. renderType: action.payload.renderType,
  176. queryConditions: {
  177. ...draft.currentItemsInfo[action.payload.itemId].queryConditions,
  178. tempFilters,
  179. linkageFilters,
  180. globalFilters,
  181. variables,
  182. linkageVariables,
  183. globalVariables,
  184. pagination,
  185. nativeQuery
  186. },
  187. selectedItems: []
  188. }
  189. break
  190. case ActionTypes.LOAD_DASHBOARD_ITEM_DATA_FAILURE:
  191. // LOAD_DASHBOARD_ITEM_DATA_FAILURE maybe executed after CLEAR_CURRENT_DASHBOARD when location changes
  192. if (draft.currentItemsInfo) {
  193. draft.currentItemsInfo[action.payload.itemId].loading = false
  194. draft.currentItemsInfo[action.payload.itemId].errorMessage =
  195. action.payload.errorMessage
  196. }
  197. break
  198. case ActionTypes.LOAD_BATCH_DATA_WITH_CONTROL_VALUES:
  199. action.payload.relatedItems.forEach((itemId) => {
  200. draft.currentItemsInfo[itemId].loading = true
  201. draft.currentItemsInfo[itemId].errorMessage = ''
  202. })
  203. draft.cancelTokenSources.push(action.payload.cancelTokenSource)
  204. break
  205. case ActionTypes.SELECT_DASHBOARD_ITEM_CHART:
  206. const selectedItem = draft.currentItemsInfo[action.payload.itemId]
  207. draft.currentItemsInfo[action.payload.itemId] = {
  208. ...selectedItem,
  209. renderType: action.payload.renderType,
  210. selectedItems: action.payload.selectedItems
  211. }
  212. break
  213. case ActionTypes.DRILL_DASHBOARDITEM:
  214. drillHistory =
  215. draft.currentItemsInfo[action.payload.itemId].queryConditions
  216. .drillHistory
  217. if (!drillHistory) {
  218. draft.currentItemsInfo[
  219. action.payload.itemId
  220. ].queryConditions.drillHistory = []
  221. }
  222. draft.currentItemsInfo[
  223. action.payload.itemId
  224. ].queryConditions.drillHistory.push(action.payload.drillHistory)
  225. break
  226. case ActionTypes.DRILL_PATH_SETTING:
  227. const drillSetting =
  228. draft.currentItemsInfo[action.payload.itemId].queryConditions
  229. .drillSetting
  230. if (!drillSetting) {
  231. draft.currentItemsInfo[
  232. action.payload.itemId
  233. ].queryConditions.drillSetting = [action.payload.history]
  234. } else {
  235. drillSetting.push(action.payload.history)
  236. }
  237. break
  238. case ActionTypes.DELETE_DRILL_HISTORY:
  239. drillHistory =
  240. draft.currentItemsInfo[action.payload.itemId].queryConditions
  241. .drillHistory
  242. if (Array.isArray(drillHistory)) {
  243. drillHistory.splice(action.payload.index + 1)
  244. }
  245. break
  246. case ActionTypes.LOAD_DASHBOARD_SHARE_LINK:
  247. draft.currentDashboardShareLoading = true
  248. if (action.payload.params.mode === 'AUTH') {
  249. draft.currentDashboardAuthorizedShareToken = ''
  250. }
  251. break
  252. case ActionTypes.LOAD_DASHBOARD_SHARE_LINK_SUCCESS:
  253. draft.currentDashboardShareToken = action.payload.shareToken
  254. draft.currentDashboardShareLoading = false
  255. break
  256. case ActionTypes.LOAD_DASHBOARD_AUTHORIZED_SHARE_LINK_SUCCESS:
  257. draft.currentDashboardAuthorizedShareToken =
  258. action.payload.authorizedShareToken
  259. draft.currentDashboardShareLoading = false
  260. break
  261. case ActionTypes.LOAD_DASHBOARD_PASSWORD_SHARE_LINK_SUCCESS:
  262. draft.currentDashboardPasswordShareToken = action.payload.passwordShareToken
  263. draft.currentDashboardPasswordSharePassword = action.payload.password
  264. draft.currentDashboardShareLoading = false
  265. break
  266. case ActionTypes.LOAD_DASHBOARD_SHARE_LINK_FAILURE:
  267. draft.currentDashboardShareLoading = false
  268. break
  269. case ActionTypes.LOAD_WIDGET_SHARE_LINK:
  270. draft.currentItemsInfo[action.payload.params.itemId].shareLoading = true
  271. if (action.payload.params.mode === 'AUTH') {
  272. draft.currentItemsInfo[
  273. action.payload.params.itemId
  274. ].authorizedShareToken = ''
  275. }
  276. break
  277. case ActionTypes.LOAD_WIDGET_SHARE_LINK_SUCCESS:
  278. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  279. targetItemInfo.shareToken = action.payload.shareToken
  280. targetItemInfo.shareLoading = false
  281. break
  282. case ActionTypes.LOAD_WIDGET_AUTHORIZED_SHARE_LINK_SUCCESS:
  283. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  284. targetItemInfo.authorizedShareToken =
  285. action.payload.authorizedShareToken
  286. targetItemInfo.shareLoading = false
  287. break
  288. case ActionTypes.LOAD_WIDGET_PASSWORD_SHARE_LINK_SUCCESS:
  289. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  290. targetItemInfo.passwordShareToken = action.payload.passwordShareToken
  291. targetItemInfo.password = action.payload.password
  292. targetItemInfo.shareLoading = false
  293. break
  294. case ActionTypes.LOAD_WIDGET_SHARE_LINK_FAILURE:
  295. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  296. targetItemInfo.shareLoading = false
  297. break
  298. case ActionTypes.OPEN_SHARE_PANEL:
  299. draft.sharePanel = {
  300. id: action.payload.id,
  301. type: action.payload.type,
  302. title: action.payload.title,
  303. itemId: action.payload.itemId,
  304. visible: true
  305. }
  306. break
  307. case ActionTypes.CLOSE_SHARE_PANEL:
  308. draft.sharePanel = defaultSharePanelState
  309. break
  310. case ActionTypes.LOAD_WIDGET_CSV:
  311. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  312. targetItemInfo.downloadCsvLoading = true
  313. break
  314. case ActionTypes.LOAD_WIDGET_CSV_SUCCESS:
  315. case ActionTypes.LOAD_WIDGET_CSV_FAILURE:
  316. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  317. targetItemInfo.downloadCsvLoading = false
  318. break
  319. case ActionTypes.INITIATE_DOWNLOAD_TASK:
  320. if (action.payload.type === DownloadTypes.Widget) {
  321. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  322. targetItemInfo.downloadCsvLoading = true
  323. }
  324. break
  325. case ActionTypes.INITIATE_DOWNLOAD_TASK_SUCCESS:
  326. case ActionTypes.INITIATE_DOWNLOAD_TASK_FAILURE:
  327. if (action.payload.type === DownloadTypes.Widget) {
  328. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  329. targetItemInfo.downloadCsvLoading = false
  330. }
  331. break
  332. case ActionTypes.RENDER_DASHBOARDITEM:
  333. draft.currentItemsInfo[action.payload.itemId].rendered = true
  334. break
  335. case ActionTypes.RESIZE_DASHBOARDITEM:
  336. targetItemInfo = draft.currentItemsInfo[action.payload.itemId]
  337. targetItemInfo.renderType = 'resize'
  338. targetItemInfo.datasource = { ...targetItemInfo.datasource }
  339. break
  340. case ActionTypes.RESIZE_ALL_DASHBOARDITEM:
  341. Object.values(draft.currentItemsInfo).forEach((itemInfo: any) => {
  342. itemInfo.renderType = 'resize'
  343. itemInfo.datasource = { ...itemInfo.datasource }
  344. })
  345. break
  346. case ActionTypes.RENDER_CHART_ERROR:
  347. draft.currentItemsInfo[
  348. action.payload.itemId
  349. ].errorMessage = action.payload.error.toString()
  350. break
  351. case ActionTypes.SET_FULL_SCREEN_PANEL_ITEM_ID:
  352. draft.fullScreenPanelItemId = action.payload.itemId
  353. if (action.payload.itemId) {
  354. draft.currentItemsInfo[action.payload.itemId].renderType = 'clear'
  355. draft.currentItemsInfo[action.payload.itemId].rendered = true
  356. }
  357. break
  358. case LOCATION_CHANGE:
  359. if (state.cancelTokenSources.length) {
  360. state.cancelTokenSources.forEach((source) => {
  361. source.cancel()
  362. })
  363. draft.cancelTokenSources = []
  364. }
  365. break
  366. }
  367. })
  368. export default dashboardReducer