606 lines
23 KiB
TypeScript
606 lines
23 KiB
TypeScript
// import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
// import { createAsyncThunk } from '@reduxjs/toolkit';
|
|
// import { toast } from 'react-toastify';
|
|
// import colors from '../../utlity/colorsArr';
|
|
// import api from '../../config/api';
|
|
|
|
|
|
|
|
// export enum recipientType {
|
|
// SIGNER = "Signer",
|
|
// INPERSONSIGNER = "InPersonSigner",
|
|
// CC = "CC"
|
|
// }
|
|
|
|
// export interface Recipient {
|
|
// id?: string;
|
|
// firstName: string;
|
|
// lastName: string;
|
|
// routingOrder: number;
|
|
// email: string;
|
|
// hostName: string;
|
|
// hostEmail: string;
|
|
// type: recipientType;
|
|
// color?: string;
|
|
// }
|
|
|
|
// export interface SelectedRecipientInt {
|
|
// recipients: Recipient[],
|
|
// signingOrder: boolean,
|
|
// transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE
|
|
// }
|
|
|
|
// interface AddRecipientArgs {
|
|
// recipientsData: Recipient[];
|
|
// accountId: string;
|
|
// transactionId: string;
|
|
// }
|
|
|
|
// export enum TRANSACTION_TEMPLATE_TOGGLE {
|
|
// TRANSACTIONS = "transactions",
|
|
// TEMPLATES = "templates"
|
|
// }
|
|
|
|
// const initialState: SelectedRecipientInt = {
|
|
// recipients: [],
|
|
// signingOrder: false,
|
|
// transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS
|
|
// };
|
|
|
|
// export const addRecipientAsync = createAsyncThunk<Recipient[], AddRecipientArgs>(
|
|
// 'selectedRecipients/addRecipientAsync',
|
|
// async ({ recipientsData, accountId, transactionId }, { rejectWithValue }) => {
|
|
// console.log(recipientsData, accountId, transactionId, "recipientsData Line 46");
|
|
// try {
|
|
// console.log(recipientsData, "recipientsData --- Line 48");
|
|
|
|
// const updateRecipientsData = recipientsData.filter((recipient, idx) => recipient.id !== null);
|
|
// const createRecipientsData = recipientsData.filter((recipient, idx) => recipient.id == null);
|
|
|
|
// console.log(updateRecipientsData, "updateRecipientsData Line 52");
|
|
// console.log(createRecipientsData, "createRecipientsData Line 53");
|
|
|
|
// const resUpdate = await api.put(
|
|
// `/api/accounts/${accountId}/transactions/${transactionId}/recipients`,
|
|
// updateRecipientsData
|
|
// );
|
|
|
|
// const resCreate = await api.post(
|
|
// `/api/accounts/${accountId}/transactions/${transactionId}/recipients`,
|
|
// createRecipientsData
|
|
// );
|
|
|
|
// if (createRecipientsData.length === 0) resCreate.data = [];
|
|
// if (updateRecipientsData.length === 0) resUpdate.data = [];
|
|
|
|
// console.log(resCreate, "resCreate");
|
|
// console.log(resUpdate, "resUpdate");
|
|
|
|
// return [...resCreate.data, ...resUpdate.data] as Recipient[];
|
|
// } catch (err: any) {
|
|
// return rejectWithValue(err.response?.data || "Failed to add recipient");
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// interface RemoveRecipientAsyncInterfaceObj {
|
|
// id?: string;
|
|
// email?: string;
|
|
// }
|
|
|
|
// interface RemoveRecipientAsyncInterface {
|
|
// recipientId: number | null;
|
|
// accountId: string;
|
|
// transactionId: string;
|
|
// email: string;
|
|
// }
|
|
|
|
// export const removeRecipientAsync = createAsyncThunk<string | number, RemoveRecipientAsyncInterface>(
|
|
// 'selectedRecipients/removeRecipientAsync',
|
|
// async (obj, { rejectWithValue }) => {
|
|
// try {
|
|
// if (obj.recipientId) {
|
|
// const res = await api.delete(`/api/accounts/${obj.accountId}/transactions/${obj.transactionId}/recipients/${obj.recipientId}`);
|
|
// console.log(res, "Line 77")
|
|
// return obj.recipientId;
|
|
// }
|
|
// return obj.email
|
|
// } catch (err: any) {
|
|
// return rejectWithValue("Failed to remove recipient");
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// export const fetchRecipients = createAsyncThunk<Recipient[], { accountId: string, transactionId: string }>(
|
|
// 'selectedRecipients/fetchRecipients',
|
|
// async ({ accountId, transactionId }, { rejectWithValue }) => {
|
|
// try {
|
|
// const response = await api.get(`/api/accounts/${accountId}/transactions/${transactionId}/recipients`);
|
|
// return response.data as Recipient[];
|
|
// } catch (err: any) {
|
|
// return rejectWithValue(err.response?.data || "Failed to fetch recipients");
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// const selectedRecipientsSlice = createSlice({
|
|
// name: 'selectedRecipients',
|
|
// initialState,
|
|
// reducers: {
|
|
// // Add a single recipient
|
|
// addRecipient: (state, action: PayloadAction<Recipient>) => {
|
|
// for (const recipient of state.recipients) {
|
|
// if (recipient.email === action.payload.email) {
|
|
// toast.dismiss();
|
|
// toast.error("Email already exists !", {
|
|
// position: "bottom-right",
|
|
// autoClose: 5000,
|
|
// hideProgressBar: false,
|
|
// closeOnClick: false,
|
|
// pauseOnHover: true,
|
|
// draggable: true,
|
|
// progress: undefined,
|
|
// theme: "light",
|
|
// });
|
|
// return state;
|
|
// }
|
|
// }
|
|
|
|
// // Adding Recipient on top if type is inPersonSigner
|
|
// console.log("Getting Type ", action.payload.type)
|
|
// if (action.payload.type === recipientType.INPERSONSIGNER) {
|
|
// state.signingOrder = true
|
|
// state.recipients = [action.payload, ...state.recipients]
|
|
// } else {
|
|
// state.recipients.push(action.payload);
|
|
// }
|
|
|
|
// },
|
|
// resetRecipients: (state) => {
|
|
// state.recipients = [];
|
|
// },
|
|
// toggleToTemplates: (state) => {
|
|
// state.transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES;
|
|
// },
|
|
// // Replace the entire selectedRecipients array
|
|
// setSelectedRecipients: (state, action: PayloadAction<Recipient[]>) => {
|
|
// for (const [index, recipient] of action.payload.entries()) {
|
|
// if ((recipient.type === recipientType.INPERSONSIGNER && index > 0) && action.payload[index - 1].type !== recipientType.INPERSONSIGNER) {
|
|
// return state;
|
|
// }
|
|
// }
|
|
|
|
// state.recipients = action.payload;
|
|
// },
|
|
// setSigningOrder: (state, action: PayloadAction<boolean>) => {
|
|
|
|
// for (const recipient of state.recipients) {
|
|
// if (recipient.type === recipientType.INPERSONSIGNER) {
|
|
// if (state.signingOrder) return state;
|
|
// state.signingOrder = true;
|
|
// return state
|
|
// }
|
|
// }
|
|
|
|
// state.signingOrder = action.payload;
|
|
// },
|
|
// // Remove Recipients
|
|
// removeSelectedRecipient: (state, action: PayloadAction<Recipient>) => {
|
|
// console.log("removeSelectedRecipient Called")
|
|
// state.recipients = state.recipients.filter((recipient) => recipient.email !== action.payload.email);
|
|
// },
|
|
|
|
// // Add Color in Recipient
|
|
// addColorsToRecipient: (state) => {
|
|
// // const colors = generateUniqueColors(state.recipients.length);
|
|
// for (const [index, recipient] of state.recipients.entries()) {
|
|
// console.log(state)
|
|
// recipient.color = colors[index]
|
|
// }
|
|
// return state;
|
|
// },
|
|
// updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => {
|
|
// console.log("recipient order called Line 159")
|
|
// const { id, routingOrder } = action.payload;
|
|
// const recipient = state.recipients.find((r) => r.id === id || r.email === id);
|
|
// if (recipient) {
|
|
// recipient.routingOrder = routingOrder;
|
|
// }
|
|
// },
|
|
// updateRecipientIds: (state, action: PayloadAction<Recipient[]>) => {
|
|
// console.log("updateRecipientIds", console.table(action.payload));
|
|
// for (const recObj of state.recipients) {
|
|
// const email = recObj.email
|
|
// for (const recObj2 of action.payload) {
|
|
// recObj.id = recObj2.id;
|
|
// }
|
|
// }
|
|
// },
|
|
// resetSelRecipient: (state) => {
|
|
// state = initialState;
|
|
// return state;
|
|
// }
|
|
// },
|
|
// extraReducers: (builder) => {
|
|
// builder
|
|
// // Fetch Recipient - START
|
|
// .addCase(fetchRecipients.pending, (state) => {
|
|
// })
|
|
// .addCase(fetchRecipients.fulfilled, (state, action: PayloadAction<Recipient[]>) => {
|
|
// // console.log("Fetched recipients successfully:", action.payload);
|
|
|
|
// // Assign colors to recipients
|
|
// const assignedRecipients = action.payload.map((recipient, index) => ({
|
|
// ...recipient,
|
|
// color: colors[index], // Cycle if more recipients than colors
|
|
// }));
|
|
|
|
// state.recipients = assignedRecipients;
|
|
// })
|
|
// .addCase(fetchRecipients.rejected, (state, action) => {
|
|
// console.error("Failed to fetch recipients:", action.payload);
|
|
// toast.error("Failed to fetch recipients", {
|
|
// position: "bottom-right",
|
|
// autoClose: 5000,
|
|
// hideProgressBar: false,
|
|
// closeOnClick: false,
|
|
// pauseOnHover: true,
|
|
// draggable: true,
|
|
// progress: undefined,
|
|
// theme: "light",
|
|
// });
|
|
// })
|
|
// // Fetch Recipient - END
|
|
|
|
// // Add Recipient - START
|
|
// .addCase(addRecipientAsync.pending, (state) => {
|
|
|
|
// })
|
|
|
|
|
|
// .addCase(addRecipientAsync.fulfilled, (state, action: PayloadAction<Recipient[]>) => {
|
|
// // Optionally avoid duplicates if needed
|
|
|
|
// console.log("addRecipientAsync Called Line 258", action.payload);
|
|
// // const newRecipients = action.payload.filter(newRec => {
|
|
// // return !state.recipients.some(existing => existing existing.id === newRec.id);
|
|
// // });
|
|
|
|
// // const newRecipients = action.payload.filter(newRec => {
|
|
// // return !state.recipients.some(existing => "id" in existing && existing.id === newRec.id);
|
|
// // });
|
|
|
|
// // // Add new recipients and assign colors
|
|
// // const startIndex = state.recipients.length;
|
|
// // newRecipients.forEach((rec, index) => {
|
|
// // rec.color = colors[startIndex + index];
|
|
// // state.recipients.push(rec);
|
|
// // });
|
|
|
|
// state.recipients = action.payload.map((recipient, index) => ({
|
|
// ...recipient,
|
|
// color: colors[index % colors.length], // Cycle through colors
|
|
// }));
|
|
|
|
// })
|
|
|
|
|
|
// .addCase(addRecipientAsync.rejected, (state, action) => {
|
|
// console.error("Failed to fetch recipients:", action.payload);
|
|
// toast.error("Failed to fetch recipients", {
|
|
// position: "bottom-right",
|
|
// autoClose: 5000,
|
|
// hideProgressBar: false,
|
|
// closeOnClick: false,
|
|
// pauseOnHover: true,
|
|
// draggable: true,
|
|
// progress: undefined,
|
|
// theme: "light",
|
|
// });
|
|
// })
|
|
// // Add Recipient - END
|
|
|
|
// // Fetch Recipient - START
|
|
// .addCase(removeRecipientAsync.pending, (state) => {
|
|
// })
|
|
// .addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction<string | number>) => {
|
|
// state.recipients = state.recipients.filter(
|
|
// (recipient) => recipient.id !== action.payload && recipient.email !== action.payload
|
|
// );
|
|
// })
|
|
// .addCase(removeRecipientAsync.rejected, (state, action) => {
|
|
// console.error("Failed to Delete recipients:", action.payload);
|
|
// toast.error("Failed to Delete recipients", {
|
|
// position: "bottom-right",
|
|
// autoClose: 5000,
|
|
// hideProgressBar: false,
|
|
// closeOnClick: false,
|
|
// pauseOnHover: true,
|
|
// draggable: true,
|
|
// progress: undefined,
|
|
// theme: "light",
|
|
// });
|
|
// })
|
|
// // Fetch Recipient - END
|
|
// }
|
|
// });
|
|
|
|
// export const { addRecipient, setSelectedRecipients, toggleToTemplates, removeSelectedRecipient, setSigningOrder, addColorsToRecipient, updateRecipientIds, resetSelRecipient, updateRecipientOrder, resetRecipients } = selectedRecipientsSlice.actions;
|
|
// export default selectedRecipientsSlice.reducer;
|
|
|
|
|
|
|
|
import { createSlice, PayloadAction, createAsyncThunk } from '@reduxjs/toolkit';
|
|
import { toast } from 'react-toastify';
|
|
import colors from '../../utlity/colorsArr';
|
|
import api from '../../config/api';
|
|
|
|
export enum recipientType {
|
|
SIGNER = "Signer",
|
|
INPERSONSIGNER = "InPersonSigner",
|
|
CC = "CC"
|
|
}
|
|
|
|
export interface Recipient {
|
|
id?: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
routingOrder: number;
|
|
email: string;
|
|
hostName: string;
|
|
hostEmail: string;
|
|
type: recipientType;
|
|
color?: string;
|
|
roleName:string
|
|
}
|
|
|
|
export interface SelectedRecipientInt {
|
|
recipients: Recipient[],
|
|
signingOrder: boolean,
|
|
transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE
|
|
}
|
|
|
|
interface AddRecipientArgs {
|
|
recipientsData: Recipient[];
|
|
accountId: string;
|
|
transactionId: string;
|
|
transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE;
|
|
}
|
|
|
|
interface RemoveRecipientAsyncInterface {
|
|
recipientId: number | null;
|
|
accountId: string;
|
|
transactionId: string;
|
|
email: string;
|
|
transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE;
|
|
}
|
|
|
|
export enum TRANSACTION_TEMPLATE_TOGGLE {
|
|
TRANSACTIONS = "transactions",
|
|
TEMPLATES = "templates"
|
|
}
|
|
|
|
const initialState: SelectedRecipientInt = {
|
|
recipients: [],
|
|
signingOrder: false,
|
|
transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS
|
|
};
|
|
|
|
// 1. Add Recipient Async
|
|
export const addRecipientAsync = createAsyncThunk<
|
|
Recipient[],
|
|
{ recipientsData: Recipient[]; accountId: string; transactionId: string }
|
|
>(
|
|
'selectedRecipients/addRecipientAsync',
|
|
async ({ recipientsData, accountId, transactionId }, { rejectWithValue, getState }) => {
|
|
try {
|
|
const state = getState() as { selectedRecipients: SelectedRecipientInt };
|
|
const toggle = state.selectedRecipients.transactionTemplateToggle;
|
|
|
|
const updateRecipientsData = recipientsData.filter(recipient => recipient.id !== null);
|
|
const createRecipientsData = recipientsData.filter(recipient => recipient.id == null);
|
|
|
|
const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`;
|
|
|
|
const resUpdate = updateRecipientsData.length
|
|
? await api.put(basePath, updateRecipientsData)
|
|
: { data: [] };
|
|
|
|
const resCreate = createRecipientsData.length
|
|
? await api.post(basePath, createRecipientsData)
|
|
: { data: [] };
|
|
|
|
return [...resCreate.data, ...resUpdate.data] as Recipient[];
|
|
} catch (err: any) {
|
|
return rejectWithValue(err.response?.data || "Failed to add recipient");
|
|
}
|
|
}
|
|
);
|
|
|
|
// 2. Remove Recipient Async
|
|
export const removeRecipientAsync = createAsyncThunk<
|
|
string | number,
|
|
{ recipientId: number | null; accountId: string; transactionId: string; email: string }
|
|
>(
|
|
'selectedRecipients/removeRecipientAsync',
|
|
async ({ recipientId, accountId, transactionId, email }, { rejectWithValue, getState }) => {
|
|
try {
|
|
const state = getState() as { selectedRecipients: SelectedRecipientInt };
|
|
const toggle = state.selectedRecipients.transactionTemplateToggle;
|
|
|
|
const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`;
|
|
|
|
if (recipientId) {
|
|
await api.delete(`${basePath}/${recipientId}`);
|
|
return recipientId;
|
|
}
|
|
|
|
return email;
|
|
} catch (err: any) {
|
|
return rejectWithValue("Failed to remove recipient");
|
|
}
|
|
}
|
|
);
|
|
|
|
// 3. Fetch Recipients Async
|
|
export const fetchRecipients = createAsyncThunk<
|
|
Recipient[],
|
|
{ accountId: string; transactionId: string }
|
|
>(
|
|
'selectedRecipients/fetchRecipients',
|
|
async ({ accountId, transactionId }, { rejectWithValue, getState }) => {
|
|
try {
|
|
const state = getState() as { selectedRecipients: SelectedRecipientInt };
|
|
const toggle = state.selectedRecipients.transactionTemplateToggle;
|
|
|
|
const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`;
|
|
const response = await api.get(basePath);
|
|
|
|
return response.data as Recipient[];
|
|
} catch (err: any) {
|
|
return rejectWithValue(err.response?.data || "Failed to fetch recipients");
|
|
}
|
|
}
|
|
);
|
|
|
|
const selectedRecipientsSlice = createSlice({
|
|
name: 'selectedRecipients',
|
|
initialState,
|
|
reducers: {
|
|
addRecipient: (state, action: PayloadAction<Recipient>) => {
|
|
for (const recipient of state.recipients) {
|
|
if (recipient.email === action.payload.email) {
|
|
toast.dismiss();
|
|
toast.error("Email already exists !", {
|
|
position: "bottom-right",
|
|
autoClose: 5000,
|
|
theme: "light",
|
|
});
|
|
return state;
|
|
}
|
|
}
|
|
|
|
if (action.payload.type === recipientType.INPERSONSIGNER) {
|
|
state.signingOrder = true;
|
|
state.recipients = [action.payload, ...state.recipients];
|
|
} else {
|
|
state.recipients.push(action.payload);
|
|
}
|
|
},
|
|
resetRecipients: (state) => {
|
|
state.recipients = [];
|
|
},
|
|
toggleToTemplates: (state) => {
|
|
state.transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES;
|
|
},
|
|
setSelectedRecipients: (state, action: PayloadAction<Recipient[]>) => {
|
|
for (const [index, recipient] of action.payload.entries()) {
|
|
if ((recipient.type === recipientType.INPERSONSIGNER && index > 0)
|
|
&& action.payload[index - 1].type !== recipientType.INPERSONSIGNER) {
|
|
return state;
|
|
}
|
|
}
|
|
|
|
state.recipients = action.payload;
|
|
},
|
|
setSigningOrder: (state, action: PayloadAction<boolean>) => {
|
|
for (const recipient of state.recipients) {
|
|
if (recipient.type === recipientType.INPERSONSIGNER) {
|
|
if (state.signingOrder) return state;
|
|
state.signingOrder = true;
|
|
return state;
|
|
}
|
|
}
|
|
|
|
state.signingOrder = action.payload;
|
|
},
|
|
removeSelectedRecipient: (state, action: PayloadAction<Recipient>) => {
|
|
state.recipients = state.recipients.filter((recipient) => recipient.email !== action.payload.email);
|
|
},
|
|
addColorsToRecipient: (state) => {
|
|
for (const [index, recipient] of state.recipients.entries()) {
|
|
recipient.color = colors[index];
|
|
}
|
|
return state;
|
|
},
|
|
updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => {
|
|
const { id, routingOrder } = action.payload;
|
|
const recipient = state.recipients.find((r) => r.id === id || r.email === id);
|
|
if (recipient) {
|
|
recipient.routingOrder = routingOrder;
|
|
}
|
|
},
|
|
updateRecipientIds: (state, action: PayloadAction<Recipient[]>) => {
|
|
for (const recObj of state.recipients) {
|
|
for (const recObj2 of action.payload) {
|
|
recObj.id = recObj2.id;
|
|
}
|
|
}
|
|
},
|
|
resetSelRecipient: () => initialState
|
|
},
|
|
extraReducers: (builder) => {
|
|
builder
|
|
.addCase(fetchRecipients.pending, () => { })
|
|
.addCase(fetchRecipients.fulfilled, (state, action: PayloadAction<Recipient[]>) => {
|
|
const assignedRecipients = action.payload.map((recipient, index) => ({
|
|
...recipient,
|
|
color: colors[index],
|
|
}));
|
|
state.recipients = assignedRecipients;
|
|
})
|
|
.addCase(fetchRecipients.rejected, (state, action) => {
|
|
console.error("Failed to fetch recipients:", action.payload);
|
|
toast.error("Failed to fetch recipients", {
|
|
position: "bottom-right",
|
|
autoClose: 5000,
|
|
theme: "light",
|
|
});
|
|
})
|
|
.addCase(addRecipientAsync.pending, () => { })
|
|
.addCase(addRecipientAsync.fulfilled, (state, action: PayloadAction<Recipient[]>) => {
|
|
state.recipients = action.payload.map((recipient, index) => ({
|
|
...recipient,
|
|
color: colors[index % colors.length],
|
|
}));
|
|
})
|
|
.addCase(addRecipientAsync.rejected, (state, action) => {
|
|
console.error("Failed to add recipients:", action.payload);
|
|
toast.error("Failed to add recipients", {
|
|
position: "bottom-right",
|
|
autoClose: 5000,
|
|
theme: "light",
|
|
});
|
|
})
|
|
.addCase(removeRecipientAsync.pending, () => { })
|
|
.addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction<string | number>) => {
|
|
state.recipients = state.recipients.filter(
|
|
(recipient) => recipient.id !== action.payload && recipient.email !== action.payload
|
|
);
|
|
})
|
|
.addCase(removeRecipientAsync.rejected, (state, action) => {
|
|
console.error("Failed to delete recipient:", action.payload);
|
|
toast.error("Failed to delete recipient", {
|
|
position: "bottom-right",
|
|
autoClose: 5000,
|
|
theme: "light",
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
export const {
|
|
addRecipient,
|
|
setSelectedRecipients,
|
|
toggleToTemplates,
|
|
removeSelectedRecipient,
|
|
setSigningOrder,
|
|
addColorsToRecipient,
|
|
updateRecipientIds,
|
|
resetSelRecipient,
|
|
updateRecipientOrder,
|
|
resetRecipients
|
|
} = selectedRecipientsSlice.actions;
|
|
|
|
export default selectedRecipientsSlice.reducer;
|