pbn-voip-modules
Version:
PBN VOIP Component Library
534 lines (489 loc) • 15.6 kB
JSX
import React, { useCallback, useContext, useEffect, useState } from "react";
import "../../general/assets/mixins/icons.scss";
import { COMPONENT_STATUS } from "../../general/common/constants";
import { TabChanger } from "../../general/components/elements";
import SearchBar from "../../general/components/SearchBar";
import { useChangeStatus } from "../../general/hooks/useChangeStatus";
import { get } from "lodash";
import { useDispatch, useSelector } from "react-redux";
import { NOTIFICATION_TYPE } from "../../general/common/constants/ui";
import {
showPatientModal,
startChatConversation,
} from "../../general/common/utils/ui";
import CustomizedGrid from "../../general/components/CustomizedGrid";
import CustomList from "../../general/components/elements/CustomList";
import CustomPopover from "../../general/components/elements/CustomPopover";
import useDispatchWarning from "../../general/hooks/useDispatchWarning";
import useHandleMenu from "../../general/hooks/useHandleMenu";
import useRenderPopover from "../../general/hooks/useRenderPopover";
import {
CALL_LOGS_FILTER,
onSetActiveMenu,
onSortDataByField,
} from "../../redux-toolkit/call-logs";
import { onResetNotificationCount } from "../../redux-toolkit/shared";
import { STORE_KEYS } from "../../redux-toolkit/store";
import { TableCallLogConfiguration, TABS_CALL_LOG } from "../common/constants";
import useSearchCallLogs from "../hooks/useSearchCallLogs";
import ActionsBar from "./elements/ActionsBar";
import CallLogItem from "./elements/CallLogItem";
import EditPhoneCall from "./tabs/EditPhoneCall";
import { CallContext } from "../../call-pop/contexts/CallContext";
const CallLogContainer = ({
missedCallCount = 0,
makeCall,
onOpenModalCall,
}) => {
const { activeMenu, handleActiveMenu } = useHandleMenu({
key: STORE_KEYS.CALL_LOGS,
onSetActiveMenu: onSetActiveMenu,
});
const {
isSuperUser,
isCurrentUserApiCalled: isCurrentUserApiCalledFromRedux,
} = useSelector((state) => state.user);
const { dispatchGiveCallFeedback } = useDispatchWarning();
const [currentData, setCurrentData] = useState(null);
const { target, hidePopover, showPopover, show } = useRenderPopover();
const { onSetEditing, isEditing, onSetPending } = useChangeStatus();
const [order, setOrder] = useState("desc");
const [selectedExtension, setSelectedExtension] = useState(null);
const { currentUser, isCurrentUserAvailable, isCurrentUserApiCalled } =
useContext(CallContext);
const notificationCount = useSelector(
(state) => state.shared.notificationCount
);
const { isDisableCallModule } = useContext(CallContext);
const {
searchedData,
handleChangeTextSearch,
handleSearchDataSpecificAPI,
searchTerm,
handleUpdateCallLog,
status,
filterAPI,
isLoading,
onSetLoading,
getCallLogFilterParams,
handleGetCallLogs,
handleGetExtensions,
} = useSearchCallLogs(true);
const dispatcher = useDispatch();
const handleOpenPopover = useCallback(
(data, e) => {
e.persist();
showPopover(e);
setCurrentData(data);
},
[showPopover]
);
const handleEditPhoneCall = () => {
hidePopover();
onSetEditing();
};
const handleGiveFeedback = (data) => {
dispatchGiveCallFeedback(data);
};
const handleEditFollowUp = async () => {
hidePopover();
await handleUpdateCallLog({
id: currentData.phone_call_item_id,
voip_call_id: currentData.voip_call_id,
follow_up_required: currentData.follow_up_required ? false : true,
__update_field_mask: {
follow_up_required: true,
},
extension_number: selectedExtension,
});
};
const onMakeCall = (e, phone_number) => {
e.stopPropagation();
makeCall(phone_number);
};
useEffect(() => {
if (status === COMPONENT_STATUS.GENERAL.SUCCESS) {
const params = getCallLogFilterParams();
handleGetCallLogs(params, true, isCurrentUserApiCalled);
}
}, [status]);
const callLogDataFetchHandler = () => {
const params = getCallLogFilterParams();
if (currentUser?.extension) {
handleGetCallLogs(params, true, isCurrentUserApiCalled);
setSelectedExtension(
selectedExtension || currentUser?.extension[0].extension_number
);
} else {
handleGetCallLogs(params, true, isCurrentUserApiCalled);
}
};
useEffect(() => {
onSetLoading();
callLogDataFetchHandler();
}, [
JSON.stringify(currentUser?.extension),
isCurrentUserApiCalledFromRedux,
JSON.stringify(filterAPI),
]);
const handleChangeTab = (tab) => {
handleActiveMenu(tab);
setOrder("desc");
if (tab === TABS_CALL_LOG.ALL.key) {
dispatcher(onResetNotificationCount(NOTIFICATION_TYPE.MISSED_CALL));
handleSearchDataSpecificAPI({
[CALL_LOGS_FILTER.MISSED_CALL]: {
key: CALL_LOGS_FILTER.MISSED_CALL,
value: null,
},
[CALL_LOGS_FILTER.FOLLOW_UP]: {
key: CALL_LOGS_FILTER.FOLLOW_UP,
value: null,
},
[CALL_LOGS_FILTER.UNHANDLED]: {
key: CALL_LOGS_FILTER.UNHANDLED,
value: false,
},
[CALL_LOGS_FILTER.EXTENSION_NUMBER]: {
filterName: CALL_LOGS_FILTER.EXTENSION_NUMBER,
value: selectedExtension,
},
});
} else if (tab === TABS_CALL_LOG.MISSED.key) {
dispatcher(onResetNotificationCount(NOTIFICATION_TYPE.MISSED_CALL));
handleSearchDataSpecificAPI({
[CALL_LOGS_FILTER.MISSED_CALL]: {
key: CALL_LOGS_FILTER.MISSED_CALL,
value: true,
},
[CALL_LOGS_FILTER.FOLLOW_UP]: {
key: CALL_LOGS_FILTER.FOLLOW_UP,
value: null,
},
[CALL_LOGS_FILTER.EXTENSION_NUMBER]: {
filterName: CALL_LOGS_FILTER.EXTENSION_NUMBER,
value: selectedExtension,
},
});
} else if (tab === TABS_CALL_LOG.FOLLOW_UP.key) {
handleSearchDataSpecificAPI({
[CALL_LOGS_FILTER.MISSED_CALL]: {
key: CALL_LOGS_FILTER.MISSED_CALL,
value: null,
},
[CALL_LOGS_FILTER.FOLLOW_UP]: {
key: CALL_LOGS_FILTER.FOLLOW_UP,
value: true,
},
[CALL_LOGS_FILTER.EXTENSION_NUMBER]: {
filterName: CALL_LOGS_FILTER.EXTENSION_NUMBER,
value: selectedExtension,
},
});
} else if (tab === TABS_CALL_LOG.UNHANDLED.key) {
handleSearchDataSpecificAPI({
[CALL_LOGS_FILTER.MISSED_CALL]: {
key: CALL_LOGS_FILTER.MISSED_CALL,
value: null,
},
[CALL_LOGS_FILTER.FOLLOW_UP]: {
key: CALL_LOGS_FILTER.FOLLOW_UP,
value: null,
},
[CALL_LOGS_FILTER.UNHANDLED]: {
key: CALL_LOGS_FILTER.UNHANDLED,
value: true,
},
[CALL_LOGS_FILTER.EXTENSION_NUMBER]: {
filterName: CALL_LOGS_FILTER.EXTENSION_NUMBER,
value: selectedExtension,
},
});
}
};
useEffect(() => {
if (
notificationCount.unhandled_call > 0 &&
activeMenu === TABS_CALL_LOG.UNHANDLED.key
) {
handleSearchDataSpecificAPI({
[CALL_LOGS_FILTER.MISSED_CALL]: {
key: CALL_LOGS_FILTER.MISSED_CALL,
value: null,
},
[CALL_LOGS_FILTER.FOLLOW_UP]: {
key: CALL_LOGS_FILTER.FOLLOW_UP,
value: null,
},
[CALL_LOGS_FILTER.UNHANDLED]: {
key: CALL_LOGS_FILTER.UNHANDLED,
value: notificationCount.unhandled_call,
},
[CALL_LOGS_FILTER.EXTENSION_NUMBER]: {
filterName: CALL_LOGS_FILTER.EXTENSION_NUMBER,
value: selectedExtension,
},
});
}
}, [notificationCount.unhandled_call]);
useEffect(() => {
dispatcher(
onSortDataByField({
field: "call_date_time",
order: order,
})
);
}, [order]);
const getActionsList = () => {
let callActions = [
{
label: "Make a Call",
onClick: (e) => onMakeCall(e, currentData?.phone_number),
},
];
if (isDisableCallModule) {
callActions = [];
}
if (currentData?.entity_type === "Patient")
return [
{
label: "Patient Profile",
onClick: () => {
showPatientModal(currentData.entity_id, 1, currentData.practice_id);
},
hidable: false,
},
...callActions,
{
label: "Send Message",
onClick: () => {
startChatConversation(
currentData.entity_id,
currentData.phone_number.replace("+1", "")
);
},
hidable: false,
},
{
label: currentData?.follow_up_required
? "Remove Follow Up Later"
: "Follow Up Later",
onClick: handleEditFollowUp,
},
{ label: "Edit Phone Call", onClick: handleEditPhoneCall },
{
label: "Give Feedback",
onClick: () => {
handleGiveFeedback(currentData);
},
},
];
else
return [
...callActions,
{
label: currentData?.follow_up_required
? "Remove Follow Up Later"
: "Follow Up Later",
onClick: handleEditFollowUp,
},
{ label: "Edit Phone Call", onClick: handleEditPhoneCall },
{
label: "Give Feedback",
onClick: () => {
handleGiveFeedback(currentData);
},
},
];
};
// this is for testing purpose
// useEffect(async () => {
// await Â(5000);
// for (let i = 0; i < callLogsSK.length; i++) {
// console.log("TEST");
// await setTimeOutAsync(2000);
// wsEventHandlers.onMessageReceived({
// data: JSON.stringify(callLogsSK[i]),
// });
// }
// }, []);
useEffect(() => {
dispatcher(onResetNotificationCount(NOTIFICATION_TYPE.MISSED_CALL));
return () => {
setSelectedExtension(null);
};
}, []);
const loadingHandler = () => {
if (!isCurrentUserAvailable) {
return false;
}
return isLoading;
};
const onRefresh = (customParams = {}, isCurrentUserApiCalled = false) => {
let params = getCallLogFilterParams();
params = {
...params,
...customParams,
};
handleGetCallLogs(params, true, isCurrentUserApiCalled);
};
const renderColumns = () => {
let columns = [
{
...TableCallLogConfiguration.columns.callDetails,
},
{
...TableCallLogConfiguration.columns.callRecording,
},
{
...TableCallLogConfiguration.columns.date,
},
];
if (!window?.voip_current_user_permission?.call_recording_soft_dialer) {
columns = [
{
...TableCallLogConfiguration.columns.callDetails,
},
{
...TableCallLogConfiguration.columns.date,
},
];
}
return columns;
};
const displayExtensionNumber = () => {
return (
get(window, "user_is_super_admin", false) ||
get(
window,
"voip_current_user_permission.view_call_logs_for_all_extensions",
false
)
);
};
return (
<div className="full-width flex-1 align-v-start logs-container">
{!isEditing && (
<>
<div className="post-heading-area full-width">
<ActionsBar
onSearch={handleSearchDataSpecificAPI}
filter={filterAPI}
// extensions={getExtensionNumber(extensions?.content || [])}
extensions={[]}
isSuperUser={displayExtensionNumber()}
onRefresh={onRefresh}
handleChangeTextSearch={handleChangeTextSearch}
searchTerm={searchTerm}
handleExtensionHandler={setSelectedExtension}
selectedExtension={selectedExtension}
/>
{displayExtensionNumber() && (
<SearchBar
value={searchTerm}
onChange={handleChangeTextSearch}
customStyle={{ marginBottom: "10px", marginTop: "0px" }}
inputCustomStyle={{ marginTop: "7px", marginBottom: "7px" }}
/>
)}
</div>
<TabChanger
onChange={handleChangeTab}
currentTab={activeMenu}
tabs={[
{ name: TABS_CALL_LOG.ALL.label, key: TABS_CALL_LOG.ALL.key },
{
name: TABS_CALL_LOG.MISSED.label,
key: TABS_CALL_LOG.MISSED.key,
customTitle:
missedCallCount > 0 ? (
<div>
Missed Call
<span className="table__notiCount">
{missedCallCount}
</span>
</div>
) : (
<div>Missed Call</div>
),
},
{
name: TABS_CALL_LOG.FOLLOW_UP.label,
key: TABS_CALL_LOG.FOLLOW_UP.key,
},
{
name: TABS_CALL_LOG.UNHANDLED.label,
key: TABS_CALL_LOG.UNHANDLED.key,
},
]}
/>
{/* <div className="call-log-container full-width"> */}
<span className="mt-10"></span>
<CustomizedGrid
columns={renderColumns()}
renderChildren
noDataText={
isCurrentUserApiCalledFromRedux &&
!currentUser?.extension &&
!get(window, "user_is_super_admin", false)
? "User has no extension number"
: "There's nothing in here"
}
// isLoading={loadingHandler()}
isLoading={isLoading}
data={searchedData}
tableContentClassName={`table__call-log-content ${
get(window, "user_is_super_admin", false)
? "table__call-log-content-admin"
: ""
}`}
headerStyle={{
borderTopLeftRadius: "10px",
borderTopRightRadius: "10px",
}}
>
{searchedData.map((log, index) => (
<div className="full-width" key={log.voip_call_id}>
<CallLogItem
callerName={log.caller_name}
callType={log.call_type}
phoneNumber={log.phone_number}
time={log.call_time}
date={log.call_date}
entityType={log.entity_type}
messageUuid={log.voip_call_id}
duration={log.talk_time}
callDateTime={log.call_date_time}
data={log}
handleOpenPopover={handleOpenPopover}
voipCalls={searchedData}
/>
</div>
))}
</CustomizedGrid>
</>
)}
{isEditing && (
<EditPhoneCall
goBack={onSetPending}
data={currentData}
extension_number={selectedExtension}
handleUpdateCallLog={handleUpdateCallLog}
updateCurrentData={setCurrentData}
/>
)}
<CustomPopover
{...{
target,
hidePopover,
showPopover,
show,
defaultPlacement: "left",
}}
>
<CustomList actions={getActionsList()} hidePopover={hidePopover} />
</CustomPopover>
</div>
);
};
export default CallLogContainer;