import { mergeArray } from "../../utilites"; import { AsyncAction } from "../types"; export function updateAsyncState( action: AsyncAction, defVal: Readonly ): AsyncState { if (action.payload.loading) { return { updating: true, data: defVal, }; } else if (action.error !== undefined) { return { updating: false, error: action.payload.item as Error, data: defVal, }; } else { return { updating: false, error: undefined, data: action.payload.item as Payload, }; } } export function updateOrderIdState( action: AsyncAction>, state: AsyncState>, id: ItemIdType ): AsyncState> { if (action.payload.loading) { return { ...state, updating: true, }; } else if (action.error !== undefined) { return { ...state, updating: false, error: action.payload.item as Error, }; } else { const { data, total } = action.payload.item as AsyncDataWrapper; const [start, length] = action.payload.parameters; // Convert item list to object const idState: IdState = data.reduce>((prev, curr) => { const tid = curr[id]; prev[tid] = curr; return prev; }, {}); const dataOrder: number[] = data.map((v) => v[id]); let newItems = { ...state.data.items, ...idState }; let newOrder = state.data.order; const countDist = total - newOrder.length; if (countDist > 0) { newOrder.push(...Array(countDist).fill(null)); } else if (countDist < 0) { // Completely drop old data if list has shrinked newOrder = Array(total).fill(null); newItems = { ...idState }; } if (typeof start === "number" && typeof length === "number") { newOrder.splice(start, length, ...dataOrder); } else if (start === undefined) { // Full Update newOrder = dataOrder; } return { updating: false, data: { items: newItems, order: newOrder, }, }; } } export function updateAsyncList( action: AsyncAction, state: AsyncState, match: ID ): AsyncState { if (action.payload.loading) { return { ...state, updating: true, }; } else if (action.error !== undefined) { return { ...state, updating: false, error: action.payload.item as Error, }; } else { const list = state.data as T[]; const payload = action.payload.item as T[]; const result = mergeArray(list, payload, (l, r) => l[match] === r[match]); return { updating: false, data: result, }; } }