import React, {
Component,
createRef,
lazy,
useEffect,
useMemo,
useRef,
useState,
} from ‘react’;
import PropTypes from ‘prop-types’;
import _find from ‘lodash/find’;
import {
Route,
Routes,
useLocation,
useNavigate,
useParams,
} from ‘react-router-dom’;
import { LazyComponent } from ‘../../base/lazyloading’;
import { toast } from ‘../../base/toast’;
import { SpinnerLoader } from ‘../../base/loader’;
import { StoreProvider } from ‘../../base/store’;
import { VendorsService } from ‘../vendors.service’;
import styles from ‘./details.module.scss’;
import { trackEvent } from ‘../../analytics’;
import { AdminService } from ‘../../adminconsole/admin.service’;
import EntireWorkflow from ‘../../workflow/Component/EntireWorkflow’;
import AppDetailHeader from ‘../AppVendorShared/DetailHeader’;
import RouteSuspense from ‘../../base/routeSuspense’;
const AppUsage = lazy(() => import(‘../ApplicationDetails/AppUsage/index’));
const NeedAction = lazy(() => import(‘../NeedAction/index’));
const LicenceManagement = lazy(() =>
import(‘../ApplicationDetails/LicenceManagement’)
);
const AppContacts = lazy(() => import(‘../ApplicationDetails/Contacts/index’));
const VendorMessaging = lazy(() => import(‘../VendorMessaging/index’));
const GeneralInfo = lazy(() =>
import(‘../ApplicationDetails/GeneralInfo/index’)
);
const InvoicesContract = lazy(() =>
import(‘../ApplicationDetails/InvoicesContract/index’)
);
const Reviews = lazy(() => import(‘./reviews’));
const Competitors = lazy(() =>
import(‘../ApplicationDetails/Competitors/index’)
);
const TaskHistory = lazy(() => import(‘../vendordetails/TaskHistory/index’));
const CompetitorDetails = lazy(() =>
import(‘../ApplicationDetails/CompetitorDetail/index’)
);
const Workflow = lazy(() => import(‘../vendordetails/Workflow’));
const AppDetails = (props) => {
constparams=useParams();
constwrapperRef=useRef();
constlocation=useLocation();
constnavigate=useNavigate();
constappStore=StoreProvider.getStore(‘App’);
constcompanyDetails=appStore.get(‘companyDetails’);
constenabledCategories=companyDetails[‘enabledCategories’];
constpermissionRequest=
enabledCategories.indexOf(‘FINANCIAL_WRITE’) >-1||
enabledCategories.indexOf(‘SUPER_ADMIN’) >-1;
constgenralGENERAL_WRITE=enabledCategories.indexOf(‘GENERAL_WRITE’) >-1;
letenableMenuData= [];
let_menuNext=_find(companyDetails[‘menus’], function (menu) {
returnmenu[‘key’] ===’application’;
});
leti;
for (i=0; i<_menuNext[‘subMenus’].length; i++) {
enableMenuData.push(_menuNext[‘subMenus’][i].key);
}
const [enableMenu, setEnableMenu] =useState(enableMenuData);
const [menus, setMenus] =useState(_menuNext[‘subMenus’]);
const [detailedData, setDetailedData] =useState(null);
constgetDefaultKey= () => {
constallURLS=location.pathname.split(‘/’);
returnallURLS[allURLS.length-1];
};
const [activeMenu, setActiveMenu] =useState(getDefaultKey());
const [isEditGenralInfo, setIsEditGenralInfo] =useState(false);
const [isBusinessEdit, setIsBusinessEdit] =useState(false);
const [isFEdit, setIsFEdit] =useState(false);
const [loaded, setLoaded] =useState(false);
const [imageError, setImageError] =useState(false);
const [generalInfoCustomField, setGeneralInfoCustomField] =useState([]);
const [contactsCustomField, setContactsCustomField] =useState([]);
const [vendorContactsCustomField, setVendorContactsCustomField] =useState(
[]
);
const [contractInvoicesCustomField, setContractInvoicesCustomField] =
useState([]);
const [showEntireWorkflow, setShowEntireWorkflow] =useState(false);
const [birdEyeWorkflowData, setBirdEyeWorkflowData] =useState({});
const [initialTaskData, setInitialTaskData] =useState({});
const [applicationSummary, setApplicationSummary] =useState({});
const [applicationIdParams, setApplicationIdParams] =useState(
params?.applicationId
);
const [addedQuickMessage, setAddedQuickMessage] =useState(false);
const [isWorkflowDetailLoading, setIsWorkflowDetailLoading] =useState(false);
const [pickListData, setPickListData] =useState([]);
letworkflowPermission;
useEffect(() => {
getApplicationDetailed();
getCustomField();
handleGetApplicationSummary();
workflowPermission=
appStore.get(‘companyDetails’).enabledCategories.includes(‘WORKFLOW’) ||
appStore
.get(‘companyDetails’)
.enabledCategories.includes(‘WORKFLOW_WRITE’);
}, []);
constgetApplicationDetailed= () => {
setLoaded(true);
VendorsService.getApplicationDetailed(params.applicationId).then(
(data) => {
trackEvent({
category:’APPLICATION VIEW’,
action:’APPLICATION VIEW’,
value:data[‘application’].id,
label:data[‘application’][‘name’],
});
setDetailedData(data);
setLoaded(false);
},
(err) => {
toast.error(err&&err[‘message’] ?err[‘message’] :`Request failed.`);
setLoaded(false);
navigate(‘/application’);
}
);
};
constgetCustomField= () => {
AdminService.getDisplaySectionWithInde(‘application’).then((data) => {
constgeneralInfoCustomFieldData=data.data.uiColumns.filter(
(column) => {
returncolumn.displaySectionName===’GENERAL_INFO’;
}
);
constpicklist=data.data.picklists;
setGeneralInfoCustomField(generalInfoCustomFieldData);
setPickListData(picklist);
});
AdminService.getDisplaySectionWithInde(‘application’).then((data) => {
constcontactsCustomFieldData=data.data.uiColumns.filter((column) => {
returncolumn.displaySectionName===’CONTACTS’;
});
setContactsCustomField(contactsCustomFieldData);
});
AdminService.getDisplaySectionWithInde(‘application’).then((data) => {
constvendorContactsCustomFieldData=data.data.uiColumns.filter(
(column) => {
returncolumn.displaySectionName===’VENDOR_CONTACTS’;
}
);
setVendorContactsCustomField(vendorContactsCustomFieldData);
});
AdminService.getDisplaySectionWithInde(‘application’).then((data) => {
constcontractInvoicesCustomFieldData=data.data.uiColumns.filter(
(column) => {
returncolumn.displaySectionName===’CONTRACTS_INVOICES’;
}
);
setContractInvoicesCustomField(contractInvoicesCustomFieldData);
});
};
constchangePage= (page, menu) => {
setActiveMenu(menu);
navigate(`/${page}`);
};
constgoBack= () => {
constpath=’/application’;
navigate(path);
};
constsetGenralInfoData= (key, data, lookup) => {
updateGenralInfoFormData(key, data, lookup);
};
constsetUsefulVendorContacts= (key, data, lookup) => {
updateGenralInfoFormData(key, data, lookup);
};
constupdateGenralInfoFormData= (key, value, lookup) => {
constcopyDetailData= […detailedData];
copyDetailData[lookup] =Object.assign(copyDetailData[lookup], {
[key]:value,
});
setDetailedData(copyDetailData);
};
constgenralInfoUpdate= () => {
if (isEditGenralInfo) {
onClickApplicationUpSert(‘General information saved.’);
}
setIsEditGenralInfo(!isEditGenralInfo);
};
constusefulVendorContacts= () => {
setLoaded(true);
letdata= {
csmContact:detailedData[‘application’][‘csmContact’],
csmEmail:detailedData[‘application’][‘csmEmail’],
phoneNumber:detailedData[‘application’][‘phoneNumber’],
salesContact:detailedData[‘application’][‘salesContact’],
salesEmail:detailedData[‘application’][‘salesEmail’],
…detailedData[‘application’],
};
VendorsService.updateVendorContractsInfo(params.applicationId, data).then(
() => {
setLoaded(false);
toast.success(‘Vendors Contacts information saved’);
},
(err) => {
setLoaded(false);
toast.error(err[‘message’] ?err[‘message’] :`failed.`);
}
);
};
constgetLicenceTableData=async (id) => {
setLoaded(true);
try {
constdata=awaitVendorsService.getInvoiceTableData(id);
if (data) {
returndata;
}
} catch (err) {
} finally {
setLoaded(false);
}
};
constonClickApplicationUpSert= (successMsg=”) => {
setLoaded(true);
letappData= {
…detailedData[‘application’],
…detailedData[‘companyVendor’],
};
appData[‘notes’] =detailedData[‘application’][‘notes’] ||”;
appData[‘billingFrequency’] =
detailedData[‘application’][‘billingFrequency’] ||”;
VendorsService.updateApplicationInfo(params.applicationId, appData).then(
() => {
getApplicationDetailed();
toast.success(successMsg||’General information saved.’);
setLoaded(false);
},
(err) => {
setLoaded(false);
toast.error(err[‘message’] ?err[‘message’] :`failed.`);
}
);
};
constbusinessInfoUpdate= () => {
if (isBusinessEdit) {
onClickApplicationUpSert(‘Contract information saved’);
}
setIsBusinessEdit(!isBusinessEdit);
};
constfinanceInfoUpdate= () => {
onClickApplicationUpSert(‘Contract/Invoices information saved’);
};
constgetBirdEyeWorkflow=async (id) => {
setIsWorkflowDetailLoading(true);
navigate(`?wId=${id}`);
try {
constres=awaitAdminService.getBirdEyeWorkflow(id);
if (res) {
setBirdEyeWorkflowData(res.data);
const { timelineView= {}, workflow= {} } =res.data|| {};
if (workflow.modelType===’TASK’) {
const [singleTask] =timelineView[1] || [];
const { stepInfo= {} } =singleTask|| {};
const { taskId } =stepInfo|| {};
if (taskId) {
getSingleTaskData(taskId);
}
} else {
setIsWorkflowDetailLoading(false);
}
}
} catch (err) {
toast.error(`${err && err[‘message’]}`);
setIsWorkflowDetailLoading(false);
} finally {
setIsWorkflowDetailLoading(false);
}
};
constgetSingleTaskData=async (id, empytData=false) => {
if (empytData) {
setInitialTaskData({});
}
if (!id) return;
setLoaded(true);
try {
constworkflow=awaitAdminService.getWorkFlow(id);
if (workflow) {
const { data } =workflow;
setInitialTaskData(data);
}
} catch (err) {
toast.error(`${err && err[‘message’]}`);
} finally {
setLoaded(false);
}
};
consthandleMainWorkflowRedirect= (id) => {
setShowEntireWorkflow(true);
getBirdEyeWorkflow(id);
};
constworkflowBreadCrumb= () => {
const { workflow= {} } =birdEyeWorkflowData|| {};
const { name, applicationName=”, applicationId } =workflow|| {};
return [
{ text: ‘APPLICATIONS’, link: `/app/application` },
{
text:applicationName.toUpperCase(),
link:`/app/application/${applicationId}/workflow`,
},
{ text: name },
];
};
consthandleToggleAddedQuickMessage= (value) => {
setAddedQuickMessage(value);
};
consthandleCloseCompetitorView= () => {
navigate(`/application/${params.applicationId}/competitors`);
};
consthandleSaveContactDetail=async (updatedData) => {
setLoaded(true);
try {
const { application } =detailedData;
constres=awaitVendorsService.updateVendorContactInfo(
application.companyVendorId,
updatedData
);
if (res) {
toast.success(‘Contact information saved.’);
getApplicationDetailed();
}
setLoaded(false);
} catch (err) {
toast.error(err.message);
} finally {
setLoaded(false);
}
};
consthandleSaveApplicationDetails=async (updatedData, toastMsg=”) => {
setLoaded(true);
try {
constres=awaitVendorsService.updateApplicationInfo(
params.applicationId,
updatedData
);
if (res) {
getApplicationDetailed();
toast.success(toastMsg||’Company contact detail save successfully’);
}
setLoaded(false);
} catch (err) {
toast.error(err.message);
} finally {
setLoaded(false);
}
};
consthandleGetApplicationSummary=async () => {
setLoaded(true);
try {
constres=awaitVendorsService.getAppSummary(params.applicationId);
if (res) {
setApplicationSummary(res.data);
}
setLoaded(false);
} catch (err) {
} finally {
setLoaded(false);
}
};
const { mainWrapperRef } =props;
const { applicationId, tab } =params;
constbaseURL=`/application/${applicationId}/competitors`;
constid=params.competitorId;
constactualURL=`${baseURL}/${id}`;
constpath=’/application/:applicationId/competitors/:competitorId’;
const { application= {} } =detailedData|| {};
const { sourcesAsString, directIntergationConnected } =application;
constdisableMenu= () =>
menus[0].key===’usage’&&
sourcesAsString===’MANUAL’&&
!directIntergationConnected
?menus[1].key
:menus[0].key;
useEffect(() => {
constquery=newURLSearchParams(props.location.search);
constwId=query.get(‘wId’);
if (wId) {
navigate(“);
}
}, []);
useEffect(() => {
if (showEntireWorkflow&&!location.search) {
setShowEntireWorkflow(false);
}
}, [showEntireWorkflow]);
useEffect(() => {
if (applicationIdParams!==params.applicationId) {
setApplicationIdParams(params.applicationId);
getApplicationDetailed();
getCustomField();
}
}, [applicationIdParams, params.applicationId]);
constactiveTab=useMemo(() => {
consttabMatch=location.pathname.match(/\/([^/]+)$/);
returntabMatch?tabMatch[1] :null;
}, [location]);
useEffect(() => {
if (activeTab!==activeMenu) {
setActiveMenu(activeTab);
}
}, [activeTab]);
return (
<>
<divclassName={styles.applicationDetailWrapper}ref={wrapperRef}>
{(loaded || !detailedData || isWorkflowDetailLoading) && (
<SpinnerLoader/>
)}
{detailedData && !showEntireWorkflow && (
<>
<AppDetailHeader
detailedData={detailedData}
menus={menus}
changePage={changePage}
activeMenu={activeMenu}
goBack={goBack}
handleToggleAddedQuickMessage={handleToggleAddedQuickMessage}
isApplicationDetailHeader={true}
vendorSummary={applicationSummary}
/>
{!menus.some(
(i) => i.key?.toLowerCase() === activeMenu?.toLowerCase()
) &&
changePage(
`application/${applicationId}/${disableMenu()}`,
disableMenu()
)}
<Routes>
<Route
path=”usage”
exact
element={
<RouteSuspense>
<AppUsage
enableMenu={enableMenu}
detailedData={detailedData}
menus={menus}
directIntegrationPresent={
detailedData.directIntegrationPresent
}
directIntergationConnected={
detailedData.application.directIntergationConnected
}
integrationFeatureConfig={
detailedData.integrationFeatureConfig
}
changePage={changePage}
mainWrapperRef={props.mainWrapperRef}
{…props}
/>
</RouteSuspense>
}
/>
{enableMenu.includes(‘needAction’) && (
<Route
exact
path=”needAction”
element={
<RouteSuspense>
<NeedAction
type=”application”
detailedData={detailedData}
/>
</RouteSuspense>
}
/>
)}
<Route
path=”licenseManagement”
exact
element={
<RouteSuspense>
<LicenceManagement
enableMenu={enableMenu}
detailedData={detailedData}
menus={menus}
getApplicationDetailed={getApplicationDetailed}
getLicenceTableData={getLicenceTableData}
changePage={changePage}
mainWrapperRef={props.mainWrapperRef}
{…props}
/>
</RouteSuspense>
}
/>
<Route
path={[”, ‘contacts’]}
exact
element={
<RouteSuspense>
<AppContacts
handleSaveContactDetail={handleSaveContactDetail}
handleSaveCompanyContactDetails={
handleSaveApplicationDetails
}
picklistData={pickListData}
contactsCustomField={contactsCustomField}
vendorContactCustomField={vendorContactsCustomField}
detailedData={detailedData}
/>
</RouteSuspense>
}
/>
<Route
path=”messaging”
exact
element={
<RouteSuspense>
<VendorMessaging
enableMenu={enableMenu}
detailedData={detailedData}
sourcePage=”VENDOR_AND_APPLICATION_PAGE”
mainWrapperRef={mainWrapperRef}
isAppDrawer
{…props}
/>
</RouteSuspense>
}
/>
<Route
path=”generalInfo”
exact
element={
<RouteSuspense>
<GeneralInfo
enableMenu={enableMenu}
detailedData={detailedData}
handleSaveGeneralInfo={handleSaveApplicationDetails}
{…props}
/>
</RouteSuspense>
}
/>
<Route
path=”spendDetails”
exact
element={
<RouteSuspense>
<InvoicesContract
permissionRequest={permissionRequest}
setGenralInfoData={setGenralInfoData}
financeInfoUpdate={financeInfoUpdate}
detailedData={detailedData}
picklistData={pickListData}
contractInvoicesCustomField={contractInvoicesCustomField}
handleSaveSpendInfo={handleSaveApplicationDetails}
mainWrapperRef={props.mainWrapperRef}
{…props}
/>
</RouteSuspense>
}
/>
<Route
path=”reviews”
exact
element={
<RouteSuspense>
<Reviews
enableMenu={enableMenu}
picklistData={pickListData}
detailedData={detailedData}
mainWrapperRef={props.mainWrapperRef}
wrapperRef={wrapperRef}
{…props}
/>
</RouteSuspense>
}
/>
<Route
path=”competitors”
exact
element={
<RouteSuspense>
<Competitors
enableMenu={enableMenu}
detailedData={detailedData}
applicationId={applicationId}
mainWrapperRef={props.mainWrapperRef}
wrapperRef={wrapperRef}
{…props}
/>
</RouteSuspense>
}
/>
<Route
path=”taskHistory”
exact
element={
<RouteSuspense>
<TaskHistorypageName=”application”/>
</RouteSuspense>
}
/>
<Route
path=”competitors/:competitorId/*”
exact
element={
<RouteSuspense>
<CompetitorDetails
{…props}
detailedData={detailedData}
baseURL={baseURL}
actualURL={actualURL}
path={path}
onCloseModal={handleCloseCompetitorView}
mainWrapperRef={props.mainWrapperRef}
wrapperRef={wrapperRef}
id={id}
/>
</RouteSuspense>
}
/>
{workflowPermission && (
<Route
path=”workflow”
exact
element={
<RouteSuspense>
<Workflow
enableMenu={enableMenu}
withoutUnresolvedFields
detailedData={detailedData}
handleMainWorkflowRedirect={handleMainWorkflowRedirect}
{…props}
/>
</RouteSuspense>
}
/>
)}
</Routes>
</>
)}
{showEntireWorkflow && (
<divclassName={styles.workflowWrapper}>
<EntireWorkflow
initialBreadCrumb={workflowBreadCrumb()}
getBirdEyeWorkflow={getBirdEyeWorkflow}
getSingleTaskDataApi={getSingleTaskData}
setIsWorkflowDetailLoading={(value) =>
setIsWorkflowDetailLoading(value)
}
{…birdEyeWorkflowData}
initialTaskData={initialTaskData}
/>
</div>
)}
</div>
</>
);
};
export default AppDetails;
Please follow and like us: