NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

import React, { useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { DashboarData, SelectRows, setFiterRowsData, setSearchFilterData, setTableRowData, DisplaySelectedSubmission, ToggleShowMyData, setTableColumns, setSearchColumn, setPageSize as setPageSizeAction } from '../../Shared/Redux/Slicers/DashboardSlice'
import Switch from 'react-switch'
import MultipleSelectDropDown from '../../Shared/Components/MultipleSelectDropDown'
import ApiService from '../../Shared/Services/CyberAIService'
import Popup from 'reactjs-popup'
import 'reactjs-popup/dist/index.css';
import { constant } from '../../Shared/Constants/constant'
import { useHistory } from 'react-router-dom/cjs/react-router-dom.min'
import { DndContext, closestCenter } from '@dnd-kit/core';
import { arrayMove, SortableContext, horizontalListSortingStrategy } from '@dnd-kit/sortable';
import { DraggableColumn } from './DraggableColumn';
import userpreferenceObj from '../../assets/data/UserPreferenceObj'
import { setCompareSubmissionVersion } from '../../Shared/Redux/Slicers/SubmissionSlice'
import { showSavePreferenceError, showSavePreferenceSuccess, showClearPreferenceSuccess, showClearPreferenceError } from '../../Shared/Components/AlertBox'
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import Checkbox from '@mui/material/Checkbox';
import ListItemText from '@mui/material/ListItemText';
import EditIcon from "@mui/icons-material/Edit";
import './Dashboard.css';
import OutlinedInput from '@mui/material/OutlinedInput';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';

const QUICK_FILTER_KEY = 'dashboardSelectedQuickFilter'; // sessionStorage key

const patchRow = (rows, id, patch) =>
rows.map(r => {
if (r.submission_id !== id) return r;
const delta = typeof patch === "function" ? patch(r) : patch;
return { ...r, ...delta };
});

const DataTable = ({ selectedDuration, setSelectedDuration }) => {
const dispatch = useDispatch();
const history = useHistory();
const { filteredRowsData } = useSelector(DashboarData);

const tableRows = useSelector(SelectRows)
const dashboardData = useSelector(DashboarData);
const { showActiveSubmission, showAllSubmissions, showReviewedSubmission, searchFilterdData, checked, UnderwriterData, AssistantUnderwriterData, ProbCloseData, ProcessorData, tableColumns, searchColumn, sortedColumns, LobData } = dashboardData

const user = localStorage.getItem('email')

const reduxPageSize = useSelector((state) => state.dashboard.page_size);
const [pageSize, setPageSize] = useState(reduxPageSize || 10);

useEffect(() => {
// Update local state if reduxPageSize changes
if (reduxPageSize && reduxPageSize !== pageSize) {
setPageSize(reduxPageSize);
}
// eslint-disable-next-line
}, [reduxPageSize]);

const [selectedPage, setSelectedPage] = useState(1)
const [maxPage, setMaxPage] = useState(1)
const [pageArray, setPageArray] = useState([1, 2, 3, 4, 5])
const [variantName, setVariantName] = useState([]);
const [auVariantName, setAuVariantName] = useState([])
const [processorVariantName, setProcessorVariantName] = useState([])
const [probCloseVariantName, setProbCloseVariantName] = useState([])
const [lobVariantName, setLobVariantName] = useState([])

const [editingProcessor, setEditingProcessor] = useState(null);
const [editingProbClose, setEditingProbClose] = useState(null);
const [editingUnderwriter, setEditingUnderwriter] = useState(null);
const [editingAU, setEditingAU] = useState(null);
const [editingDuplicate, setEditingDuplicate] = useState(null);
const [editingLob, setEditingLob] = useState(null);

const applyRowEdit = (id, patchObj) => {
const prevTable = tableRows.tableRowsData;
const prevFiltered = tableRows.filteredRowsData;

const newTable = patchRow(prevTable, id, patchObj);
const newFiltered = patchRow(prevFiltered, id, patchObj);

skipRecalcRef.current = true;
dispatch(setTableRowData(newTable));
dispatch(setFiterRowsData(newFiltered));

// rollback helper (call on failed API)
return () => {
dispatch(setTableRowData(prevTable));
dispatch(setFiterRowsData(prevFiltered));
};
};

const skipRecalcRef = React.useRef(false);
const storedFilter = sessionStorage.getItem(QUICK_FILTER_KEY) || '';
const [selectedQuickFilter, setSelectedQuickFilter] = useState(storedFilter);
const [activeQuickFilter, setActiveQuickFilter] = useState(storedFilter);

const filterDescriptions = {
"No Quick Filter": "No Quick Filter applied",
"Assign Ready": `Processor = "Not Assigned"nAI Status = "Ready"`,
"Ready Queue Monitoring": `Processor ≠ "Not Assigned"nAI Status = "Ready"nRFP Status ≠ "In Preparation"`,
"Additional Information": `AI Status = "Ready"nProcessor ≠ "Not Assigned"nRFP Status ≠ "Not Started"nDocs Pending = "Needs Review"`,
"Assign Fail": `Processor = "Not Assigned" nAI Status = "Failed"`,
"Fail Queue Monitoring": `Processor ≠ "Not Assigned"nAI Status = "Failed"nDocs Pending = "Needs Review"`,
};
const isInfoAvailable = selectedQuickFilter && filterDescriptions[selectedQuickFilter];

// PRE API API CALL METHOD SET LOADER STATUS
const fetchDashBoardDataAsync = async () => {
getSearchFilterdDataArray()
}
const tableRowsData = tableRows.tableRowsData;


//THIS METHOD FILTER TABLE ARRAY BASED ON THE SEARCH CRITERIA
const getSearchFilterdDataArray = () => {
const tableRowsData = tableRows.tableRowsData;
// Only consider filters with a value
const activeFilters = searchColumn.filter(c => (c.value || "").trim() !== "");

// If no active filters, show all data and bail out early
if (activeFilters.length === 0) {
filterArrayForActiveCloseSubmission(tableRowsData);
return;
}

let data = [];
for (let i of tableRowsData) {
let count = 0;
for (let j of activeFilters) {
if (
j.id === "underwriter" ||
j.id === "assistant_underwriter" ||
j.id === "probability_of_close" ||
j.id === "processor" ||
j.id === "line_of_business"
) {
if (i[j.id] !== null && i[j.id] !== undefined) {
let strarr = j.value.split(",");
strarr.forEach(e => {
if (i[j.id].includes(e)) {
count++;
}
});
}
} else {
if (i[j.id] !== null && i[j.id] !== undefined) {
if (i[j.id].toUpperCase().includes(j.value.toUpperCase())) {
count++;
}
}
}
}
if (count === activeFilters.length) {
data.push(i);
}
}
filterArrayForActiveCloseSubmission(data);
};

//SET TOGGLE SWITCH STATE BASED ON TOGGLE POSITION & BASED ON SELECTED UPDATE THE DASHBOARD DATA STATE
const onToggleShowMyData = (data) => {
const loggedInUser = localStorage.getItem("email")?.trim().toUpperCase() || "";
let filteredData = [];

if (checked) {
const updatedLoggedInUser = loggedInUser.replace('@US.', '@');
if (updatedLoggedInUser) {
filteredData = data.filter(e =>
[e.underwriter, e.assistant_underwriter, e.processor]
.some(user => user?.trim().toUpperCase() === updatedLoggedInUser)
);
}
} else {
filteredData = data;
}

if (activeQuickFilter) {
applyQuickFilter(activeQuickFilter, filteredData, dispatch, pageSize);
} else {
dispatch(setSearchFilterData(filteredData));
getFilteredArray(filteredData, pageArray, pageSize, selectedPage);
setPagination(filteredData);
}
};



useEffect(() => {
// skip ONE recalculation when we just did an in‑row edit
if (skipRecalcRef.current) { skipRecalcRef.current = false; return; }

// Only run after data is actually present
if (tableRows.tableRowsData && tableRows.tableRowsData.length) {
getSearchFilterdDataArray();
}
}, [
tableRows.tableRowsData,
showActiveSubmission,
showReviewedSubmission,
showAllSubmissions,
checked,
searchColumn,
pageSize
]);

//THIS METHOD FILTER TABLE ARRAY BASED ON THE SEARCH CRITARIA EG. ACTIVE, CLOSE SUBMISSION
const filterArrayForActiveCloseSubmission = (data) => {
const searchFilterdData = data
const closeFilteredData = searchFilterdData.filter((e) => {
if (["Completed", "Review Complete"].includes(e.underwriter_status)) {
return e
}

})

const activeFilteredData = searchFilterdData.filter((e) => {
if (!["Completed", "Review Complete"].includes(e.underwriter_status)) {

return e
}
})
const updatedata = showActiveSubmission ? activeFilteredData : showReviewedSubmission ? closeFilteredData : showAllSubmissions ? searchFilterdData : searchFilterdData
onToggleShowMyData(updatedata);
}

// --- pagination helper ---
// keeps the user on the same page after an in‑row dropdown edit
const setPagination = (tabledata) => {
const totalPages = Math.max(1, Math.ceil(tabledata.length / pageSize));
const newSelectedPage = selectedPage > totalPages ? totalPages : selectedPage; // clamp if needed

// build a window of up to 5 consecutive page numbers centred on the current page
const first = Math.max(1, Math.min(newSelectedPage - 2, totalPages - 4));
const newPageArray = [];
for (let i = first; i <= Math.min(first + 4, totalPages); i++) newPageArray.push(i);

setMaxPage(totalPages);
setPageArray(newPageArray);
setSelectedPage(newSelectedPage);
};

//SET ACTIVE/CLOSE SUBMISSION TOGGLE BUTTON STATE & FILTER DATA BASED ON NEW SUBMISSION STATE (ACTIVE/CLOSE) PAGE
const onTogggleSubmissionListBtn = (submissionType) => {
dispatch(DisplaySelectedSubmission(submissionType));
setSelectedPage(1);
}
//HANDLE SHOW MY DATA TOGGLE SWICTH STATE & FILTER OUT DATA BASED ON SELECTION
const handleChange = (checked) => {
dispatch(ToggleShowMyData(checked));
setSelectedPage(1);
}

//SET PAGE SIZE BASED ON PAGE SIZE DROPDOWN & FILTER DATA BASED ON NEW PAGE SIZE
const onChangePageSize = (event) => {
const newSize = Number(event.target.value);
setPageSize(newSize);
dispatch(setPageSizeAction(newSize));
setSelectedPage(1);

if (activeQuickFilter) {
// pass newSize so the filter recalculates pages correctly
applyQuickFilter(activeQuickFilter, filteredRowsData, dispatch, newSize);
} else {
// reset to page 1 with the new size
getFilteredArray(filteredRowsData, pageArray, newSize, 1);
}
};


//UPDATE SEARCH COLUMN LIST BASED ON SELECTED COLUMN
const getSearchInput = (options) => {
dispatch(setSearchColumn(options))
}

//UPDATE STATE BASED ON COLUMN SEARCH INPUT BOX
const onChangeSearchInput = (event) => {
const data = searchColumn.map((e) => {
if (e.id == event.target.id) {
return ({ ...e, value: event.target.value })
} else {
return e
}
})
dispatch(setSearchColumn(data));
setSelectedPage(1);
}

//REMOVE COLUMN FROM THE LIST OF SELECTED SEARCH COLUMN LIST & FILTER BASED ON UPDATED SEARCH CRITARIA
const onClickDelete = (id) => {
const filteredSearchColum = searchColumn.filter((e) => e.id !== id);
id === "underwriter" && setVariantName([])
id === "assistant_underwriter" && setAuVariantName([])
id === "probability_of_close" && setProbCloseVariantName([])
id === "processor" && setProcessorVariantName([])
id === "line_of_business" && setLobVariantName([])
dispatch(setSearchColumn(filteredSearchColum))
}
const onClickAsc = (name, order) => {
if (!tableRows?.searchFilterdData) {
console.error("tableRos or searchFilteredData is undefined")
return
}
const searchFilterdData = tableRows.searchFilterdData.slice(); //Clone array to avoid mutating state directly
let finalArray = [];
if (name === "sender") {
const filteredArray = searchFilterdData.filter((e) => e.sender === null);
const nonFilteredArray = searchFilterdData.filter((e) => e.sender !== null);
const sortedArray = sortArray(nonFilteredArray, 'sender.emailAddress.address', order);
finalArray = order === "Desc" ? [...sortedArray, ...filteredArray] : [...filteredArray, ...sortedArray];
} else if (name === "deal_id") {
const filteredArray = searchFilterdData.filter((e) => e.sender === null);
const nonFilteredArray = searchFilterdData.filter((e) => e.sender !== null);
const sortedArray = sortArray(nonFilteredArray, 'deal_id', order);
finalArray = order === "Desc" ? [...sortedArray, ...filteredArray] : [...filteredArray, ...sortedArray];
} else {
if (name !== "product_type") {
finalArray = sortArray(searchFilterdData, name, order);
}
else {
finalArray = searchFilterdData
}

}
dispatch(
setSearchFilterData(finalArray)
)
getFilteredArray(finalArray, pageArray, pageSize, 1);
updateColumnOrderByStatus(name);
};
const sortArray = (arr, key, order) => {
return arr.sort((a, b) => {
if ((a[key] === null) || (b[key] === null)) return 0;
if (a[key].toUpperCase() < b[key].toUpperCase()) {
return order === "Asc" ? -1 : 1;
}
if (a[key].toUpperCase() > b[key].toUpperCase()) {
return order === "Asc" ? 1 : -1;
}
return 0;
});
};

//UPDATE CURRENT COLUMN ORDER STATUS & ACTIVE PAGE IN STATE OBEJCT
const updateColumnOrderByStatus = (name) => {
const updatedTableColumn = tableColumns.map((e) => {
if (e.controlId === name) {
return { ...e, previousSort: e.orderBy, orderBy: e.orderBy === "Asc" ? "Desc" : "Asc", isActive: true };
} else {
return { ...e, isActive: false, previousSort: "" }
}
});
dispatch(setTableColumns(updatedTableColumn))

};

//SET MANUALLY SELECTED PAGE AS SELECTED STATE & FILTER DATA BASED ON NEW SELECTED PAGE
const onClickPageSelect = (e) => {
getFilteredArray(searchFilterdData, pageArray, pageSize, e);
}
//SET NEXT PAGE AS SELECTED & FILTER DATA BASED ON NEW SELECTED PAGE
const onClickNext = () => {
const data = [...pageArray];
if (pageArray[pageArray.length - 1] !== maxPage) {
data.shift();
data.push(pageArray[pageArray.length - 1] + 1);
}

if (selectedPage !== maxPage) {
const selectedPage1 = selectedPage + 1;
getFilteredArray(searchFilterdData, data, pageSize, selectedPage1)
}
}

// --- slice data for the visible page ---
// if skipPagination === true we keep the existing page/window unchanged
const getFilteredArray = (
data,
pageArray,
pageSize,
selectedPageArg,
skipPagination = false
) => {
const totalPages = Math.max(1, Math.ceil(data.length / pageSize));
const page = Math.min(selectedPageArg, totalPages);

// only rebuild the page window when we explicitly allow it
if (!skipPagination) {
const first = Math.max(1, Math.min(page - 2, totalPages - 4));
const newPageArray = [];
for (let i = first; i <= Math.min(first + 4, totalPages); i++)
newPageArray.push(i);
setMaxPage(totalPages);
setPageArray(newPageArray);
}

const start = pageSize * (page - 1);
const currentRows = data.slice(start, start + pageSize);

setSelectedPage(page);
dispatch(setFiterRowsData(currentRows));
};

//SET PREVIOUS PAGE AS SELECTED & FILTER DATA BASED ON NEW SELECTED PAGE
const onClickPrevious = () => {
const data = pageArray
if (data[0] !== 1) {
data.splice(data.length - 1, 1);
data.splice(0, 0, data[0] - 1);
}

if (selectedPage !== 1) {
const selectedPage1 = selectedPage - 1;
setSelectedPage(selectedPage1)
getFilteredArray(searchFilterdData, data, pageSize, selectedPage1)
}
}
const handleActiveComponent = (e) => {
const statusVal = (e.genai_status || "").trim().toLowerCase();
// only block if it's still processing/queued
if (statusVal !== "processing" && statusVal !== "queued") {
dispatch(setCompareSubmissionVersion(false));
let underwriterName = ""
history.push({
state: { e, underwriterName },
pathname: '/submission',
})

}
}

const handleDragEnd = (event) => {
if (event.delta.x === 0 && event.delta.y === 0) {
let columnObj = tableColumns.filter(e => e.controlId === event.active.id)
onClickAsc(event.active.id, columnObj[0].orderBy)
}
else {
const { active, over } = event;

if (active.id !== over.id) {
const oldIndex = tableColumns.findIndex((col) => col.controlId === active.id);
const newIndex = tableColumns.findIndex((col) => col.controlId === over.id);
const updatedColumn = arrayMove(tableColumns, oldIndex, newIndex);
let table_columns = []
let search_filters = []
let all_my_data = checked
let active_reviewed_submission = showActiveSubmission ? "Active Submission" : showReviewedSubmission ? "Reviewed Submission" : showAllSubmissions ? "All Submission" : ""
updatedColumn.map(e => table_columns.push(e))
searchColumn.map(e => {
search_filters.push(e)
})
dispatch(setTableColumns(updatedColumn))
}
}

}
let emptyrows = tableRows.filteredRowsData === null || tableRows.filteredRowsData === undefined || tableRows.filteredRowsData.length === 0

const handleUnderwriterDropdown = (event, row) => {
const newVal = event.target.value;
if (newVal === row.underwriter) { setEditingUnderwriter(null); return; }
const rollback = applyRowEdit(row.submission_id, { underwriter: newVal });
setEditingUnderwriter(null);
ApiService.updateUwAuProcessorApiUrl({
submission_id: row.submission_id,
version: row.submission_version,
user_email: newVal,
attribute_to_update: "UW",
updating_underwriter: user
})
.then(res => { if (res?.data !== true) rollback(); })
.catch(() => rollback());
};

const onProbablityCloseHandler = (event, row) => {
const newVal = event.target.value;
if (newVal === row.probability_of_close) { setEditingProbClose(null); return; }
const rollback = applyRowEdit(row.submission_id, { probability_of_close: newVal });
setEditingProbClose(null);
ApiService.getProbClosDuplicateApiUrl({
submission_id: row.submission_id,
version: row.submission_version,
attribute_to_update: "close-probability",
attribute_value: newVal,
updating_underwriter: user
})
.then(res => { if (res?.data !== true) rollback(); })
.catch(() => rollback());
};

const onLobHandler = (event, row) => {
const newVal = event.target.value;
if (newVal === row.line_of_business) { setEditingLob(null); return; }
const rollback = applyRowEdit(row.submission_id, { line_of_business: newVal });
setEditingLob(null);
ApiService.getProbClosDuplicateApiUrl({
submission_id: row.submission_id,
version: row.submission_version,
attribute_to_update: "lob",
attribute_value: newVal,
updating_underwriter: user
})
.then(res => { if (res?.data !== true) rollback(); })
.catch(() => rollback());
};


const onProcessorHandler = (event, row) => {
const newVal = event.target.value;
if (newVal === row.processor) { setEditingProcessor(null); return; }
const rollback = applyRowEdit(row.submission_id, { processor: newVal });
setEditingProcessor(null);
ApiService.updateUwAuProcessorApiUrl({
submission_id: row.submission_id,
version: row.submission_version,
user_email: newVal,
attribute_to_update: "GSSC",
updating_underwriter: user
})
.then(res => { if (res?.data !== true) rollback(); })
.catch(() => rollback());
};
     
 
what is notes.io
 

Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 14 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.