feat: Complete API binding

This commit is contained in:
Muhsin Keloth
2024-03-29 12:27:52 +05:30
parent 088795f0ad
commit 89cac2dec7
9 changed files with 370 additions and 69 deletions
@@ -0,0 +1,73 @@
/* global axios */
import ApiClient from './ApiClient';
class SLAReportsAPI extends ApiClient {
constructor() {
super('applied_slas', { accountScoped: true });
}
get({
from,
to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
page,
} = {}) {
return axios.get(this.url, {
params: {
since: from,
until: to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
page,
},
});
}
download({
from,
to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
} = {}) {
return axios.get(`${this.url}/download`, {
params: {
since: from,
until: to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
},
});
}
getMetrics({
from,
to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
} = {}) {
// no ratings for metrics
return axios.get(`${this.url}/metrics`, {
params: {
since: from,
until: to,
assigned_agent_id,
inbox_id,
team_id,
sla_policy_id,
},
});
}
}
export default new SLAReportsAPI();
@@ -1,10 +1,20 @@
<template>
<div class="flex flex-col flex-1 gap-6 p-4 overflow-auto font-inter">
<SLAMetrics :hit-rate="`12%`" :no-of-breaches="5" />
<SLATable />
<SLAMetrics
:hit-rate="slaMetrics.hitRate"
:no-of-breaches="slaMetrics.numberOfSLABreaches"
/>
<SLATable
:sla-reports="slaReports"
:current-page="Number(slaMeta.currentPage)"
:total-count="Number(slaMeta.count)"
:page-size="3"
@page-change="onPageChange"
/>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import SLAMetrics from './components/SLA/SLAMetrics.vue';
import SLATable from './components/SLA/SLATable.vue';
export default {
@@ -13,5 +23,31 @@ export default {
SLAMetrics,
SLATable,
},
data() {
return {
pageNumber: 1,
};
},
computed: {
...mapGetters({
slaReports: 'slaReports/getAll',
slaMetrics: 'slaReports/getMetrics',
slaMeta: 'slaReports/getMeta',
}),
},
mounted() {
this.$store.dispatch('slaReports/getMetrics');
this.fetchSLAReports();
},
methods: {
fetchSLAReports({ pageNumber } = {}) {
this.$store.dispatch('slaReports/get', {
page: pageNumber || this.pageNumber,
});
},
onPageChange(pageNumber) {
this.fetchSLAReports({ pageNumber });
},
},
};
</script>
@@ -0,0 +1,43 @@
<script setup>
import CardLabels from 'dashboard/components/widgets/conversation/conversationCardComponents/CardLabels.vue';
defineProps({
slaName: {
type: String,
required: true,
},
conversationId: {
type: Number,
required: true,
},
});
</script>
<template>
<div
class="grid content-center h-16 grid-cols-12 gap-4 px-6 py-0 bg-white border-b border-slate-75 dark:border-slate-800/50 dark:bg-slate-900"
>
<div
class="flex items-center capitalize py-2 px-0 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 text-left rtl:text-right col-span-2"
>
{{ slaName }}
</div>
<div
class="flex items-center col-span-6 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
#{{ conversationId }} with John Doe
<card-labels :conversation-id="148" />
</div>
<div
class="flex items-center col-span-2 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
Elijah
</div>
<div
class="flex items-center col-span-2 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
<woot-button color-scheme="secondary" variant="link">
View details
</woot-button>
</div>
</div>
</template>
@@ -1,60 +1,92 @@
<template>
<div
class="min-w-full border rounded-xl border-slate-75 dark:border-slate-800/50"
>
<!-- Header -->
<div>
<div
class="grid content-center h-12 grid-cols-12 gap-4 px-6 py-0 border-b bg-slate-25 border-slate-75 dark:border-slate-800 rounded-t-xl dark:bg-slate-900"
class="min-w-full border rounded-xl border-slate-75 dark:border-slate-800/50"
>
<!-- Header -->
<div
class="flex items-center font-medium capitalize text-xs py-2 px-0 tracking-[10%] text-slate-700 dark:text-slate-100 text-left rtl:text-right col-span-2"
class="grid content-center h-12 grid-cols-12 gap-4 px-6 py-0 border-b bg-slate-25 border-slate-75 dark:border-slate-800 rounded-t-xl dark:bg-slate-900"
>
POLICY BREACHED
<div
class="flex items-center font-medium capitalize text-xs py-2 px-0 tracking-[10%] text-slate-700 dark:text-slate-100 text-left rtl:text-right col-span-2"
>
POLICY BREACHED
</div>
<div
class="flex items-center col-span-6 px-0 py-2 text-xs font-medium text-left capitalize text-slate-700 dark:text-slate-100 rtl:text-right"
>
CONVERSATION
</div>
<div
class="flex items-center px-0 text-xs font-medium text-left capitalize col-span-2py-2 text-slate-700 dark:text-slate-100 rtl:text-right"
>
AGENT
</div>
<div
class="col-span-2 px-0 py-2 text-xs font-medium text-left capitalize text-slate-700 dark:text-slate-100 rtl:text-right"
/>
</div>
<div
class="flex items-center col-span-6 px-0 py-2 text-xs font-medium text-left capitalize text-slate-700 dark:text-slate-100 rtl:text-right"
>
CONVERSATION
</div>
<div
class="flex items-center px-0 text-xs font-medium text-left capitalize col-span-2py-2 text-slate-700 dark:text-slate-100 rtl:text-right"
>
AGENT
</div>
<div
class="col-span-2 px-0 py-2 text-xs font-medium text-left capitalize text-slate-700 dark:text-slate-100 rtl:text-right"
<SLA-report-item
v-for="sla in slaReports"
:key="sla.id"
:sla-name="sla.sla_policy.name"
:conversation-id="sla.conversation.id"
/>
</div>
<div
class="grid content-center h-16 grid-cols-12 gap-4 px-6 py-0 bg-white border-b border-slate-75 dark:border-slate-800/50 dark:bg-slate-900"
>
<div
class="flex items-center capitalize py-2 px-0 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 text-left rtl:text-right col-span-2"
>
Premium SLA
</div>
<div
class="flex items-center col-span-6 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
#198 with John Doe
<card-labels :conversation-id="148" />
</div>
<div
class="flex items-center col-span-2 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
Elijah
</div>
<div
class="flex items-center col-span-2 px-0 py-2 text-sm tracking-[0.5] text-slate-700 dark:text-slate-100 rtl:text-right"
>
<woot-button color-scheme="secondary" variant="link">
View details
</woot-button>
</div>
</div>
<table-footer
v-if="shouldShowFooter"
:current-page="currentPage"
:total-count="totalCount"
:page-size="pageSize"
class="dark:bg-slate-900 sticky bottom-0"
@page-change="onPageChange"
/>
</div>
</template>
<script setup>
import CardLabels from 'dashboard/components/widgets/conversation/conversationCardComponents/CardLabels.vue';
<script>
import TableFooter from 'dashboard/components/widgets/TableFooter.vue';
import SLAReportItem from './SLAReportItem.vue';
export default {
name: 'SLATable',
components: {
SLAReportItem,
TableFooter,
},
props: {
slaReports: {
type: Array,
default: () => [],
},
totalCount: {
type: Number,
default: 0,
},
currentPage: {
type: Number,
default: 1,
},
pageSize: {
type: Number,
default: 25,
},
},
data() {
return {
pageNo: 1,
};
},
computed: {
shouldShowFooter() {
return this.currentPage === 1
? this.totalCount > this.pageSize
: this.slaReports.length > 0;
},
},
methods: {
onPageChange(page) {
this.$emit('page-change', page);
},
},
};
</script>
+2
View File
@@ -44,6 +44,7 @@ import teams from './modules/teams';
import userNotificationSettings from './modules/userNotificationSettings';
import webhooks from './modules/webhooks';
import draftMessages from './modules/draftMessages';
import SLAReports from './modules/SLAReports';
import LogRocket from 'logrocket';
import createPlugin from 'logrocket-vuex';
@@ -111,6 +112,7 @@ export default new Vuex.Store({
webhooks,
draftMessages,
sla,
slaReports: SLAReports,
},
plugins,
});
@@ -0,0 +1,99 @@
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
import types from '../mutation-types';
import SLAReportsAPI from '../../api/slaReports';
export const state = {
records: [],
metrics: {
numberOfSLABreaches: 0,
hitRate: '0%',
},
uiFlags: {
isFetching: false,
isFetchingMetrics: false,
},
meta: {
count: 0,
currentPage: 1,
},
};
export const getters = {
getAll(_state) {
return _state.records;
},
getMeta(_state) {
return _state.meta;
},
getMetrics(_state) {
return _state.metrics;
},
getUIFlags(_state) {
return _state.uiFlags;
},
};
export const actions = {
get: async function getResponses({ commit }, params) {
commit(types.SET_SLA_REPORTS_UI_FLAG, { isFetching: true });
try {
const response = await SLAReportsAPI.get(params);
const { payload, meta } = response.data;
commit(types.SET_SLA_REPORTS, payload);
commit(types.SET_SLA_REPORTS_META, meta);
} catch (error) {
// Ignore error
} finally {
commit(types.SET_SLA_REPORTS_UI_FLAG, { isFetching: false });
}
},
getMetrics: async function getMetrics({ commit }, params) {
commit(types.SET_SLA_REPORTS_UI_FLAG, { isFetchingMetrics: true });
try {
const response = await SLAReportsAPI.getMetrics(params);
commit(types.SET_SLA_REPORTS_METRICS, response.data);
} catch (error) {
// Ignore error
} finally {
commit(types.SET_SLA_REPORTS_UI_FLAG, { isFetchingMetrics: false });
}
},
};
export const mutations = {
[types.SET_SLA_REPORTS_UI_FLAG](_state, data) {
_state.uiFlags = {
..._state.uiFlags,
...data,
};
},
[types.SET_SLA_REPORTS]: MutationHelpers.set,
[types.SET_SLA_REPORTS_METRICS](
_state,
{ number_of_sla_breaches: numberOfSLABreaches, hit_rate: hitRate }
) {
_state.metrics = {
numberOfSLABreaches,
hitRate,
};
},
[types.SET_SLA_REPORTS_META](
_state,
{ total_applied_slas: totalAppliedSLAs, current_page: currentPage }
) {
_state.meta = {
count: totalAppliedSLAs,
currentPage,
};
},
};
export default {
namespaced: true,
state,
getters,
actions,
mutations,
};
@@ -309,4 +309,10 @@ export default {
ADD_SLA: 'ADD_SLA',
EDIT_SLA: 'EDIT_SLA',
DELETE_SLA: 'DELETE_SLA',
// SLA Reports
SET_SLA_REPORTS_UI_FLAG: 'SET_SLA_REPORTS_UI_FLAG',
SET_SLA_REPORTS: 'SET_SLA_REPORTS',
SET_SLA_REPORTS_METRICS: 'SET_SLA_REPORTS_METRICS',
SET_SLA_REPORTS_META: 'SET_SLA_REPORTS_META',
};