Fixes #1010 - display only used channels in dashboard
This commit is contained in:
parent
feac4bb938
commit
20ee2e87ca
4 changed files with 113 additions and 43 deletions
|
@ -15,21 +15,26 @@ class Stats extends App.Controller
|
||||||
data.StatsTicketChannelDistribution =
|
data.StatsTicketChannelDistribution =
|
||||||
channels:
|
channels:
|
||||||
1:
|
1:
|
||||||
inbound: 1
|
icon: 'email'
|
||||||
outbound: 0
|
sender: 'email'
|
||||||
inbound_in_percent: 0
|
inbound: 0
|
||||||
|
outbound: 0
|
||||||
|
inbound_in_percent: 0
|
||||||
outbound_in_percent: 0
|
outbound_in_percent: 0
|
||||||
2:
|
2:
|
||||||
inbound: 0
|
icon: 'phone'
|
||||||
outbound: 0
|
sender: 'phone'
|
||||||
inbound_in_percent: 0
|
inbound: 0
|
||||||
outbound_in_percent: 0
|
outbound: 0
|
||||||
3:
|
inbound_in_percent: 0
|
||||||
inbound: 2
|
|
||||||
outbound: 0
|
|
||||||
inbound_in_percent: 0
|
|
||||||
outbound_in_percent: 0
|
outbound_in_percent: 0
|
||||||
|
|
||||||
|
totalTickets = _.reduce data.StatsTicketChannelDistribution.channels, ((memo, channel) -> memo + channel.inbound + channel.outbound), 0
|
||||||
|
totalChannels = _.size data.StatsTicketChannelDistribution.channels
|
||||||
|
|
||||||
|
for id, channel of data.StatsTicketChannelDistribution.channels
|
||||||
|
channel.overal_percentage = Math.round((channel.inbound + channel.outbound) / totalTickets * 100)
|
||||||
|
|
||||||
data.StatsTicketChannelDistribution.description = 'How many of your tickets are coming from email, phone, Twitter, or Facebook? (Shows percentages for both inbound and outbound tickets.)'
|
data.StatsTicketChannelDistribution.description = 'How many of your tickets are coming from email, phone, Twitter, or Facebook? (Shows percentages for both inbound and outbound tickets.)'
|
||||||
|
|
||||||
content = App.view('dashboard/stats/ticket_channel_distribution')(data)
|
content = App.view('dashboard/stats/ticket_channel_distribution')(data)
|
||||||
|
|
|
@ -6,15 +6,17 @@
|
||||||
<%- @Icon('help') %>
|
<%- @Icon('help') %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-graphic">
|
<div class="stat-graphic" data-columns="<%- _.size(@StatsTicketChannelDistribution.channels) %>">
|
||||||
<% for channel_name, channel of @StatsTicketChannelDistribution.channels: %>
|
<% for id, channel of @StatsTicketChannelDistribution.channels: %>
|
||||||
<div class="stats-row email-channel">
|
<div class="stats-row">
|
||||||
<%- @Icon(channel.icon, 'stat-channel-icon') %>
|
<div title="<%- channel.sender %>">
|
||||||
<div class="stat-bars">
|
<%- @Icon(channel.icon, 'stat-channel-icon') %>
|
||||||
<div class="stat-bar primary" style="height: <%- channel.inbound_in_percent %>%" title="<%- @Ti('Inbound') %>: <%- channel.inbound_in_percent %>% (<%- channel.inbound %>)"></div>
|
|
||||||
<div class="stat-bar secondary" style="height: <%- channel.outbound_in_percent %>%" title="<%- @Ti('Outbound') %>: <%- channel.outbound_in_percent %>% (<%- channel.outbound %>)"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-label"></div>
|
<div class="stat-bars">
|
||||||
|
<div class="stat-bar stat-bar--inbound" style="height: <%- channel.inbound_in_percent %>%" title="<%- @Ti('Inbound') %>: <%- channel.inbound_in_percent %>% (<%- channel.inbound %>)"></div>
|
||||||
|
<div class="stat-bar stat-bar--outbound" style="height: <%- channel.outbound_in_percent %>%" title="<%- @Ti('Outbound') %>: <%- channel.outbound_in_percent %>% (<%- channel.outbound %>)"></div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-detail"><%- channel.overal_percentage %>%</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4982,7 +4982,7 @@ footer {
|
||||||
|
|
||||||
.stat-widget {
|
.stat-widget {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
padding: 13px;
|
padding: 10px 10px 8px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
@ -5018,12 +5018,12 @@ footer {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-widget .stat-label {
|
.stat-label {
|
||||||
color: #444a4f;
|
color: #444a4f;
|
||||||
@extend .u-textTruncate;
|
@extend .u-textTruncate;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-widget .stat-detail {
|
.stat-detail {
|
||||||
color: #b4b7b9;
|
color: #b4b7b9;
|
||||||
@extend .u-textTruncate;
|
@extend .u-textTruncate;
|
||||||
}
|
}
|
||||||
|
@ -5060,11 +5060,15 @@ footer {
|
||||||
|
|
||||||
.stats-row {
|
.stats-row {
|
||||||
padding: 8px 0 7px;
|
padding: 8px 0 7px;
|
||||||
margin-bottom: -7px;
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex: 0 1 38px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-row:hover {
|
.stats-row:hover {
|
||||||
|
@ -5072,28 +5076,30 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-row .stat-bars {
|
.stats-row .stat-bars {
|
||||||
height: 73px;
|
flex: 1;
|
||||||
margin: 16px 0 15px;
|
margin: 10px 0 13px;
|
||||||
padding: 2px 12px;
|
padding: 2px 5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(to top, #f2f2f3, #f2f2f3 1px, transparent 1px);
|
background: linear-gradient(to top, #f2f2f3, #f2f2f3 1px, transparent 1px);
|
||||||
background-position: center bottom;
|
background-position: center bottom;
|
||||||
background-size: 100% 12px;
|
background-size: 100% 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-bars .stat-bar {
|
.stat-bars .stat-bar {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 10px;
|
max-width: 10px;
|
||||||
|
flex: 1;
|
||||||
color: #a9bcc4;
|
color: #a9bcc4;
|
||||||
background: #a9bcc4;
|
background: #a9bcc4;
|
||||||
}
|
|
||||||
|
|
||||||
.stat-widget .secondary {
|
&--outbound {
|
||||||
opacity: .38;
|
opacity: .38;
|
||||||
color: #a9bcc4;
|
color: #a9bcc4;
|
||||||
background: #a9bcc4;
|
background: #a9bcc4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-legend {
|
.stat-legend {
|
||||||
|
@ -5118,6 +5124,17 @@ footer {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ticket_channel_distribution {
|
||||||
|
.stat-graphic {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-row {
|
||||||
|
margin-bottom: -4px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.frequency.stat-widget {
|
.frequency.stat-widget {
|
||||||
.stat-bars {
|
.stat-bars {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Stats::TicketChannelDistribution
|
||||||
# get users groups
|
# get users groups
|
||||||
group_ids = user.group_ids_access('full')
|
group_ids = user.group_ids_access('full')
|
||||||
|
|
||||||
# get channels
|
# set default channels
|
||||||
channels = [
|
channels = [
|
||||||
{
|
{
|
||||||
sender: 'email',
|
sender: 'email',
|
||||||
|
@ -20,19 +20,65 @@ class Stats::TicketChannelDistribution
|
||||||
sender: 'phone',
|
sender: 'phone',
|
||||||
icon: 'phone',
|
icon: 'phone',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
sender: 'twitter',
|
|
||||||
icon: 'twitter',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sender: 'facebook',
|
|
||||||
icon: 'facebook',
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if Setting.get('customer_ticket_create')
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'web',
|
||||||
|
icon: 'web',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Setting.get('chat')
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'chat',
|
||||||
|
icon: 'chat',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Channel.where(area: 'Sms::Account').exists?
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'sms',
|
||||||
|
icon: 'sms',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Channel.where(area: 'Twitter::Account').exists?
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'twitter',
|
||||||
|
icon: 'twitter',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Channel.where(area: 'Facebook::Account').exists?
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'facebook',
|
||||||
|
icon: 'facebook',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Channel.where(area: 'Telegram::Account').exists?
|
||||||
|
channels.push(
|
||||||
|
{
|
||||||
|
sender: 'telegram',
|
||||||
|
icon: 'telegram',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
# calculate
|
# calculate
|
||||||
result = {}
|
result = {}
|
||||||
total_in = 0
|
total_in = 0
|
||||||
total_out = 0
|
total_out = 0
|
||||||
channels.each do |channel|
|
channels.each do |channel|
|
||||||
result[channel[:sender].to_sym] = {
|
result[channel[:sender].to_sym] = {
|
||||||
|
|
Loading…
Reference in a new issue