feat: UI to show the SLA threshold in chat screen (#9146)

- UI will show the breach in the conversation list.
- UI will show the breach in the conversation header.

Fixes: https://linear.app/chatwoot/issue/CW-3146/update-the-ui-to-show-the-breach-in-the-conversation-list
Fixes: https://linear.app/chatwoot/issue/CW-3144/ui-update-to-show-the-breachgoing-to-breach
This commit is contained in:
Sivin Varghese
2024-04-04 15:46:46 +05:30
committed by GitHub
parent e21d7552d3
commit e49ef773d8
21 changed files with 745 additions and 106 deletions

View File

@@ -0,0 +1,78 @@
import axios from 'axios';
import { actions } from '../../sla';
import * as types from '../../../mutation-types';
import SLAList from './fixtures';
const commit = jest.fn();
global.axios = axios;
jest.mock('axios');
describe('#actions', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('#get', () => {
it('sends correct actions if API is success', async () => {
axios.get.mockResolvedValue({
data: { payload: SLAList },
});
await actions.get({ commit });
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isFetching: true }],
[types.default.SET_SLA, SLAList],
[types.default.SET_SLA_UI_FLAG, { isFetching: false }],
]);
});
it('sends correct actions if API is error', async () => {
axios.get.mockRejectedValue({ message: 'Incorrect header' });
await actions.get({ commit });
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isFetching: true }],
[types.default.SET_SLA_UI_FLAG, { isFetching: false }],
]);
});
});
describe('#create', () => {
it('sends correct actions if API is success', async () => {
axios.post.mockResolvedValue({
data: { payload: SLAList[0] },
});
await actions.create({ commit }, SLAList[0]);
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isCreating: true }],
[types.default.ADD_SLA, SLAList[0]],
[types.default.SET_SLA_UI_FLAG, { isCreating: false }],
]);
});
it('sends correct actions if API is error', async () => {
axios.post.mockRejectedValue({ message: 'Incorrect header' });
await expect(actions.create({ commit })).rejects.toThrow(Error);
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isCreating: true }],
[types.default.SET_SLA_UI_FLAG, { isCreating: false }],
]);
});
});
describe('#delete', () => {
it('sends correct actions if API is success', async () => {
axios.delete.mockResolvedValue({});
await actions.delete({ commit }, 1);
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isDeleting: true }],
[types.default.DELETE_SLA, 1],
[types.default.SET_SLA_UI_FLAG, { isDeleting: false }],
]);
});
it('sends correct actions if API is error', async () => {
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
await expect(actions.delete({ commit })).rejects.toThrow(Error);
expect(commit.mock.calls).toEqual([
[types.default.SET_SLA_UI_FLAG, { isDeleting: true }],
[types.default.SET_SLA_UI_FLAG, { isDeleting: false }],
]);
});
});
});

View File

@@ -0,0 +1,95 @@
export default [
{
id: 1,
name: 'Premium SLA',
description:
'SLA for chatwoot cloud premium and self-hosted premium customers. SLA for chatwoot cloud premium and self-hosted premium customers',
first_response_time_threshold: 14400,
next_response_time_threshold: 18000,
resolution_time_threshold: 86400,
only_during_business_hours: true,
},
{
id: 2,
name: 'Enterprise SLA',
description:
'SLA for chatwoot enterprise and self-hosted enterprise customers.',
first_response_time_threshold: 600,
next_response_time_threshold: 2400,
resolution_time_threshold: 3600,
only_during_business_hours: false,
},
{
id: 3,
name: 'Business SLA',
description:
'Chatwoot cloud Business and self-hosted Business customers SLA',
first_response_time_threshold: null,
next_response_time_threshold: null,
resolution_time_threshold: null,
only_during_business_hours: false,
},
{
id: 4,
name: 'Hacker SLA',
description: '',
first_response_time_threshold: 60,
next_response_time_threshold: 120,
resolution_time_threshold: 180,
only_during_business_hours: false,
},
{
id: 5,
name: 'SLA',
description: '',
first_response_time_threshold: 120,
next_response_time_threshold: 300,
resolution_time_threshold: 21600,
only_during_business_hours: false,
},
{
id: 6,
name: 'ALla',
description: '',
first_response_time_threshold: 5400,
next_response_time_threshold: 9000,
resolution_time_threshold: 23040,
only_during_business_hours: false,
},
{
id: 7,
name: '10',
description: '',
first_response_time_threshold: 120,
next_response_time_threshold: null,
resolution_time_threshold: null,
only_during_business_hours: false,
},
{
id: 8,
name: '11',
description: '',
first_response_time_threshold: null,
next_response_time_threshold: 240,
resolution_time_threshold: null,
only_during_business_hours: false,
},
{
id: 9,
name: '12',
description: '',
first_response_time_threshold: null,
next_response_time_threshold: null,
resolution_time_threshold: 300,
only_during_business_hours: false,
},
{
id: 10,
name: '14',
description: '',
first_response_time_threshold: null,
next_response_time_threshold: null,
resolution_time_threshold: null,
only_during_business_hours: false,
},
];

View File

@@ -0,0 +1,26 @@
import { getters } from '../../sla';
import SLAs from './fixtures';
describe('#getters', () => {
it('getSLA', () => {
const state = { records: SLAs };
expect(getters.getSLA(state)).toEqual(SLAs);
});
it('getUIFlags', () => {
const state = {
uiFlags: {
isFetching: true,
isCreating: false,
isUpdating: false,
isDeleting: false,
},
};
expect(getters.getUIFlags(state)).toEqual({
isFetching: true,
isCreating: false,
isUpdating: false,
isDeleting: false,
});
});
});

View File

@@ -0,0 +1,34 @@
import types from '../../../mutation-types';
import { mutations } from '../../sla';
import SLAs from './fixtures';
describe('#mutations', () => {
describe('#SET_SLA_UI_FLAG', () => {
it('set sla ui flags', () => {
const state = { uiFlags: {} };
mutations[types.SET_SLA_UI_FLAG](state, { isFetching: true });
expect(state.uiFlags).toEqual({ isFetching: true });
});
});
describe('#SET_SLA', () => {
it('set sla records', () => {
const state = { records: [] };
mutations[types.SET_SLA](state, SLAs);
expect(state.records).toEqual(SLAs);
});
});
describe('#ADD_SLA', () => {
it('push newly created sla to the store', () => {
const state = { records: [SLAs[0]] };
mutations[types.ADD_SLA](state, SLAs[1]);
expect(state.records).toEqual([SLAs[0], SLAs[1]]);
});
});
describe('#DELETE_SLA', () => {
it('delete sla record', () => {
const state = { records: [SLAs[0]] };
mutations[types.DELETE_SLA](state, 1);
expect(state.records).toEqual([]);
});
});
});