feat: Add SLA selector
This commit is contained in:
@@ -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 {
|
||||
|
||||
+66
@@ -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>
|
||||
+122
@@ -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>
|
||||
+50
@@ -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>
|
||||
+43
@@ -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>
|
||||
Reference in New Issue
Block a user