feat: Add SLA selector

This commit is contained in:
Muhsin Keloth
2024-03-31 10:45:36 +05:30
parent 31e2356b29
commit 1935d45a42
5 changed files with 284 additions and 0 deletions
@@ -1,5 +1,6 @@
<template>
<div class="flex flex-col flex-1 gap-6 p-4 overflow-auto font-inter">
<SLA-filters />
<SLAMetrics
:hit-rate="slaMetrics.hitRate"
:no-of-breaches="slaMetrics.numberOfSLABreaches"
@@ -16,11 +17,13 @@
import { mapGetters } from 'vuex';
import SLAMetrics from './components/SLA/SLAMetrics.vue';
import SLATable from './components/SLA/SLATable.vue';
import SLAFilters from './components/SLA/SLAFilters.vue';
export default {
name: 'SLAReports',
components: {
SLAMetrics,
SLATable,
SLAFilters,
},
data() {
return {
@@ -0,0 +1,66 @@
<template>
<div
class="menu text-slate-700 dark:text-slate-200 font-medium text-sm h-11 flex items-center hover:bg-slate-50 dark:hover:bg-slate-100"
role="button"
@click.stop="$emit('click')"
>
<span
v-if="variant === 'label' && option.color"
class="label-pill"
:style="{ backgroundColor: option.color }"
/>
<thumbnail
v-if="variant === 'agent'"
:username="option.label"
:src="option.thumbnail"
:status="option.status"
size="20px"
class="agent-thumbnail"
/>
<p class="menu-label overflow-hidden whitespace-nowrap text-ellipsis">
{{ option.label }}
</p>
</div>
</template>
<script>
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
export default {
components: {
Thumbnail,
},
props: {
option: {
type: Object,
default: () => {},
},
variant: {
type: String,
default: 'default',
},
},
};
</script>
<style scoped lang="scss">
.menu {
width: calc(var(--space-mega) * 2);
@apply flex items-center flex-nowrap p-1 rounded-sm overflow-hidden cursor-pointer;
.menu-label {
@apply my-0 mx-2 text-xs flex-shrink-0;
}
// &:hover {
// @apply bg-woot-500 dark:bg-woot-500 text-white dark:text-slate-50;
// }
}
.agent-thumbnail {
margin-top: 0 !important;
}
.label-pill {
@apply w-4 h-4 rounded-full border border-slate-50 border-solid dark:border-slate-900 flex-shrink-0;
}
</style>
@@ -0,0 +1,122 @@
<template>
<div
class="bg-white dark:bg-slate- rounded-xl border-slate-100 dark:border-slate-900 border-solid border"
>
<menu-item
:option="unreadOption"
variant="icon"
@click="$emit('mark-as-unread')"
/>
<menu-item-with-submenu :option="priorityConfig">
<menu-item
v-for="(option, i) in priorityConfig.options"
:key="i"
:option="option"
/>
</menu-item-with-submenu>
<template v-for="option in statusMenuConfig">
<menu-item
v-if="show(option.key)"
:key="option.key"
:option="option"
variant="icon"
/>
</template>
<menu-item
v-if="show(snoozeOption.key)"
:option="snoozeOption"
variant="icon"
/>
<menu-item-with-submenu :option="priorityConfig">
<menu-item
v-for="(option, i) in priorityConfig.options"
:key="i"
:option="option"
/>
</menu-item-with-submenu>
</div>
</template>
<script>
import MenuItem from './MenuItem.vue';
import MenuItemWithSubmenu from './menuItemWithSubmenu.vue';
import wootConstants from 'dashboard/constants/globals';
import agentMixin from 'dashboard/mixins/agentMixin';
import { mapGetters } from 'vuex';
export default {
components: {
MenuItem,
MenuItemWithSubmenu,
},
mixins: [agentMixin],
data() {
return {
STATUS_TYPE: wootConstants.STATUS_TYPE,
unreadOption: {
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.MARK_AS_UNREAD'),
icon: 'mail',
},
statusMenuConfig: [
{
key: wootConstants.STATUS_TYPE.RESOLVED,
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.RESOLVED'),
icon: 'checkmark',
},
{
key: wootConstants.STATUS_TYPE.PENDING,
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.PENDING'),
icon: 'book-clock',
},
{
key: wootConstants.STATUS_TYPE.OPEN,
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.REOPEN'),
icon: 'arrow-redo',
},
],
snoozeOption: {
key: wootConstants.STATUS_TYPE.SNOOZED,
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.SNOOZE.TITLE'),
icon: 'snooze',
},
priorityConfig: {
key: 'priority',
label: this.$t('CONVERSATION.PRIORITY.TITLE'),
icon: 'warning',
options: [
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.NONE'),
key: null,
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.URGENT'),
key: 'urgent',
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.HIGH'),
key: 'high',
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.MEDIUM'),
key: 'medium',
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.LOW'),
key: 'low',
},
].filter(item => item.key !== this.priority),
},
};
},
computed: {
...mapGetters({}),
},
methods: {
show(key) {
// If the conversation status is same as the action, then don't display the option
// i.e.: Don't show an option to resolve if the conversation is already resolved.
return this.status !== key;
},
},
};
</script>
@@ -0,0 +1,50 @@
<template>
<div>
<woot-button
color-scheme="secondary"
icon="plus-sign"
class="rounded-xl"
@click="openContextMenu"
>
Add filter
</woot-button>
<woot-context-menu
v-if="showContextMenu"
ref="menu"
:x="contextMenu.x"
:y="contextMenu.y"
@close="closeContextMenu"
>
<SLA-context-menu />
</woot-context-menu>
</div>
</template>
<script>
import SLAContextMenu from './SLAContextMenu.vue';
export default {
name: 'SLAFilters',
components: {
SLAContextMenu,
},
props: {},
data() {
return {
showContextMenu: false,
};
},
computed: {},
methods: {
openContextMenu() {
this.showContextMenu = true;
this.contextMenu = {
x: null,
y: null,
};
},
closeContextMenu() {
this.showContextMenu = false;
},
},
};
</script>
@@ -0,0 +1,43 @@
<template>
<div
class="text-slate-800 dark:text-slate-100 menu-with-submenu min-width-calc w-full p-1 flex items-center h-7 rounded-md relative bg-white dark:bg-slate-700 justify-between hover:bg-woot-75 cursor-pointer dark:hover:bg-slate-800"
:class="!subMenuAvailable ? 'opacity-50 cursor-not-allowed' : ''"
>
<div class="flex items-center">
<p class="my-0 mx-2 text-xs">{{ option.label }}</p>
</div>
<div
v-if="subMenuAvailable"
class="submenu bg-white dark:bg-slate-700 p-1 shadow-lg rounded-md absolute left-full top-0 hidden min-h-min max-h-[15rem] overflow-y-auto overflow-x-hidden cursor-pointer"
>
<slot />
</div>
</div>
</template>
<script>
export default {
props: {
option: {
type: Object,
default: () => {},
},
subMenuAvailable: {
type: Boolean,
default: true,
},
},
};
</script>
<style scoped lang="scss">
.menu-with-submenu {
min-width: calc(6.25rem * 2);
&:hover {
.submenu {
@apply block;
}
}
}
</style>