OSDN Git Service

Merge branch 'master' of git://github.com/Bytom/dashboard into dashboardmaster
[bytom/bytom-electron.git] / src / features / shared / actions / list.js
1 import { chainClient } from 'utility/environment'
2 import { push, replace } from 'react-router-redux'
3
4 export default function(type, options = {}) {
5   const listPath  = options.listPath || `/${type}s`
6   const clientApi = () => options.clientApi ? options.clientApi() : chainClient()[`${type}s`]
7
8   const receive = (param) => ({
9     type: `RECEIVED_${type.toUpperCase()}_ITEMS`,
10     param,
11   })
12
13   // Dispatch a single request for the specified query, and persist the
14   // results to the default item store
15   const fetchItems = (params) => {
16     const requiredParams = options.requiredParams || {}
17
18     params = { ...params, ...requiredParams }
19
20     return (dispatch) => {
21       const promise = clientApi().query(params)
22
23       promise.then(
24         (resp) => {
25           if(resp.status == 'fail'){
26             dispatch({type: 'ERROR', payload: { 'message': resp.msg}})
27           }else{
28             dispatch(receive(resp))
29           }
30         }
31       )
32
33       return promise
34     }
35   }
36
37   // Fetch all items up to the specified page, and persist the results to
38   // the filter-specific store
39   const fetchPage = (query, pageNumber = 1, options = {}) => {
40     const listId =  query.filter || ''
41     pageNumber = parseInt(pageNumber || 1)
42
43     return (dispatch, getState) => {
44       const getFilterStore = () => getState()[type].queries[listId] || {}
45
46       const fetchNextPage = () =>
47         dispatch(_load(query, getFilterStore(), options)).then((resp) => {
48           if (!resp || resp.type == 'ERROR') return
49
50           return Promise.resolve(resp)
51         })
52
53       return dispatch(fetchNextPage)
54     }
55   }
56
57   // Fetch and persist all records of the current object type
58   const fetchAll = () => {
59     return fetchPage('', -1)
60   }
61
62   const _load = function(query = {}, list = {}, requestOptions) {
63     return function(dispatch) {
64       const latestResponse = list.cursor || null
65       const refresh = requestOptions.refresh || false
66
67       if (!refresh && latestResponse && latestResponse.lastPage) {
68         return Promise.resolve({last: true})
69       }
70
71       let promise
72       const filter = query.filter || ''
73
74       if (!refresh && latestResponse) {
75         let responsePage
76         promise = latestResponse.nextPage()
77           .then(resp => {
78             responsePage = resp
79             return dispatch(receive(responsePage))
80           }).then(() =>
81             responsePage
82           )
83       } else {
84         const params = {}
85         if (query.filter) params.filter = filter
86         if (query.sumBy) params.sumBy = query.sumBy.split(',')
87
88         promise = dispatch(fetchItems(params))
89       }
90
91       return promise.then((response) => {
92         return dispatch({
93           type: `APPEND_${type.toUpperCase()}_PAGE`,
94           param: response,
95           refresh: refresh,
96         })
97       }).catch(err => {
98         return dispatch({type: 'ERROR', payload: err})
99       })
100     }
101   }
102
103   const deleteItem = (id, confirmMessage, deleteMessage) => {
104     return (dispatch) => {
105       if (!window.confirm(confirmMessage)) {
106         return
107       }
108
109       clientApi().delete(id)
110         .then(() => dispatch({
111           type: `DELETE_${type.toUpperCase()}`,
112           id: id,
113           message: deleteMessage,
114         })).catch(err => dispatch({
115           type: 'ERROR', payload: err
116         }))
117     }
118   }
119
120   const pushList = (query = {}, pageNumber, options = {}) => {
121     if (pageNumber) {
122       query = {
123         ...query,
124         page: pageNumber,
125       }
126     }
127
128     const location = {
129       pathname: listPath,
130       query
131     }
132
133     if (options.replace) return replace(location)
134     return push(location)
135   }
136
137   return {
138     fetchItems,
139     fetchPage,
140     fetchAll,
141     deleteItem,
142     pushList,
143     didLoadAutocomplete: {
144       type: `DID_LOAD_${type.toUpperCase()}_AUTOCOMPLETE`
145     },
146   }
147 }