import axios, { AxiosError, AxiosRequestConfig } from 'axios' import { toast } from 'react-toastify' import { type ErrorInfo } from '../components/BackendError' import { config } from './constants' import { IConstituentaList, IConstituentaMeta, ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstRenameData, ICstUpdateData, ICurrentUser, IExpressionParse, ILibraryItem, ILibraryUpdateData, IReferenceData, IRefsText, IRSExpression, IRSFormCreateData, IRSFormData, IRSFormUploadData, IUserInfo, IUserLoginData, IUserProfile, IUserSignupData, IUserUpdateData, IUserUpdatePassword } from './models' export function initBackend() { axios.defaults.withCredentials = true; axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'x-csrftoken'; axios.defaults.baseURL = `${config.backend}`; } // ================ Data transfer types ================ export type DataCallback = (data: ResponseData) => void; interface IFrontRequest { data?: RequestData onSuccess?: DataCallback onError?: (error: ErrorInfo) => void setLoading?: (loading: boolean) => void showError?: boolean } export interface FrontPush extends IFrontRequest { data: DataType } export interface FrontPull extends IFrontRequest{ onSuccess: DataCallback } export interface FrontExchange extends IFrontRequest{ data: RequestData onSuccess: DataCallback } export interface FrontAction extends IFrontRequest{} interface IAxiosRequest { endpoint: string request: IFrontRequest title: string options?: AxiosRequestConfig } // ==================== API ==================== export function getAuth(request: FrontPull) { AxiosGet({ title: 'Current user', endpoint: `/users/api/auth`, request: request }); } export function postLogin(request: FrontPush) { AxiosPost({ title: 'Login', endpoint: '/users/api/login', request: request }); } export function postLogout(request: FrontAction) { AxiosPost({ title: 'Logout', endpoint: '/users/api/logout', request: request }); } export function postSignup(request: FrontExchange) { AxiosPost({ title: 'Register user', endpoint: '/users/api/signup', request: request }); } export function getProfile(request: FrontPull) { AxiosGet({ title: 'Current user profile', endpoint: '/users/api/profile', request: request }); } export function patchProfile(request: FrontExchange) { AxiosPatch({ title: 'Current user profile', endpoint: '/users/api/profile', request: request }); } export function patchPassword(request: FrontPush) { AxiosPatch({ title: 'Update Password', endpoint: '/users/api/change-password', request: request }); } export function getActiveUsers(request: FrontPull) { AxiosGet({ title: 'Active users list', endpoint: '/users/api/active-users', request: request }); } export function getLibrary(request: FrontPull) { AxiosGet({ title: 'Available RSForms (Library) list', endpoint: '/api/library/active', request: request }); } export function postNewRSForm(request: FrontExchange) { AxiosPost({ title: 'New RSForm', endpoint: '/api/rsforms/create-detailed', request: request, options: { headers: { 'Content-Type': 'multipart/form-data' } } }); } export function postCloneLibraryItem(target: string, request: FrontExchange) { AxiosPost({ title: 'clone RSForm', endpoint: `/api/library/${target}/clone`, request: request }); } export function getRSFormDetails(target: string, request: FrontPull) { AxiosGet({ title: `RSForm details for id=${target}`, endpoint: `/api/rsforms/${target}/details`, request: request }); } export function patchLibraryItem(target: string, request: FrontExchange) { AxiosPatch({ title: `RSForm id=${target}`, endpoint: `/api/library/${target}`, request: request }); } export function deleteLibraryItem(target: string, request: FrontAction) { AxiosDelete({ title: `RSForm id=${target}`, endpoint: `/api/library/${target}`, request: request }); } export function postClaimLibraryItem(target: string, request: FrontPull) { AxiosPost({ title: `Claim on RSForm id=${target}`, endpoint: `/api/library/${target}/claim`, request: request }); } export function postSubscribe(target: string, request: FrontAction) { AxiosPost({ title: `Claim on RSForm id=${target}`, endpoint: `/api/library/${target}/subscribe`, request: request }); } export function deleteUnsubscribe(target: string, request: FrontAction) { AxiosDelete({ title: `Claim on RSForm id=${target}`, endpoint: `/api/library/${target}/unsubscribe`, request: request }); } export function getTRSFile(target: string, request: FrontPull) { AxiosGet({ title: `RSForm TRS file for id=${target}`, endpoint: `/api/rsforms/${target}/export-trs`, request: request, options: { responseType: 'blob' } }); } export function postNewConstituenta(schema: string, request: FrontExchange) { AxiosPost({ title: `New Constituenta for RSForm id=${schema}: ${request.data.alias}`, endpoint: `/api/rsforms/${schema}/cst-create`, request: request }); } export function patchDeleteConstituenta(schema: string, request: FrontExchange) { AxiosPatch({ title: `Delete Constituents for RSForm id=${schema}: ${request.data.items.map(item => String(item.id)).join(' ')}`, endpoint: `/api/rsforms/${schema}/cst-multidelete`, request: request }); } export function patchConstituenta(target: string, request: FrontExchange) { AxiosPatch({ title: `Constituenta id=${target}`, endpoint: `/api/constituents/${target}`, request: request }); } export function patchRenameConstituenta(schema: string, request: FrontExchange) { AxiosPatch({ title: `Renaming constituenta id=${request.data.id} for schema id=${schema}`, endpoint: `/api/rsforms/${schema}/cst-rename`, request: request }); } export function patchMoveConstituenta(schema: string, request: FrontExchange) { AxiosPatch({ title: `Moving Constituents for RSForm id=${schema}: ${JSON.stringify(request.data.items)} to ${request.data.move_to}`, endpoint: `/api/rsforms/${schema}/cst-moveto`, request: request }); } export function postCheckExpression(schema: string, request: FrontExchange) { AxiosPost({ title: `Check expression for RSForm id=${schema}: ${request.data.expression }`, endpoint: `/api/rsforms/${schema}/check`, request: request }); } export function postResolveText(schema: string, request: FrontExchange) { AxiosPost({ title: `Resolve text references for RSForm id=${schema}: ${request.data.text }`, endpoint: `/api/rsforms/${schema}/resolve`, request: request }); } export function patchResetAliases(target: string, request: FrontPull) { AxiosPatch({ title: `Reset alias for RSForm id=${target}`, endpoint: `/api/rsforms/${target}/reset-aliases`, request: request }); } export function patchUploadTRS(target: string, request: FrontExchange) { AxiosPatch({ title: `Replacing data with trs file for RSForm id=${target}`, endpoint: `/api/rsforms/${target}/load-trs`, request: request, options: { headers: { 'Content-Type': 'multipart/form-data' } } }); } // ============ Helper functions ============= function AxiosGet({ endpoint, request, title, options }: IAxiosRequest) { console.log(`REQUEST: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.get(endpoint, options) .then(response => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((error: Error | AxiosError) => { if (request.setLoading) request.setLoading(false); if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); } function AxiosPost( { endpoint, request, title, options }: IAxiosRequest ) { console.log(`POST: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.post(endpoint, request.data, options) .then(response => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((error: Error | AxiosError) => { if (request.setLoading) request.setLoading(false); if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); } function AxiosDelete( { endpoint, request, title, options }: IAxiosRequest ) { console.log(`DELETE: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.delete(endpoint, options) .then(response => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); }) .catch((error: Error | AxiosError) => { if (request.setLoading) request.setLoading(false); if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); } function AxiosPatch( { endpoint, request, title, options }: IAxiosRequest ) { console.log(`PATCH: [[${title}]]`); if (request.setLoading) request.setLoading(true); axios.patch(endpoint, request.data, options) .then(response => { if (request.setLoading) request.setLoading(false); if (request.onSuccess) request.onSuccess(response.data); return response.data; }) .catch((error: Error | AxiosError) => { if (request.setLoading) request.setLoading(false); if (request.showError) toast.error(error.message); if (request.onError) request.onError(error); }); }