File upload saga

 avatar
user_8921180445
typescript
3 years ago
5.5 kB
6
Indexable
import { PayloadAction } from '@reduxjs/toolkit';
import routes from 'app/API/api.routes';
import makeCall from 'app/API/makeCalls';
import { EUploadResources, IFileUploadResponse } from 'app/Model/types';
import {
  DEFAULT_DESCRIPTION,
  DEFAULT_TITLE,
  VARIANTS,
} from 'app/pages/DefaultLayout/constants';
import { defaultLayoutActions } from 'app/pages/DefaultLayout/slice';
import { IFileUploadAction } from 'app/pages/OrderItemPage/OrderItemDetails/slice/types';
import { contractStatusChecker } from 'helpers/getContractStatus';
import { TypeOptions } from 'react-toastify';
import {
  call,
  fork,
  put,
  take,
  takeLatest,
  takeEvery,
} from 'redux-saga/effects';
import { createFileUploaderChannel } from 'utils/upload';
import {
  IContractToDownload,
  IOrderToUpdate,
  orderDetailActions as actions,
} from '.';
import { IOrderDetailsResponse } from './type';
import { v4 as uuidV4 } from 'uuid';

function* getOrderSaga(action: PayloadAction<string>) {
  try {
    const id = action.payload;
    const response: IOrderDetailsResponse = yield call(makeCall, {
      method: 'GET',
      isSecureRoute: true,
      route: `${routes.orders.get}${id}`,
    });
    if (response) {
      const currentStatusOfContract = yield call(
        contractStatusChecker,
        Boolean(response?.contractUrl?.length),
        response.signedByClient,
        response.contractApproved,
      );
      yield put(actions.setOrder({ response, currentStatusOfContract }));
    } else {
      yield put(actions.setGettingOrder(false));
    }
  } catch (error) {
    console.log(error);
    yield put(actions.setGettingOrder(false));
  }
}

function* fileUploadProgressWatcher(
  channel: any,
  currentState: IFileUploadAction,
): any {
  while (true) {
    const progress: unknown = yield take(channel);
    if (!Number.isNaN(progress) && typeof progress === 'number') {
      const newState: IFileUploadAction = {
        _type: currentState._type,
        state: {
          ...currentState.state,
          progress,
        },
      };
      yield put(actions.setFileUploadOnly(newState));
    }
  }
}

function* updateOrderSaga(action: PayloadAction<IOrderToUpdate>) {
  const { orderId, contractPath } = action.payload;
  const body = {
    contractUrl: contractPath,
  };
  try {
    const response: IOrderDetailsResponse = yield call(makeCall, {
      method: 'PUT',
      isSecureRoute: true,
      route: `${routes.orders.get}${orderId}`,
      body,
    });
    // console.log('response', response);
    if (response) {
      yield put(actions.setOrder({ response }));
    } else {
      yield put(actions.setGettingOrder(false));
    }
  } catch (error) {
    yield put(actions.setGettingOrder(false));
  }
}

function* setUploadFileSaga(action: PayloadAction<IFileUploadAction>): any {
  try {
    const { fileToUpload } = action.payload.state;
    const data = new FormData();
    data.append('documents', fileToUpload!);

    // const [uploadPromise, channel] = yield call(createFileUploaderChannel, {
    //   data,
    //   isPublic: false,
    //   resource: EUploadResources.CONTRACT_DOCUMENT,
    //   contractDocumentResource: action.payload?._type,
    // });

    // yield fork(fileUploadProgressWatcher, channel, action.payload);
    const mainRoute = routes.upload.base;
    let route = '';
    console.log(route, mainRoute);
    if (action.payload?._type === 'bagMark') {
      route = `${mainRoute}/orderResource/${EUploadResources.CONTRACT_DOCUMENT}/${action.payload?._type}`;
    } else {
      route = `${mainRoute}/${EUploadResources.CONTRACT_DOCUMENT}/${action.payload?._type}`;
    }
    const response: IFileUploadResponse = yield call(makeCall, {
      method: 'POST',
      body: data,
      isSecureRoute: true,
      route: route,
    });

    if (
      response &&
      Array.isArray(response.uploadedFiles) &&
      response.uploadedFiles.length
    ) {
      const uploadedUrl = response.uploadedFiles[0].uploaded || '';
      yield put(
        actions.finishFileUpload({
          type: action.payload._type,
          uploadedPath: uploadedUrl,
          error: false,
        }),
      );
    } else {
      yield put(
        actions.finishFileUpload({
          type: action.payload._type,
          uploadedPath: '',
          error: true,
        }),
      );
    }
  } catch (error: any) {
    console.log(error);
    yield put(
      defaultLayoutActions.setAppMessage({
        currentMessage: DEFAULT_DESCRIPTION.Error,
        currentTitle: DEFAULT_TITLE.Fail,
        currentVariant: VARIANTS.Error as TypeOptions,
        count: uuidV4(),
      }),
    );
    yield put(
      actions.finishFileUpload({
        type: action.payload._type,
        uploadedPath: '',
        error: true,
      }),
    );
  }
}

function* downloadFileSaga(action: PayloadAction<IContractToDownload>) {
  const { filePath, orderId } = action.payload;
  try {
    yield call(makeCall, {
      method: 'GET',
      isSecureRoute: true,
      route: routes.download.base,
      query: { key: filePath, orderId },
      responseType: 'arraybuffer',
      isOnDownload: true,
    });
    yield put(actions.finishDownload);
  } catch (error) {
    console.log('error', error);
  }
}

export function* orderDetailSaga() {
  yield takeLatest(actions.getOrder.type, getOrderSaga);
  yield takeLatest(actions.updateOrder.type, updateOrderSaga);
  yield takeEvery(actions.setFileUpload.type, setUploadFileSaga);
  yield takeLatest(actions.downloadFile.type, downloadFileSaga);
}