Skip to content

Commit e1989bc

Browse files
committed
fix: calling sidebar, phone search, card padding, and IVR path across flows
- Fix calling sidebar submenu collapsing by using /calling as parent path - Add phone number search to call logs with debounced input - Add consistent padding to calling view table cards - Accumulate IVR path across goto_flow transitions instead of overwriting
1 parent 4514cb3 commit e1989bc

File tree

10 files changed

+51
-8
lines changed

10 files changed

+51
-8
lines changed

frontend/src/components/layout/navigation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export const navigationItems: NavItem[] = [
9898
},
9999
{
100100
name: 'nav.calling',
101-
path: '/calling/logs',
101+
path: '/calling',
102102
icon: Phone,
103103
permission: 'call_logs',
104104
childPermissions: ['call_logs', 'ivr_flows', 'call_transfers'],

frontend/src/i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,7 @@
20922092
"error": "Error",
20932093
"rootMenu": "Root Menu",
20942094
"noCallLogs": "No call logs found.",
2095+
"searchByPhone": "Search phone number",
20952096
"filterByStatus": "Filter by status",
20962097
"filterByDirection": "Filter by direction",
20972098
"filterByIVRFlow": "Filter by IVR flow",

frontend/src/router/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ const router = createRouter({
218218
component: () => import('@/views/settings/CustomActionsView.vue'),
219219
meta: { permission: 'custom_actions' }
220220
},
221+
{
222+
path: 'calling',
223+
redirect: '/calling/logs'
224+
},
221225
{
222226
path: 'calling/logs',
223227
name: 'call-logs',

frontend/src/services/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ export const outgoingCallsService = {
944944
}
945945

946946
export const callLogsService = {
947-
list: (params?: { status?: string; account?: string; contact_id?: string; direction?: string; ivr_flow_id?: string; from?: string; to?: string; page?: number; limit?: number }) =>
947+
list: (params?: { status?: string; account?: string; contact_id?: string; direction?: string; ivr_flow_id?: string; phone?: string; from?: string; to?: string; page?: number; limit?: number }) =>
948948
api.get<{ call_logs: CallLog[]; total: number }>('/call-logs', { params }),
949949
get: (id: string) => api.get<CallLog>(`/call-logs/${id}`),
950950
getRecordingURL: (id: string) =>

frontend/src/stores/calling.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export const useCallingStore = defineStore('calling', () => {
4646
contact_id?: string
4747
direction?: string
4848
ivr_flow_id?: string
49+
phone?: string
4950
from?: string
5051
to?: string
5152
page?: number

frontend/src/views/calling/CallLogsView.vue

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
1010
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'
1111
import { Phone, PhoneIncoming, PhoneOutgoing, PhoneOff, PhoneMissed, Clock, RefreshCw, Mic } from 'lucide-vue-next'
1212
import DataTable, { type Column } from '@/components/shared/DataTable.vue'
13+
import SearchInput from '@/components/shared/SearchInput.vue'
1314
1415
const { t } = useI18n()
1516
const store = useCallingStore()
1617
1718
// Filters
19+
const phoneSearch = ref('')
1820
const statusFilter = ref('all')
1921
const accountFilter = ref('all')
2022
const directionFilter = ref('all')
2123
const ivrFlowFilter = ref('all')
2224
const currentPage = ref(1)
25+
let searchTimeout: number | null = null
2326
const pageSize = 20
2427
const accounts = ref<{ name: string }[]>([])
2528
const ivrFlows = ref<IVRFlow[]>([])
@@ -56,6 +59,7 @@ function fetchLogs() {
5659
account: accountFilter.value !== 'all' ? accountFilter.value : undefined,
5760
direction: directionFilter.value !== 'all' ? directionFilter.value : undefined,
5861
ivr_flow_id: ivrFlowFilter.value !== 'all' ? ivrFlowFilter.value : undefined,
62+
phone: phoneSearch.value || undefined,
5963
page: currentPage.value,
6064
limit: pageSize
6165
})
@@ -148,6 +152,14 @@ watch([statusFilter, accountFilter, directionFilter, ivrFlowFilter], () => {
148152
currentPage.value = 1
149153
fetchLogs()
150154
})
155+
156+
watch(phoneSearch, () => {
157+
if (searchTimeout) clearTimeout(searchTimeout)
158+
searchTimeout = window.setTimeout(() => {
159+
currentPage.value = 1
160+
fetchLogs()
161+
}, 300)
162+
})
151163
</script>
152164

153165
<template>
@@ -166,7 +178,8 @@ watch([statusFilter, accountFilter, directionFilter, ivrFlowFilter], () => {
166178
<!-- Filters -->
167179
<Card>
168180
<CardContent class="pt-6">
169-
<div class="flex gap-4 flex-wrap">
181+
<div class="flex gap-4 flex-wrap items-center">
182+
<SearchInput v-model="phoneSearch" :placeholder="t('calling.searchByPhone')" class="w-48" />
170183
<Select v-model="statusFilter">
171184
<SelectTrigger class="w-48">
172185
<SelectValue :placeholder="t('calling.filterByStatus')" />
@@ -218,7 +231,7 @@ watch([statusFilter, accountFilter, directionFilter, ivrFlowFilter], () => {
218231

219232
<!-- Table -->
220233
<Card>
221-
<CardContent class="p-0">
234+
<CardContent class="pt-6">
222235
<DataTable
223236
:items="store.callLogs"
224237
:columns="columns"

frontend/src/views/calling/CallTransfersView.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ onMounted(() => {
121121

122122
<TabsContent value="waiting" class="mt-4">
123123
<Card>
124-
<CardContent class="p-0">
124+
<CardContent class="pt-6">
125125
<DataTable
126126
:items="store.waitingTransfers"
127127
:columns="waitingColumns"
@@ -160,7 +160,7 @@ onMounted(() => {
160160

161161
<TabsContent value="history" class="mt-4">
162162
<Card>
163-
<CardContent class="p-0">
163+
<CardContent class="pt-6">
164164
<DataTable
165165
:items="historyTransfers"
166166
:columns="historyColumns"

frontend/src/views/calling/IVRFlowsView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ onMounted(async () => {
197197

198198
<!-- Flows Table -->
199199
<Card>
200-
<CardContent class="p-0">
200+
<CardContent class="pt-6">
201201
<Table>
202202
<TableHeader>
203203
<TableRow>

internal/calling/ivr.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,26 @@ func (m *Manager) runIVRFlow(session *CallSession, waAccount *whatsapp.Account)
4141
// Set parent references for submenus
4242
setMenuParents(&rootMenu, nil)
4343

44-
// Track path through IVR
44+
// Track path through IVR — load existing steps so goto_flow accumulates
4545
var ivrPath []map[string]string
46+
var existingLog models.CallLog
47+
if err := m.db.Select("ivr_path").Where("id = ?", session.CallLogID).First(&existingLog).Error; err == nil {
48+
if existingLog.IVRPath != nil {
49+
if steps, ok := existingLog.IVRPath["steps"].([]interface{}); ok {
50+
for _, s := range steps {
51+
if stepMap, ok := s.(map[string]interface{}); ok {
52+
entry := map[string]string{}
53+
for k, v := range stepMap {
54+
if str, ok := v.(string); ok {
55+
entry[k] = str
56+
}
57+
}
58+
ivrPath = append(ivrPath, entry)
59+
}
60+
}
61+
}
62+
}
63+
}
4664

4765
// Start at the root menu
4866
currentMenu := &rootMenu

internal/handlers/call_logs.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func (a *App) ListCallLogs(r *fastglue.Request) error {
2222
contactIDStr := string(r.RequestCtx.QueryArgs().Peek("contact_id"))
2323
direction := string(r.RequestCtx.QueryArgs().Peek("direction"))
2424
ivrFlowID := string(r.RequestCtx.QueryArgs().Peek("ivr_flow_id"))
25+
phone := string(r.RequestCtx.QueryArgs().Peek("phone"))
2526

2627
query := a.DB.Where("call_logs.organization_id = ?", orgID).
2728
Preload("Contact").
@@ -56,6 +57,11 @@ func (a *App) ListCallLogs(r *fastglue.Request) error {
5657
query = query.Where("call_logs.ivr_flow_id = ?", ivrFlowID)
5758
countQuery = countQuery.Where("ivr_flow_id = ?", ivrFlowID)
5859
}
60+
if phone != "" {
61+
phoneLike := "%" + phone + "%"
62+
query = query.Where("call_logs.caller_phone LIKE ?", phoneLike)
63+
countQuery = countQuery.Where("caller_phone LIKE ?", phoneLike)
64+
}
5965

6066
// Date range filter
6167
if start, ok := parseDateParam(r, "start_date"); ok {

0 commit comments

Comments
 (0)