All files / src/utils/hooks useData.ts

55.55% Statements 15/27
80.48% Branches 33/41
20% Functions 2/10
60% Lines 15/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                          66x                       66x       10x 10x 10x 10x 1x   10x     10x   10x                     10x 10x                               10x   10x 10x          
import {
  EnumValues, ObjectValues, DynamicSelectValues, RecordProps, ExtendDataNode, DataRefreshMode
} from '@props/RecordProps';
 
export interface DataProps {
  data?: Array<RecordProps>;
  prevData?: Array<RecordProps>;
  selectedData?: Array<RecordProps>;
  selectedRowKeys?: Array<number>;
  enumValues?: EnumValues;
  objectValues?: ObjectValues,
  dynamicSelectValues?: DynamicSelectValues,
  //For master detail list component, tree data
  treeData?: Array<ExtendDataNode>,
  insertLines?: Array<RecordProps>,
  deleteLines?: Array<RecordProps>,
  updateLines?: Array<RecordProps>,
  refreshMode?: DataRefreshMode,
  dataChanged?: boolean,
}
 
export const initData = {
  data: [] as Array<RecordProps>,
  prevData: [] as Array<RecordProps>,
  selectedRowKeys: [] as Array<number>,
  selectedData: [] as Array<RecordProps>,
  enumValues: {} as EnumValues,
  objectValues: {} as ObjectValues,
  dynamicSelectValues: {} as DynamicSelectValues,
  treeData: [] as Array<ExtendDataNode>,
  refreshMode: "disable",
} as DataProps;
 
export const dataReducer = (state: DataProps, action: {
  type: 'set';
  payload: DataProps;
}): DataProps => {
  const { payload } = action;
  const { data: newData } = payload;
  const newDataNotNull = (newData != null);
  const insertLineThisTime: RecordProps | undefined = newDataNotNull ?
    newData?.find((d: RecordProps) => state?.data?.findIndex(
      (d2: RecordProps) => d2.id === d.id) === -1) : undefined;
  const deleteLineThisTime: RecordProps | undefined = newDataNotNull ?
    state?.data?.find((d: RecordProps) => newData?.findIndex(
      (d2: RecordProps) => d2.id === d.id) === -1) : undefined;
  const updateLinesThisTime: Array<RecordProps> = [] as Array<RecordProps>;
  // find changed attributes in the new data, compare to state.data
  newDataNotNull && state?.data?.forEach((d: RecordProps) => {
    const newLine = newData.find((d2: RecordProps) => d2.id === d.id);
    newLine && Object.keys(newLine).forEach((key: string) => {
      // Changed key is key, 如果未来希望标记出变化的列,则需要返回 key 信息
      if (newLine[key] !== d[key]) {
        //Remove the old line with id equals to newLine.id
        updateLinesThisTime.splice(updateLinesThisTime.findIndex((d3: RecordProps) => d3.id === newLine.id), 1);
        updateLinesThisTime.push(newLine);
      }
    });
  });
  const dataChanged = (insertLineThisTime != null || deleteLineThisTime != null || updateLinesThisTime.length > 0);
  const newState = {
    data: action.payload.data ?? state.data,
    prevData: action.payload.data ? [...state.data ?? []] : state.prevData,
    selectedData: action.payload.selectedData ?? state.selectedData,
    selectedRowKeys: action.payload.selectedData?.map(d => d.id) ?? state.selectedRowKeys,
    enumValues: action.payload.enumValues ?? state.enumValues,
    objectValues: action.payload.objectValues ?? state.objectValues,
    dynamicSelectValues: action.payload.dynamicSelectValues ?? state.dynamicSelectValues,
    treeData: action.payload.treeData ?? state.treeData,
    insertLines: insertLineThisTime ? [insertLineThisTime] : [],
    deleteLines: deleteLineThisTime ? [deleteLineThisTime] : [],
    updateLines: updateLinesThisTime ?? [],
    refreshMode: action.payload.refreshMode ?? state.refreshMode,
    dataChanged: dataChanged,
  };
 
  switch (action.type) {
    case 'set':
      state = newState;
      return newState;
    default:
      throw new Error("Not support action ", action.type);
  }
};