TT#100754 Dashboard - As Customer, I want to see a Dashboard

Change-Id: Ibf6cfc82f56ae62fd1ec7997e160ca2e8025749d
mr10.0
Hugo Zigha 4 years ago committed by Hugo Zigha
parent 22739de401
commit 116773786b

@ -112,3 +112,29 @@ export async function deleteVoicemail (id) {
const res = await Vue.http.delete('api/voicemails/' + id)
return res.status >= 200
}
export function getAllVoicemails (options) {
return new Promise((resolve, reject) => {
getList({
resource: 'voicemails',
params: { subscriber_id: options.subscriberId, rows: options.rows }
}).then((result) => {
resolve(result)
}).catch((err) => {
reject(err)
})
})
}
export function getAllCalls (options) {
return new Promise((resolve, reject) => {
getList({
resource: 'conversations',
params: { subscriber_id: options.subscriberId, rows: options.rows, type: 'call' }
}).then((result) => {
resolve(result)
}).catch((err) => {
reject(err)
})
})
}

@ -57,6 +57,12 @@ export default {
]),
items () {
return [
{
to: '/user/dashboard',
icon: 'fas fa-tachometer-alt',
label: this.$t('Dashboard'),
visible: true
},
{
to: '/user/home',
icon: 'call',

@ -0,0 +1,133 @@
<template>
<q-card
dark
bordered
class="my-card csc-card-style column csc-item-odd no-wrap"
>
<q-card-section>
<div class="text-h6 text-center">
{{ title }}
</div>
</q-card-section>
<q-separator
dark
inset
/>
<q-card-section>
<div
v-if="!loading && error"
class="text-h2 text-center csc-card-data-error"
>
N/A
</div>
<div
v-if="!loading && !error"
class="text-h2 text-center"
>
{{ count }}
</div>
<div
class="text-h2 text-center"
>
<csc-spinner
v-if="loading"
/>
</div>
<div
v-if="!error"
class="text-center"
>
{{ countTitle }}
</div>
</q-card-section>
<q-separator
dark
inset
/>
<q-card-section
class="csc-card-list"
/>
<q-separator
dark
inset
/>
<q-card-section
class="text-center"
>
<q-btn
color="primary"
unelevated
flat
:label="buttonTitle"
:to="routeTo"
/>
</q-card-section>
</q-card>
</template>
<script>
import CscSpinner from 'components/CscSpinner'
export default {
name: 'CscCardDashboard',
components: {
CscSpinner
},
props: {
title: {
type: String,
default: ''
},
count: {
type: Number,
default: 0
},
countTitle: {
type: String,
default: ''
},
buttonTitle: {
type: String,
default: ''
},
itemsList: {
type: Array,
default () {
return []
}
},
routeTo: {
type: [Object, String],
required: true
},
loading: {
type: Boolean,
default: false
},
error: {
type: Boolean,
default: false
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.csc-card-style
margin 10px
width 30%
height max-content
min-width 284px
.csc-card-data-error
color: $negative
padding-bottom: 22px
.csc-card-list
min-height: 316px
</style>

@ -56,6 +56,7 @@
"Call": "Call",
"Call Blocking": "Call Blocking",
"Call Forwarding": "Call Forwarding",
"Call List": "Call List",
"Call Queue": "Call Queue",
"Call Queues": "Call Queues",
"Call Settings": "Call Settings",
@ -111,6 +112,7 @@
"Custom sound": "Custom sound",
"Customer Details": "Customer Details",
"Daily": "Daily",
"Dashboard": "Dashboard",
"Default": "Default",
"Default sound": "Default sound",
"Default sound set for all seats and groups": "Default sound set for all seats and groups",
@ -234,6 +236,7 @@
"Name": "Name",
"Name in Fax Header for Sendfax": "Name in Fax Header for Sendfax",
"Never": "Never",
"New Messages": "New Messages",
"New features": "New features",
"New password": "New password",
"New password retyped": "New password retyped",
@ -294,6 +297,7 @@
"Random Ringing": "Random Ringing",
"Receive Reports": "Receive Reports",
"Received from IP": "Received from IP",
"Recent Calls": "Recent Calls",
"Recording successfully deleted": "Recording successfully deleted",
"Recordings": "Recordings",
"Recover password": "Recover password",
@ -428,8 +432,14 @@
"User Agent": "User Agent",
"User settings": "User settings",
"Username": "Username",
"Video Call": "Video Call",
"View All Registered Devices": "View All Registered Devices",
"View Call List": "View Call List",
"View Voicebox Messages": "View Voicebox Messages",
"Voice Call": "Voice Call",
"Voice prompts language for voicemail, conference and application server": "Voice prompts language for voicemail, conference and application server",
"Voicebox": "Voicebox",
"Voicebox Messages": "Voicebox Messages",
"Voicemail": "Voicemail",
"Voicemails": "Voicemails",
"We": "We",

@ -300,7 +300,7 @@ export default {
]),
close () {
if (!this.isJoined) {
this.$router.push({ path: '/user/home' })
this.$router.push({ path: '/user/dashboard' })
this.$store.commit('conference/disposeLocalMedia')
} else {
this.$refs.confirmDialog.open()

@ -415,7 +415,7 @@ export default {
})
}
window.scrollTo(0, 0)
if (route.path === '/user/home') {
if (route.path === '/user/dashboard') {
this.forwardHome()
}
}

@ -125,12 +125,18 @@ export default {
mixins: [
platformMixin
],
props: {
initialTab: {
type: String,
default: 'call-fax-voicemail'
}
},
data () {
return {
filter: undefined,
topMargin: 0,
deletionId: null,
selectedTab: 'call-fax-voicemail'
selectedTab: this.initialTab
}
},
computed: {

@ -0,0 +1,113 @@
<template>
<csc-page
id="csc-page-dashboard"
class="row justify-center"
>
<csc-card-dashboard
:title="$t('Voicebox Messages')"
:count="voicemailsCount"
:count-title="$t('New Messages')"
:button-title="$t('View Voicebox Messages')"
:items-list="voicemailItems"
:route-to="{ name: 'CscConversations', params: { initialTab: 'voicemail' } }"
:loading="$wait.is('getVoicemailsData')"
:error="voicemailsError"
/>
<csc-card-dashboard
:title="$t('Call List')"
:count="callsCount"
:count-title="$t('Recent Calls')"
:button-title="$t('View Call List')"
:items-list="callItems"
:route-to="{ name: 'CscConversations', params: { initialTab: 'call' } }"
:loading="$wait.is('getCallsData')"
:error="callsError"
/>
<csc-card-dashboard
:title="$t('Registered Devices')"
:count="registeredDevicesCount"
:count-title="$t('Registered Devices')"
:button-title="$t('View All Registered Devices')"
:items-list="registeredDevicesItems"
:route-to="{ name: 'RegisteredDevices', params: { initialTab: 'null' } }"
:loading="$wait.is('getRegisteredDevicesData')"
:error="registeredDevicesError"
/>
</csc-page>
</template>
<script>
import CscCardDashboard from 'components/pages/Dashboard/CscCardDashboard'
import CscPage from 'components/CscPage'
import { mapWaitingActions } from 'vue-wait'
import {
showGlobalError
} from 'src/helpers/ui'
export default {
name: 'CscPageDashboard',
components: {
CscCardDashboard,
CscPage
},
data () {
return {
callItems: [],
voicemailItems: [],
registeredDevicesItems: [],
callsCount: 0,
voicemailsCount: 0,
registeredDevicesCount: 0,
voicemailsError: false,
callsError: false,
registeredDevicesError: false
}
},
mounted () {
this.loadDatas()
},
methods: {
...mapWaitingActions('dashboard', {
getCallsData: 'getCallsData',
getVoicemailsData: 'getVoicemailsData',
getRegisteredDevicesData: 'getRegisteredDevicesData'
}),
async loadDatas () {
const values = await Promise.allSettled([
this.getCallsData(),
this.getVoicemailsData(),
this.getRegisteredDevicesData()
])
this.checkResponses('calls', values[0])
this.checkResponses('voicemails', values[1])
this.checkResponses('registered-devices', values[2])
},
checkResponses (type, response) {
if (type === 'calls') {
if (response.status === 'rejected') {
this.callsError = true
showGlobalError(response?.reason?.data?.message)
} else {
this.callsCount = response.value.totalCount
this.callItems = response.value.items
}
} else if (type === 'voicemails') {
if (response.status === 'rejected') {
this.voicemailsError = true
showGlobalError(response?.reason?.data?.message)
} else {
this.voicemailsCount = response.value.totalCount
this.voicemailItems = response.value.items
}
} else if (type === 'registered-devices') {
if (response.status === 'rejected') {
this.registeredDevicesError = true
showGlobalError(response?.reason?.data?.message)
} else {
this.registeredDevicesCount = response.value.totalCount
this.registeredDevicesItems = response.value.items
}
}
}
}
}
</script>

@ -29,7 +29,7 @@
icon="home"
text-color="dark"
unelevated
to="/user/home"
to="/user/dashboard"
/>
</q-card-actions>
</q-card>

@ -30,6 +30,7 @@ import CscPageCf from 'pages/CscPageCf'
import CscPageCallSettings from 'pages/CscPageCallSettings'
import CscPageRegisteredDevices from 'pages/CscPageRegisteredDevices'
import CscPagePbxSettingsAutoAttendant from 'pages/CscPagePbxSettingsAutoAttendant'
import CscPageDashboard from 'pages/CscPageDashboard'
const getToken = (route) => {
return {
@ -44,6 +45,15 @@ export default function routes (app) {
path: '/user',
component: CscLayoutMain,
children: [
{
path: 'dashboard',
component: CscPageDashboard,
meta: {
get title () {
return i18n.t('Dashboard')
}
}
},
{
path: 'home',
component: CscPageHome,
@ -55,7 +65,9 @@ export default function routes (app) {
},
{
path: 'conversations',
name: 'CscConversations',
component: CscPageConversations,
props: true,
meta: {
get title () {
return i18n.t('Conversations')
@ -320,6 +332,7 @@ export default function routes (app) {
},
{
path: 'registered-devices',
name: 'RegisteredDevices',
component: CscPageRegisteredDevices,
meta: {
get title () {
@ -403,7 +416,7 @@ export default function routes (app) {
{
path: '/',
redirect: {
path: '/user/home'
path: '/user/dashboard'
}
},
{

@ -0,0 +1,39 @@
import {
getAllVoicemails,
getAllCalls
} from '../api/conversations'
import {
getSubscriberRegistrations
} from '../api/subscriber'
export default {
namespaced: true,
getters: {
getSubscriberId (state, getters, rootState, rootGetters) {
return parseInt(rootGetters['user/getSubscriberId'])
}
},
actions: {
async getVoicemailsData (context) {
const res = await getAllVoicemails({
subscriberId: context.getters.getSubscriberId,
rows: 5
})
return res
},
async getCallsData (context) {
const res = await getAllCalls({
subscriberId: context.getters.getSubscriberId,
rows: 5
})
return res
},
async getRegisteredDevicesData (context) {
const res = await getSubscriberRegistrations({
subscriber_id: context.getters.getSubscriberId,
rows: 5
})
return res
}
}
}

@ -26,6 +26,7 @@ import CommunicationModule from './communication'
import FaxModule from './fax'
import VoiceboxModule from './voicebox'
import ConferenceModule from './conference'
import DashboardModule from './dashboard'
import RtcEnginePlugin from 'src/plugins/rtc-engine'
import CallPlugin from 'src/plugins/call'
@ -69,7 +70,8 @@ export default function (/* { ssrContext } */) {
pbxSoundSets: PbxSoundSetsModule,
pbxMsConfigs: PbxMsConfigsModule,
callForwarding: CallForwardingModule,
pbxAutoAttendants: PbxAutoAttendants
pbxAutoAttendants: PbxAutoAttendants,
dashboard: DashboardModule
},
state: {

@ -376,7 +376,7 @@ export default {
}
},
async forwardHome (context) {
if (context.rootState.route?.path === '/user/home' && !context.getters.isRtcEngineUiVisible) {
if (context.rootState.route?.path === '/user/dashboard' && !context.getters.isRtcEngineUiVisible) {
await router.push({ path: '/user/conversations' })
}
},

Loading…
Cancel
Save