fix: improve empty screen for call history (#27231)
* Improve empty screen * fix type error --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com>
This commit is contained in:
co-authored by
CarinaWolli
parent
f5d79a1470
commit
216e871b22
@@ -1,6 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { getCoreRowModel, getSortedRowModel, useReactTable, type ColumnDef } from "@tanstack/react-table";
|
||||
import {
|
||||
getCoreRowModel,
|
||||
getSortedRowModel,
|
||||
useReactTable,
|
||||
type ColumnDef,
|
||||
} from "@tanstack/react-table";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useMemo, useState, useReducer } from "react";
|
||||
|
||||
@@ -10,15 +16,23 @@ import {
|
||||
convertFacetedValuesToMap,
|
||||
useDataTable,
|
||||
} from "@calcom/features/data-table";
|
||||
import { DataTableWrapper, DataTableToolbar, DataTableFilters } from "~/data-table/components";
|
||||
import {
|
||||
DataTableWrapper,
|
||||
DataTableToolbar,
|
||||
DataTableFilters,
|
||||
} from "~/data-table/components";
|
||||
import { useSegments } from "@calcom/features/data-table/hooks/useSegments";
|
||||
import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider";
|
||||
import type { CallDetailsState, CallDetailsAction } from "@calcom/features/ee/workflows/lib/types";
|
||||
import type {
|
||||
CallDetailsState,
|
||||
CallDetailsAction,
|
||||
} from "@calcom/features/ee/workflows/lib/types";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { Badge } from "@calcom/ui/components/badge";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
|
||||
import { CallDetailsSheet } from "@calcom/web/modules/ee/workflows/components/CallDetailsSheet";
|
||||
|
||||
@@ -47,7 +61,10 @@ const initialState: CallDetailsState = {
|
||||
},
|
||||
};
|
||||
|
||||
function reducer(state: CallDetailsState, action: CallDetailsAction): CallDetailsState {
|
||||
function reducer(
|
||||
state: CallDetailsState,
|
||||
action: CallDetailsAction
|
||||
): CallDetailsState {
|
||||
switch (action.type) {
|
||||
case "OPEN_CALL_DETAILS":
|
||||
return { ...state, callDetailsSheet: action.payload };
|
||||
@@ -65,7 +82,11 @@ function CallHistoryTable(props: CallHistoryProps) {
|
||||
const pathname = usePathname();
|
||||
if (!pathname) return null;
|
||||
return (
|
||||
<DataTableProvider tableIdentifier={pathname} useSegments={useSegments} defaultPageSize={25}>
|
||||
<DataTableProvider
|
||||
tableIdentifier={pathname}
|
||||
useSegments={useSegments}
|
||||
defaultPageSize={25}
|
||||
>
|
||||
<CallHistoryContent {...props} />
|
||||
</DataTableProvider>
|
||||
);
|
||||
@@ -95,20 +116,29 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
|
||||
return callsData.calls.map((call) => ({
|
||||
id: call.call_id || Math.random().toString(),
|
||||
time: call.start_timestamp ? new Date(call.start_timestamp).toISOString() : new Date().toISOString(),
|
||||
time: call.start_timestamp
|
||||
? new Date(call.start_timestamp).toISOString()
|
||||
: new Date().toISOString(),
|
||||
duration: Math.round((call.duration_ms || 0) / 1000),
|
||||
channelType: (call.call_type || "phone_call") as "web_call" | "phone_call",
|
||||
channelType: (call.call_type || "phone_call") as
|
||||
| "web_call"
|
||||
| "phone_call",
|
||||
sessionId: call.call_id || t("unknown"),
|
||||
endReason: call.disconnection_reason || t("unknown"),
|
||||
sessionStatus:
|
||||
call.call_status === "ended" ? "completed" : call.call_status === "ongoing" ? "ongoing" : "failed",
|
||||
call.call_status === "ended"
|
||||
? "completed"
|
||||
: call.call_status === "ongoing"
|
||||
? "ongoing"
|
||||
: "failed",
|
||||
userSentiment:
|
||||
call.call_analysis?.user_sentiment?.toLowerCase() === "positive"
|
||||
? "positive"
|
||||
: call.call_analysis?.user_sentiment?.toLowerCase() === "negative"
|
||||
? "negative"
|
||||
: "neutral",
|
||||
from: "from_number" in call ? call.from_number || t("unknown") : t("unknown"),
|
||||
from:
|
||||
"from_number" in call ? call.from_number || t("unknown") : t("unknown"),
|
||||
to: "to_number" in call ? call.to_number || t("unknown") : t("unknown"),
|
||||
callCreated: call.call_analysis?.call_successful ?? true,
|
||||
inVoicemail: call.call_analysis?.in_voicemail ?? false,
|
||||
@@ -141,7 +171,11 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
const seconds = row.original.duration;
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return <span>{`${minutes}:${remainingSeconds.toString().padStart(2, "0")}`}</span>;
|
||||
return (
|
||||
<span>{`${minutes}:${remainingSeconds
|
||||
.toString()
|
||||
.padStart(2, "0")}`}</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -159,7 +193,9 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
accessorKey: "sessionId",
|
||||
header: t("session_id"),
|
||||
size: 210,
|
||||
cell: ({ row }) => <code className="text-xs">{row.original.sessionId}</code>,
|
||||
cell: ({ row }) => (
|
||||
<code className="text-xs">{row.original.sessionId}</code>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "endReason",
|
||||
@@ -178,7 +214,12 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const status = row.original.sessionStatus;
|
||||
const variant = status === "completed" ? "green" : status === "ongoing" ? "blue" : "red";
|
||||
const variant =
|
||||
status === "completed"
|
||||
? "green"
|
||||
: status === "ongoing"
|
||||
? "blue"
|
||||
: "red";
|
||||
return <Badge variant={variant}>{status}</Badge>;
|
||||
},
|
||||
},
|
||||
@@ -192,7 +233,12 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const sentiment = row.original.userSentiment;
|
||||
const variant = sentiment === "positive" ? "green" : sentiment === "negative" ? "red" : "gray";
|
||||
const variant =
|
||||
sentiment === "positive"
|
||||
? "green"
|
||||
: sentiment === "negative"
|
||||
? "red"
|
||||
: "gray";
|
||||
return <Badge variant={variant}>{sentiment}</Badge>;
|
||||
},
|
||||
},
|
||||
@@ -216,7 +262,11 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
cell: ({ row }) => {
|
||||
const created = row.original.callCreated;
|
||||
const variant = created ? "green" : "red";
|
||||
return <Badge variant={variant}>{created ? t("successful") : t("unsuccessful")}</Badge>;
|
||||
return (
|
||||
<Badge variant={variant}>
|
||||
{created ? t("successful") : t("unsuccessful")}
|
||||
</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -227,7 +277,9 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
cell: ({ row }) => {
|
||||
const inVoicemail = row.original.inVoicemail;
|
||||
const variant = inVoicemail ? "blue" : "gray";
|
||||
return <Badge variant={variant}>{inVoicemail ? t("yes") : t("no")}</Badge>;
|
||||
return (
|
||||
<Badge variant={variant}>{inVoicemail ? t("yes") : t("no")}</Badge>
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -286,7 +338,9 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
paginationMode="standard"
|
||||
rowClassName="cursor-pointer hover:bg-subtle"
|
||||
onRowMouseclick={(row) => {
|
||||
const callIndex = callHistoryData.findIndex((call) => call.id === row.original.id);
|
||||
const callIndex = callHistoryData.findIndex(
|
||||
(call) => call.id === row.original.id
|
||||
);
|
||||
if (callIndex !== -1 && callsData?.calls?.[callIndex]) {
|
||||
dispatch({
|
||||
type: "OPEN_CALL_DETAILS",
|
||||
@@ -312,14 +366,29 @@ function CallHistoryContent({ org: _org }: CallHistoryProps) {
|
||||
EmptyView={
|
||||
<EmptyScreen
|
||||
Icon="phone"
|
||||
headline={searchTerm ? t("no_result_found_for", { searchTerm }) : t("no_call_history")}
|
||||
headline={
|
||||
searchTerm
|
||||
? t("no_result_found_for", { searchTerm })
|
||||
: t("no_call_history")
|
||||
}
|
||||
description={t("no_call_history_description")}
|
||||
className="mb-16"
|
||||
buttonRaw={
|
||||
!searchTerm && (
|
||||
<Button>
|
||||
<Link href="/workflow/new?action=calAi&templateWorkflowId=wf-11">
|
||||
{t("create_first_workflow")}
|
||||
</Link>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
{state.callDetailsSheet.showModal && <CallDetailsSheet state={state} dispatch={dispatch} />}
|
||||
{state.callDetailsSheet.showModal && (
|
||||
<CallDetailsSheet state={state} dispatch={dispatch} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1016,7 +1016,8 @@
|
||||
"new_team_event_type_description": "Event types enable the team to share links that show available times on their calendars and allow people to make bookings with the team.",
|
||||
"event_type_created_successfully": "{{eventTypeTitle}} event type created successfully",
|
||||
"no_call_history": "No call history",
|
||||
"no_call_history_description": "No matching call history found for the particular account/search query.",
|
||||
"no_call_history_description": "Create your first Cal.ai workflow and view your call history here.",
|
||||
"create_first_workflow": "Create a Cal.ai workflow",
|
||||
"event_type_updated_successfully": "{{eventTypeTitle}} event type updated successfully",
|
||||
"event_type_deleted_successfully": "Event type deleted successfully",
|
||||
"hours": "Hours",
|
||||
|
||||
Reference in New Issue
Block a user