chore: integrate the composable replacing the mixing in pages and components

This commit is contained in:
Fayaz Ahmed
2024-08-09 13:10:21 +05:30
parent a795028979
commit f29a86d1f5
4 changed files with 127 additions and 24 deletions
@@ -1,6 +1,5 @@
<script>
import { useAvailability } from 'widget/composables/useAvailability';
import availabilityMixin from 'widget/mixins/availability';
import nextAvailabilityTime from 'widget/mixins/nextAvailabilityTime';
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import HeaderActions from './HeaderActions.vue';
@@ -13,7 +12,7 @@ export default {
FluentIcon,
HeaderActions,
},
mixins: [nextAvailabilityTime, availabilityMixin, routerMixin, darkMixin],
mixins: [nextAvailabilityTime, routerMixin, darkMixin],
props: {
avatarUrl: {
type: String,
@@ -37,8 +36,10 @@ export default {
},
},
setup(props) {
const { isOnline } = useAvailability(props.availableAgents);
return { isOnline };
const { isOnline, replyWaitMessage } = useAvailability(
props.availableAgents
);
return { isOnline, replyWaitMessage };
},
methods: {
onBackButtonClick() {
@@ -4,7 +4,7 @@ import { getContrastingTextColor } from '@chatwoot/utils';
import nextAvailabilityTime from 'widget/mixins/nextAvailabilityTime';
import AvailableAgents from 'widget/components/AvailableAgents.vue';
import configMixin from 'widget/mixins/configMixin';
import availabilityMixin from 'widget/mixins/availability';
import { useAvailability } from 'widget/composables/useAvailability';
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import { IFrameHelper } from 'widget/helpers/utils';
import { CHATWOOT_ON_START_CONVERSATION } from '../constants/sdkEvents';
@@ -15,7 +15,7 @@ export default {
AvailableAgents,
FluentIcon,
},
mixins: [configMixin, nextAvailabilityTime, availabilityMixin],
mixins: [configMixin, nextAvailabilityTime],
props: {
availableAgents: {
type: Array,
@@ -26,7 +26,12 @@ export default {
default: false,
},
},
setup(props) {
const { isOnline, replyWaitMessage } = useAvailability(
props.availableAgents
);
return { isOnline, replyWaitMessage };
},
computed: {
...mapGetters({
widgetColor: 'appConfig/getWidgetColor',
@@ -34,15 +39,6 @@ export default {
textColor() {
return getContrastingTextColor(this.widgetColor);
},
isOnline() {
const { workingHoursEnabled } = this.channelConfig;
const anyAgentOnline = this.availableAgents.length > 0;
if (workingHoursEnabled) {
return this.isInBetweenTheWorkingHours;
}
return anyAgentOnline;
},
},
methods: {
startConversation() {
@@ -1,26 +1,28 @@
import { computed } from 'vue';
import { utcToZonedTime } from 'date-fns-tz';
import { isTimeAfter } from 'shared/helpers/DateHelper';
import { useI18n } from 'dashboard/composables/useI18n';
/**
* Composable for handling availability-related computations.
* @param {Object} i18n - Vue i18n instance for translations.
* @param {Object} $t - Vue i18n instance for translations.
* @returns {Object} An object containing computed properties and methods for availability management.
*/
export function useAvailability(availableAgents, i18n) {
export function useAvailability(availableAgents) {
const { t: $t } = useI18n();
const channelConfig = computed(() => window.chatwootWebChannel);
const replyTime = computed(() => window.chatwootWebChannel.replyTime);
const replyTimeStatus = computed(() => {
switch (replyTime.value) {
case 'in_a_few_minutes':
return i18n.t('REPLY_TIME.IN_A_FEW_MINUTES');
return $t('REPLY_TIME.IN_A_FEW_MINUTES');
case 'in_a_few_hours':
return i18n.t('REPLY_TIME.IN_A_FEW_HOURS');
return $t('REPLY_TIME.IN_A_FEW_HOURS');
case 'in_a_day':
return i18n.t('REPLY_TIME.IN_A_DAY');
return $t('REPLY_TIME.IN_A_DAY');
default:
return i18n.t('REPLY_TIME.IN_A_FEW_HOURS');
return $t('REPLY_TIME.IN_A_FEW_HOURS');
}
});
@@ -29,11 +31,11 @@ export function useAvailability(availableAgents, i18n) {
if (workingHoursEnabled) {
return isOnline.value
? replyTimeStatus.value
: `${i18n.t('REPLY_TIME.BACK_IN')} ${timeLeftToBackInOnline.value}`;
: `${$t('REPLY_TIME.BACK_IN')} ${timeLeftToBackInOnline.value}`;
}
return isOnline.value
? replyTimeStatus.value
: i18n.t('TEAM_AVAILABILITY.OFFLINE');
: $t('TEAM_AVAILABILITY.OFFLINE');
});
const outOfOfficeMessage = computed(
@@ -0,0 +1,104 @@
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { ref } from 'vue';
import { useAvailability } from '../../composables/useAvailability';
vi.mock('dashboard/composables/useI18n', () => ({
useI18n: () => ({
t: key => key,
}),
}));
describe('useAvailability', () => {
beforeEach(() => {
vi.useFakeTimers();
global.chatwootWebChannel = {
workingHoursEnabled: true,
workingHours: [
{
day_of_week: 3,
closed_all_day: false,
open_hour: 8,
open_minutes: 30,
close_hour: 17,
close_minutes: 35,
open_all_day: false,
},
{
day_of_week: 4,
closed_all_day: false,
open_hour: 8,
open_minutes: 30,
close_hour: 17,
close_minutes: 30,
open_all_day: false,
},
],
utcOffset: '-07:00',
replyTime: 'in_a_few_minutes',
};
});
it('returns correct replyTimeStatus', () => {
const availableAgents = ref([]);
const { replyTimeStatus } = useAvailability(availableAgents);
expect(replyTimeStatus.value).toBe('REPLY_TIME.IN_A_FEW_MINUTES');
});
it('returns correct isInBetweenTheWorkingHours when in working hours', () => {
vi.setSystemTime(new Date('Wed Apr 13 2022 10:00:00 GMT-0700'));
const availableAgents = ref([]);
const { isInBetweenTheWorkingHours } = useAvailability(availableAgents);
expect(isInBetweenTheWorkingHours.value).toBe(true);
});
it('returns correct isInBetweenTheWorkingHours when outside working hours', () => {
vi.setSystemTime(new Date('Wed Apr 13 2022 18:00:00 GMT-0700'));
const availableAgents = ref([]);
const { isInBetweenTheWorkingHours } = useAvailability(availableAgents);
expect(isInBetweenTheWorkingHours.value).toBe(false);
});
it('returns true for isInBetweenTheWorkingHours when open all day', () => {
global.chatwootWebChannel.workingHours = [
{ day_of_week: 3, open_all_day: true },
];
const availableAgents = ref([]);
const { isInBetweenTheWorkingHours } = useAvailability(availableAgents);
expect(isInBetweenTheWorkingHours.value).toBe(true);
});
it('returns false for isInBetweenTheWorkingHours when closed all day', () => {
global.chatwootWebChannel.workingHours = [
{ day_of_week: 3, closed_all_day: true },
];
const availableAgents = ref([]);
const { isInBetweenTheWorkingHours } = useAvailability(availableAgents);
expect(isInBetweenTheWorkingHours.value).toBe(false);
});
it('returns correct isOnline status when agents are available', () => {
const availableAgents = ref([{ id: 1 }]);
const { isOnline } = useAvailability(availableAgents);
expect(isOnline.value).toBe(true);
});
it('returns correct isOnline status when no agents are available and outside working hours', () => {
vi.setSystemTime(new Date('Wed Apr 13 2022 18:00:00 GMT-0700'));
const availableAgents = ref([]);
const { isOnline } = useAvailability(availableAgents);
expect(isOnline.value).toBe(false);
});
it('returns correct replyWaitMessage when online', () => {
const availableAgents = ref([{ id: 1 }]);
const { replyWaitMessage } = useAvailability(availableAgents);
expect(replyWaitMessage.value).toBe('REPLY_TIME.IN_A_FEW_MINUTES');
});
it('returns correct replyWaitMessage when offline', () => {
vi.setSystemTime(new Date('Wed Apr 13 2022 18:00:00 GMT-0700'));
const availableAgents = ref([]);
const { replyWaitMessage } = useAvailability(availableAgents);
expect(replyWaitMessage.value).toBe('TEAM_AVAILABILITY.OFFLINE');
});
});