Skip to content

Commit

Permalink
feat: Better SLA missed events popover (chatwoot#9215)
Browse files Browse the repository at this point in the history
* feat: SLA events component

* feat: Add SLA event item component

* Update SLAPopoverCard.vue

* Update SLAPopoverCard.vue

* fix: Translation

* Update SLAEventItem.vue

* feat: complete sticky nrt

* chore: code cleanup

* Update SLACardLabel.vue

* chore: code cleanup

* chore: away click fixes

* feat: use tabular nums

---------

Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
  • Loading branch information
muhsin-k and scmmishra authored Apr 10, 2024
1 parent 9013450 commit aed156f
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
:class="showExtendedInfo ? 'h-[26px] rounded-lg' : 'rounded h-5'"
>
<div
v-on-clickaway="closeSlaPopover"
class="flex items-center w-full truncate"
:class="showExtendedInfo ? 'px-1.5' : 'px-2 gap-1'"
@mouseover="openSlaPopover()"
@mouseleave="closeSlaPopover()"
>
<div
class="flex items-center gap-1"
Expand Down Expand Up @@ -42,7 +42,7 @@
</div>
<SLA-popover-card
v-if="showSlaPopoverCard"
:all-missed-slas="slaEvents"
:sla-missed-events="slaEvents"
class="right-0 top-7"
/>
</div>
Expand All @@ -51,13 +51,15 @@
<script>
import { evaluateSLAStatus } from '../helpers/SLAHelper';
import SLAPopoverCard from './SLAPopoverCard.vue';
import { mixin as clickaway } from 'vue-clickaway';
const REFRESH_INTERVAL = 60000;
export default {
components: {
SLAPopoverCard,
},
mixins: [clickaway],
props: {
chat: {
type: Object,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup>
import { format, fromUnixTime } from 'date-fns';
defineProps({
label: {
type: String,
required: true,
},
items: {
type: Array,
required: true,
},
});
const formatDate = timestamp =>
format(fromUnixTime(timestamp), 'MMM dd, yyyy, hh:mm a');
</script>
<template>
<div class="flex justify-between w-full">
<span
class="text-sm sticky top-0 h-fit font-normal tracking-[-0.6%] min-w-[140px] truncate text-slate-600 dark:text-slate-200"
>
{{ label }}
</span>
<div class="flex flex-col w-full gap-2">
<span
v-for="item in items"
:key="item.id"
class="text-sm font-normal text-slate-900 dark:text-slate-25 text-right tabular-nums"
>
{{ formatDate(item.created_at) }}
</span>
<slot name="showMore" />
</div>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -1,45 +1,85 @@
<script setup>
import { format, fromUnixTime } from 'date-fns';
import { ref, computed } from 'vue';
defineProps({
allMissedSlas: {
import wootConstants from 'dashboard/constants/globals';
import SLAEventItem from './SLAEventItem.vue';
const { SLA_MISS_TYPES } = wootConstants;
const props = defineProps({
slaMissedEvents: {
type: Array,
default: () => [],
required: true,
},
});
const formatDate = timestamp => format(fromUnixTime(timestamp), 'PP');
const shouldShowAllNrts = ref(false);
const frtMisses = computed(() =>
props.slaMissedEvents.filter(
slaEvent => slaEvent.event_type === SLA_MISS_TYPES.FRT
)
);
const nrtMisses = computed(() => {
const missedEvents = props.slaMissedEvents.filter(
slaEvent => slaEvent.event_type === SLA_MISS_TYPES.NRT
);
return shouldShowAllNrts.value ? missedEvents : missedEvents.slice(0, 6);
});
const rtMisses = computed(() =>
props.slaMissedEvents.filter(
slaEvent => slaEvent.event_type === SLA_MISS_TYPES.RT
)
);
const upperCase = str => str.toUpperCase();
const shouldShowMoreNRTButton = computed(() => nrtMisses.value.length > 6);
const toggleShowAllNRT = () => {
shouldShowAllNrts.value = !shouldShowAllNrts.value;
};
</script>
<template>
<div
class="absolute flex flex-col items-start bg-[#fdfdfd] dark:bg-slate-800 z-50 p-4 border border-solid border-slate-75 dark:border-slate-700 w-[384px] rounded-xl gap-4"
class="absolute flex flex-col items-start bg-[#fdfdfd] dark:bg-slate-800 z-50 p-4 border border-solid border-slate-75 dark:border-slate-700 w-[384px] rounded-xl gap-4 max-h-96 overflow-auto"
>
<div
v-for="missedSLA in allMissedSlas"
:key="missedSLA.id"
class="flex items-center justify-between w-full"
<span class="text-sm font-medium text-slate-900 dark:text-slate-25">
{{ $t('SLA.EVENTS.TITLE') }}
</span>
<SLA-event-item
v-if="frtMisses.length"
:label="$t('SLA.EVENTS.FRT')"
:items="frtMisses"
/>
<SLA-event-item
v-if="nrtMisses.length"
:label="$t('SLA.EVENTS.NRT')"
:items="nrtMisses"
>
<span
class="text-sm font-normal tracking-[-0.6%] w-[140px] truncate text-slate-900 dark:text-slate-50"
>
{{
$t(
`CONVERSATION.HEADER.SLA_POPOVER.${upperCase(missedSLA.event_type)}`
)
}}
</span>
<span
class="text-sm font-normal tracking-[-0.6%] text-slate-600 dark:text-slate-200"
>
{{ $t('CONVERSATION.HEADER.SLA_POPOVER.MISSED') }}
</span>
<span
class="text-sm font-normal tracking-[-0.6%] text-slate-900 dark:text-slate-50"
>
{{ formatDate(missedSLA.created_at) }}
</span>
</div>
<template #showMore>
<div
v-if="shouldShowMoreNRTButton"
class="flex flex-col items-end w-full"
>
<woot-button
size="small"
:icon="!shouldShowAllNrts ? 'plus-sign' : ''"
variant="link"
color-scheme="secondary"
class="hover:!no-underline !gap-1 hover:!bg-transparent dark:hover:!bg-transparent"
@click="toggleShowAllNRT"
>
{{
shouldShowAllNrts
? $t('SLA.EVENTS.HIDE', { count: nrtMisses.length })
: $t('SLA.EVENTS.SHOW_MORE', { count: nrtMisses.length })
}}
</woot-button>
</div>
</template>
</SLA-event-item>
<SLA-event-item
v-if="rtMisses.length"
:label="$t('SLA.EVENTS.RT')"
:items="rtMisses"
/>
</div>
</template>
5 changes: 5 additions & 0 deletions app/javascript/dashboard/constants/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,10 @@ export default {
TYPE: 'type',
SORT_ORDER: 'sort_order',
},
SLA_MISS_TYPES: {
FRT: 'frt',
NRT: 'nrt',
RT: 'rt',
},
};
export const DEFAULT_REDIRECT_URL = '/app/';
6 changes: 0 additions & 6 deletions app/javascript/dashboard/i18n/locale/en/conversation.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@
"RT": "RT {status}",
"MISSED": "missed",
"DUE": "due"
},
"SLA_POPOVER": {
"FRT": "First Response Time",
"NRT": "Next Response Time",
"RT": "Resolution Time",
"MISSED": "missed on"
}
},
"RESOLVE_DROPDOWN": {
Expand Down
10 changes: 9 additions & 1 deletion app/javascript/dashboard/i18n/locale/en/sla.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@
"YES": "Yes, Delete ",
"NO": "No, Keep "
}
},
"EVENTS": {
"TITLE": "SLA Misses",
"FRT": "First response time",
"NRT": "Next response time",
"RT": "Resolution time",
"SHOW_MORE": "{count} more",
"HIDE": "Hide {count} rows"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</woot-button>
<SLA-popover-card
v-if="showSlaPopoverCard"
:all-missed-slas="slaEvents"
:sla-missed-events="slaEvents"
class="right-0"
/>
</div>
Expand Down

0 comments on commit aed156f

Please sign in to comment.