import graphql from './graphql' ; interface FnParams { reducerName : string ; actionType : string ; api : string ; fields : string ; unshift ? : boolean ; processList ? : ( data : Array < object > , store : any , id : string ) => Array < object > ; } interface Params { id : string ; args ? : any ; fields ? : string ; restart ? : boolean ; } export default function ( obj ) { return ( params ) => { return ( dispatch , getState ) => { let _obj = JSON . parse ( JSON . stringify ( obj ) ) ; _obj . processList = obj . processList ; if ( params . id ) _obj . id = params . id ; if ( params . args ) _obj . args = params . args ; if ( params . fields ) _obj . fields = params . fields ; if ( params . restart ) _obj . restart = params . restart ; return loadList ( dispatch , getState ) ( _obj ) ; } ; } ; } interface Props { id : string ; reducerName : string ; actionType : string ; processList ? : ( data : Array < object > , store : any , id : string ) => Array < object > ; api : string ; args ? : any ; fields : string ; restart ? : boolean ; unshift ? : boolean ; } const loadList = function ( dispatch , getState ) { return ( { id , reducerName , actionType , processList = data => data , api , args , fields , restart = false , unshift = false } ) => { return new Promise ( async ( resolve , reject ) => { let state = getState ( ) , list = state [ reducerName ] [ id ] || { } , accessToken = state . user . accessToken || '' ; if ( restart ) list = { } ; if ( list . loading ) return resolve ( [ 'loading...' ] ) ; if ( typeof list . more != 'undefined' && ! list . more ) return resolve ( [ null , list ] ) ; if ( ! list . data ) list . data = [ ] ; if ( typeof list . filters == 'undefined' ) { if ( typeof args . page_number == 'undefined' ) args . page_number = 1 ; if ( typeof args . page_size == 'undefined' ) args . page_size = 25 ; args . page_number = parseInt ( args . page_number ) ; args . page_size = parseInt ( args . page_size ) ; list . filters = args ; } else { args = list . filters ; args . page_number += 1 ; } list . loading = true ; if ( actionType ) dispatch ( { type : actionType , name : id , data : list } ) ; let apis = [ { aliases : 'list' , api , args , fields } ] ; let data = [ ] , err , res ; if ( ! args . _id ) { if ( ! Reflect . has ( list , 'count' ) ) { let s = Object . assign ( { } , args ) ; delete s . page_size ; delete s . page_number ; delete s . sort_by ; apis . push ( { aliases : 'count' , api : 'count' + api . charAt ( 0 ) . toUpperCase ( ) + api . slice ( 1 ) , args : s , fields : `count` } ) ; } [ err , res ] = await graphql ( { apis , headers : { accessToken } } ) ; if ( res && res . count ) { list . count = res . count . count ; data = res . list ; } else { data = res ; } } else { [ err , res ] = await graphql ( { apis , headers : { accessToken } } ) ; list . count = 1 ; data = res ; } if ( err ) { list . loading = false ; resolve ( [ null , list ] ) ; return ; } data = JSON . parse ( JSON . stringify ( data ) ) ; let _data = processList ( data , { dispatch , getState } , id ) ; if ( unshift ) { list . data = _data . concat ( list . data ) ; } else { list . data = list . data . concat ( _data ) ; } list . filters = args ; list . loading = false ; list . more = list . filters . page_size * list . filters . page_number > list . count ? false : true ; if ( actionType ) dispatch ( { type : actionType , name : id , data : list } ) ; resolve ( [ null , list ] ) ; } ) ; } ; } ;