diff --git a/src/api/conversations.js b/src/api/conversations.js index 973f3f56..4a7b925c 100644 --- a/src/api/conversations.js +++ b/src/api/conversations.js @@ -17,15 +17,21 @@ export function getConversations (options) { const from = _.get(options, 'from', '') const to = _.get(options, 'to', '') const direction = _.get(options, 'direction', '') + const subscriberId = _.get(options, 'subscriberId') + const noCount = _.get(options, 'no_count') const params = { - subscriber_id: _.get(options, 'subscriberId'), order_by: _.get(options, 'order_by', 'timestamp'), order_by_direction: 'desc', - no_count: true, tz: 'UTC', page: _.get(options, 'page', 1), rows: _.get(options, 'rows', LIST_DEFAULT_ROWS) } + if (noCount !== null) { + params.no_count = noCount + } + if (subscriberId !== null) { + params.subscriber_id = subscriberId + } if (type !== null) { params.type = type } diff --git a/src/components/CscMainMenuTop.vue b/src/components/CscMainMenuTop.vue index a3303bd0..ba6dbc44 100644 --- a/src/components/CscMainMenuTop.vue +++ b/src/components/CscMainMenuTop.vue @@ -149,6 +149,20 @@ export default { label: this.$t('Fax Settings'), visible: this.hasFaxCapability && this.hasSubscriberProfileAttribute(PROFILE_ATTRIBUTE_MAP.faxServer) }, + { + icon: 'fas fa-chart-line', + label: this.$t('PBX Statistics'), + visible: this.isPbxAdmin, + opened: this.isPbxConfiguration, + children: [ + { + to: '/user/pbx-statistics/cdr', + icon: 'fas fa-table', + label: this.$t('Cdr'), + visible: true + } + ] + }, { icon: 'miscellaneous_services', label: this.$t('PBX Configuration'), diff --git a/src/components/pages/PbxStatistics/CscCdrFilters.vue b/src/components/pages/PbxStatistics/CscCdrFilters.vue new file mode 100644 index 00000000..54e65335 --- /dev/null +++ b/src/components/pages/PbxStatistics/CscCdrFilters.vue @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/i18n/en.json b/src/i18n/en.json index bbe1e1c9..17a48c4a 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -56,6 +56,7 @@ "Block outgoing": "Block outgoing", "Busy Greeting": "Busy Greeting", "Busy Lamp Field": "Busy Lamp Field", + "CDR": "CDR", "CLI": "CLI", "Call": "Call", "Call Blocking": "Call Blocking", @@ -81,6 +82,7 @@ "Calls, Faxes, VoiceMails": "Calls, Faxes, VoiceMails", "Cancel": "Cancel", "Cancel Mode": "Cancel Mode", + "Cdr": "Cdr", "Change Email": "Change Email", "Change PIN": "Change PIN", "Change Password": "Change Password", @@ -146,6 +148,7 @@ "Destination must not be empty": "Destination must not be empty", "Destinations": "Destinations", "Devices": "Devices", + "Direction": "Direction", "Disable": "Disable", "Display Name": "Display Name", "Do not ring primary number": "Do not ring primary number", @@ -219,8 +222,10 @@ "If available": "If available", "If busy": "If busy", "If not available": "If not available", + "In": "In", "In call with": "In call with", "In call with {number}": "In call with {number}", + "In/Out": "In/Out", "Incoming": "Incoming", "Incoming call from": "Incoming call from", "Incoming call from {number}": "Incoming call from {number}", @@ -308,8 +313,10 @@ "Only incoming calls from listed numbers are allowed": "Only incoming calls from listed numbers are allowed", "Only once": "Only once", "Only outgoing calls to listed numbers are allowed": "Only outgoing calls to listed numbers are allowed", + "Out": "Out", "Outgoing": "Outgoing", "PBX Configuration": "PBX Configuration", + "PBX Statistics": "PBX Statistics", "PIN": "PIN", "Page Header": "Page Header", "Page not found": "Page not found", @@ -429,6 +436,7 @@ "Slot {number}": "Slot {number}", "Slots saved successfully": "Slots saved successfully", "Slots successfully added": "Slots successfully added", + "Sms": "Sms", "Something went wrong. Please retry later": "Something went wrong. Please retry later", "Sound Set": "Sound Set", "Sound Sets": "Sound Sets", @@ -439,6 +447,7 @@ "Start time": "Start time", "Start time should be less than End time": "Start time should be less than End time", "Station name": "Station name", + "Status": "Status", "Su": "Su", "Subscriber": "Subscriber", "Subscriber Phonebook": "Subscriber Phonebook", @@ -509,6 +518,7 @@ "Wrap Up Time": "Wrap Up Time", "Wrap up time": "Wrap up time", "Wrong username or password": "Wrong username or password", + "Xmpp": "Xmpp", "Yesterday": "Yesterday", "You are about to change your login password. After the password was changed successfully, you get automatically logged out to authenticate with the new password. ": "You are about to change your login password. After the password was changed successfully, you get automatically logged out to authenticate with the new password. ", "You are about to delete recording #{id}": "You are about to delete recording #{id}", diff --git a/src/pages/CscPagePbxStatisticsCdr.vue b/src/pages/CscPagePbxStatisticsCdr.vue new file mode 100644 index 00000000..82d0bb82 --- /dev/null +++ b/src/pages/CscPagePbxStatisticsCdr.vue @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + {{ $t('Refresh') }} + + + + + + + + + diff --git a/src/router/routes.js b/src/router/routes.js index 98b6051f..cab03066 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -37,6 +37,7 @@ import CscPagePbxSettingsCallQueues from 'pages/CscPagePbxSettingsCallQueues' import CscPagePbxSoundSetDetails from 'src/pages/CscPagePbxSoundSetDetails' import CscPageSubscriberPhonebookDetails from 'src/pages/CscPageSubscriberPhonebookDetails' import CscPageSubscriberPhonebookAdd from 'src/pages/CscPageSubscriberPhonebookAdd' +import CscPagePbxStatisticsCdr from 'src/pages/CscPagePbxStatisticsCdr' import { i18n } from 'src/boot/i18n' const getToken = (route) => { @@ -201,6 +202,18 @@ const routes = [ profileAttribute: PROFILE_ATTRIBUTE_MAP.speedDial } }, + { + path: 'pbx-statistics/cdr', + component: CscPagePbxStatisticsCdr, + meta: { + get title () { + return i18n.global.tc('PBX Statistics') + }, + get subtitle () { + return i18n.global.tc('CDR') + } + } + }, { path: 'pbx-configuration/groups', component: CscPagePbxGroups, diff --git a/src/store/conversations/actions.js b/src/store/conversations/actions.js index 1104ef84..50bb4e0b 100644 --- a/src/store/conversations/actions.js +++ b/src/store/conversations/actions.js @@ -26,6 +26,18 @@ const ReloadConfig = { } export default { + async loadConversations ({ commit, dispatch, state, rootGetters }, options) { + try { + const list = await getConversations({ + ...options + }) + commit('setConversations', list.items) + return list.totalCount + } catch (err) { + commit('setConversations', []) + throw err + } + }, reloadItems (context, options) { context.commit('reloadItemsRequesting') const rows = context.state.currentPage * ROWS_PER_PAGE @@ -37,7 +49,8 @@ export default { subscriberId: context.getters.getSubscriberId, page: 1, rows: rows, - type: options.type + type: options.type, + no_count: true }).then((result) => { const firstResultItemTimestamp = result.items[0] ? result.items[0].start_time @@ -95,7 +108,8 @@ export default { type: options.type, from: _.get(options, 'filter.from', ''), to: _.get(options, 'filter.to', ''), - direction: _.get(options, 'filter.direction', '') + direction: _.get(options, 'filter.direction', ''), + no_count: true }) context.commit('nextPageSucceeded', res) } catch (err) { diff --git a/src/store/conversations/mutations.js b/src/store/conversations/mutations.js index bc55460b..45d803a6 100644 --- a/src/store/conversations/mutations.js +++ b/src/store/conversations/mutations.js @@ -155,5 +155,8 @@ export default { deletionFailed (state, err) { state.deletionState = RequestState.failed state.deletionError = err + }, + setConversations (state, value) { + state.conversations = value } }