Skip to content

Commit

Permalink
feat: Update the design for SLA policy management pages (#9136)
Browse files Browse the repository at this point in the history
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
  • Loading branch information
3 people committed Mar 22, 2024
1 parent e94b276 commit 6d4551b
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 112 deletions.
13 changes: 0 additions & 13 deletions app/javascript/dashboard/i18n/locale/en/sla.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,9 @@
"ADD_ACTION": "Add SLA",
"DESCRIPTION": "Service Level Agreements (SLAs) are contracts that define clear expectations between your team and customers. They establish standards for response and resolution times, creating a framework for accountability and ensures a consistent, high-quality experience.",
"LEARN_MORE": "Learn more about SLA",
"HEADER_BTN_TXT": "Add SLA",
"LOADING": "Fetching SLAs",
"SEARCH_404": "There are no items matching this query",
"SIDEBAR_TXT": "<p><b>SLA</b> <p>Think of Service Level Agreements (SLAs) like friendly promises between a service provider and a customer.</p> <p> These promises set clear expectations for things like how quickly the team will respond to issues, making sure you always get a reliable and top-notch experience!</p>",
"LIST": {
"404": "There are no SLAs available in this account.",
"TITLE": "Manage SLA",
"DESC": "SLAs: Friendly promises for great service!",
"TABLE_HEADER": [
"Name",
"Description",
"FRT",
"NRT",
"RT",
"Business Hours"
],
"BUSINESS_HOURS_ON": "Business hours on",
"BUSINESS_HOURS_OFF": "Business hours off",
"RESPONSE_TYPES": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
<script setup>
defineProps({
isLoading: {
type: Boolean,
default: false,
},
loadingMessage: {
type: String,
default: '',
},
});
</script>
<template>
<div class="flex flex-col w-full h-full gap-10 font-inter">
<slot name="header" />
<slot name="body" />
<div>
<slot v-if="isLoading" name="loading">
<woot-loading-state :message="loadingMessage" />
</slot>
<slot v-else name="body" />
</div>
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defineProps({
</script>
<template>
<div
class="flex relative flex-col sm:flex-row p-4 gap-4 sm:p-6 justify-between shadow-sm sm:divide-x sm:divide-slate-75 sm:dark:divide-slate-700/50 group bg-white border border-solid rounded-xl dark:bg-slate-800 border-slate-75 dark:border-slate-700/50 max-w-[900px] w-full"
class="flex relative flex-col sm:flex-row p-4 gap-4 sm:p-6 justify-between shadow-sm group bg-white border border-solid rounded-xl dark:bg-slate-800 border-slate-75 dark:border-slate-700/50 max-w-[900px] w-full"
>
<!-- left side section -->
<slot name="leftSection">
Expand Down
141 changes: 52 additions & 89 deletions app/javascript/dashboard/routes/dashboard/settings/sla/Index.vue
Original file line number Diff line number Diff line change
@@ -1,99 +1,58 @@
<template>
<div class="flex-1 overflow-auto p-4">
<woot-button
color-scheme="success"
class-names="button--fixed-top"
icon="add-circle"
@click="openAddPopup"
>
{{ $t('SLA.HEADER_BTN_TXT') }}
</woot-button>
<div class="flex flex-row gap-4">
<div class="w-full xl:w-3/5">
<p
v-if="!uiFlags.isFetching && !records.length"
class="flex h-full items-center flex-col justify-center"
>
{{ $t('SLA.LIST.404') }}
</p>
<woot-loading-state
v-if="uiFlags.isFetching"
:message="$t('SLA.LOADING')"
<settings-layout
:is-loading="uiFlags.isFetching"
:loading-message="$t('SLA.LOADING')"
>
<template #header>
<SLA-header @click="openAddPopup" />
</template>
<template #loading>
<SLAListItemLoading v-for="ii in 2" :key="ii" class="mb-3" />
</template>
<template #body>
<p
v-if="!records.length"
class="flex flex-col items-center justify-center h-full"
>
{{ $t('SLA.LIST.404') }}
</p>
<div v-if="records.length" class="flex flex-col w-full h-full gap-3">
<SLA-list-item
v-for="sla in records"
:key="sla.title"
:sla-name="sla.name"
:description="sla.description"
:first-response="displayTime(sla.first_response_time_threshold)"
:next-response="displayTime(sla.next_response_time_threshold)"
:resolution-time="displayTime(sla.resolution_time_threshold)"
:has-business-hours="sla.only_during_business_hours"
:is-loading="loading[sla.id]"
@click="openDeletePopup(sla)"
/>
<table v-if="!uiFlags.isFetching && records.length" class="woot-table">
<thead>
<th v-for="thHeader in $t('SLA.LIST.TABLE_HEADER')" :key="thHeader">
{{ thHeader }}
</th>
</thead>
<tbody>
<tr v-for="sla in records" :key="sla.title">
<td>
<span
class="inline-block overflow-hidden whitespace-nowrap text-ellipsis"
>
{{ sla.name }}
</span>
</td>
<td>{{ sla.description }}</td>
<td>
<span class="flex items-center">
{{ displayTime(sla.first_response_time_threshold) }}
</span>
</td>
<td>
<span class="flex items-center">
{{ displayTime(sla.next_response_time_threshold) }}
</span>
</td>
<td>
<span class="flex items-center">
{{ displayTime(sla.resolution_time_threshold) }}
</span>
</td>
<td>
<span class="flex items-center">
{{ sla.only_during_business_hours }}
</span>
</td>
<td class="button-wrapper">
<woot-button
v-tooltip.top="$t('SLA.FORM.DELETE')"
variant="smooth"
color-scheme="alert"
size="tiny"
icon="dismiss-circle"
class-names="grey-btn"
:is-loading="loading[sla.id]"
@click="openDeletePopup(sla)"
/>
</td>
</tr>
</tbody>
</table>
</div>

<div class="w-1/3 hidden xl:block">
<span v-dompurify-html="$t('SLA.SIDEBAR_TXT')" />
</div>
</div>
<woot-modal :show.sync="showAddPopup" :on-close="hideAddPopup">
<add-SLA @close="hideAddPopup" />
</woot-modal>
<woot-modal :show.sync="showAddPopup" :on-close="hideAddPopup">
<add-SLA @close="hideAddPopup" />
</woot-modal>

<woot-delete-modal
:show.sync="showDeleteConfirmationPopup"
:on-close="closeDeletePopup"
:on-confirm="confirmDeletion"
:title="$t('SLA.DELETE.CONFIRM.TITLE')"
:message="$t('SLA.DELETE.CONFIRM.MESSAGE')"
:message-value="deleteMessage"
:confirm-text="deleteConfirmText"
:reject-text="deleteRejectText"
/>
</div>
<woot-delete-modal
:show.sync="showDeleteConfirmationPopup"
:on-close="closeDeletePopup"
:on-confirm="confirmDeletion"
:title="$t('SLA.DELETE.CONFIRM.TITLE')"
:message="$t('SLA.DELETE.CONFIRM.MESSAGE')"
:message-value="deleteMessage"
:confirm-text="deleteConfirmText"
:reject-text="deleteRejectText"
/>
</template>
</settings-layout>
</template>
<script>
import SettingsLayout from '../SettingsLayout.vue';
import SLAHeader from './components/SLAHeader.vue';
import SLAListItem from './components/SLAListItem.vue';
import SLAListItemLoading from './components/SLAListItemLoading.vue';
import { mapGetters } from 'vuex';
import { convertSecondsToTimeUnit } from '@chatwoot/utils';
Expand All @@ -103,6 +62,10 @@ import alertMixin from 'shared/mixins/alertMixin';
export default {
components: {
AddSLA,
SLAHeader,
SLAListItem,
SLAListItemLoading,
SettingsLayout,
},
mixins: [alertMixin],
data() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ defineProps({
});
</script>
<template>
<base-settings-list-item :title="slaName" :description="description">
<base-settings-list-item
class="sm:divide-x sm:divide-slate-75 sm:dark:divide-slate-700/50"
:title="slaName"
:description="description"
>
<template #label>
<SLA-business-hours-label :has-business-hours="hasBusinessHours" />
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup>
import BaseSettingsListItem from '../../components/BaseSettingsListItem.vue';
</script>
<template>
<base-settings-list-item class="opacity-50">
<template #title>
<div class="w-24 h-[26px] rounded-md bg-slate-50 animate-pulse" />
</template>
<template #description>
<div class="w-64 h-4 mb-0.5 rounded-md bg-slate-50 animate-pulse" />
<div class="w-48 h-4 rounded-md bg-slate-50 animate-pulse" />
</template>
<template #label>
<div class="w-32 h-[26px] bg-slate-50 animate-pulse rounded-md" />
</template>
<template #rightSection>
<div
class="flex items-center sm:rtl:!border-l-0 sm:rtl:!border-r sm:rtl:border-solid sm:rtl:border-slate-75 sm:rtl:dark:border-slate-700/50 gap-1.5 w-fit sm:w-full sm:gap-0 sm:justify-between"
>
<div
v-for="ii in 3"
:key="ii"
class="flex justify-end w-1/3 h-full px-4"
>
<div class="w-32 h-full rounded-md bg-slate-50 animate-pulse" />
</div>
</div>
</template>
</base-settings-list-item>
</template>
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { frontendURL } from '../../../../helper/URLHelper';

const SettingsContent = () => import('../Wrapper.vue');
const SettingsWrapper = () => import('../SettingsWrapper.vue');
const Index = () => import('./Index.vue');

export default {
routes: [
{
path: frontendURL('accounts/:accountId/settings/sla'),
component: SettingsContent,
props: {
headerTitle: 'SLA.HEADER',
icon: 'document-list-clock',
showNewButton: true,
},
component: SettingsWrapper,
props: {},
children: [
{
path: '',
Expand Down

0 comments on commit 6d4551b

Please sign in to comment.