feat: Migrate availability mixins to composable and helper (#11596)
# Pull Request Template ## Description **This PR includes:** * Refactored two legacy mixins (`availability.js`, `nextAvailability.js`) into a Vue 3 composable (`useAvailability`), helper module and component based rendering logic. * Fixed an issue where the widget wouldn't load if business hours were enabled but all days were unchecked. * Fixed translation issue [[#11280](https://github.com/chatwoot/chatwoot/issues/11280)](https://github.com/chatwoot/chatwoot/issues/11280). * Reduced code complexity and size. * Added test coverage for both the composable and helper functions. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ### Loom video https://www.loom.com/share/2bc3ed694b4349419505e275d14d0b98?sid=22d585e4-0dc7-4242-bcb6-e3edc16e3aee ### Story <img width="995" height="442" alt="image" src="https://github.com/user-attachments/assets/d6340738-07db-41d5-86fa-a8ecf734cc70" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Fixes https://github.com/chatwoot/chatwoot/issues/12012 --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useMapGetter } from 'dashboard/composables/store.js';
|
||||
import GroupedAvatars from 'widget/components/GroupedAvatars.vue';
|
||||
import AvailabilityText from './AvailabilityText.vue';
|
||||
import { useAvailability } from 'widget/composables/useAvailability';
|
||||
|
||||
const props = defineProps({
|
||||
agents: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showAvatars: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
textClasses: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const availableMessage = useMapGetter('appConfig/getAvailableMessage');
|
||||
const unavailableMessage = useMapGetter('appConfig/getUnavailableMessage');
|
||||
|
||||
const {
|
||||
currentTime,
|
||||
hasOnlineAgents,
|
||||
isOnline,
|
||||
inboxConfig,
|
||||
isInWorkingHours,
|
||||
} = useAvailability(props.agents);
|
||||
|
||||
const workingHours = computed(() => inboxConfig.value.workingHours || []);
|
||||
const workingHoursEnabled = computed(
|
||||
() => inboxConfig.value.workingHoursEnabled || false
|
||||
);
|
||||
const utcOffset = computed(
|
||||
() => inboxConfig.value.utcOffset || inboxConfig.value.timezone || 'UTC'
|
||||
);
|
||||
const replyTime = computed(
|
||||
() => inboxConfig.value.replyTime || 'in_a_few_minutes'
|
||||
);
|
||||
|
||||
// If online or in working hours
|
||||
const isAvailable = computed(
|
||||
() => isOnline.value || (workingHoursEnabled.value && isInWorkingHours.value)
|
||||
);
|
||||
|
||||
const headerText = computed(() =>
|
||||
isAvailable.value
|
||||
? availableMessage.value || t('TEAM_AVAILABILITY.ONLINE')
|
||||
: unavailableMessage.value || t('TEAM_AVAILABILITY.OFFLINE')
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div v-if="showHeader" class="font-medium text-n-slate-12">
|
||||
{{ headerText }}
|
||||
</div>
|
||||
|
||||
<AvailabilityText
|
||||
:time="currentTime"
|
||||
:utc-offset="utcOffset"
|
||||
:working-hours="workingHours"
|
||||
:working-hours-enabled="workingHoursEnabled"
|
||||
:has-online-agents="hasOnlineAgents"
|
||||
:reply-time="replyTime"
|
||||
:is-online="isOnline"
|
||||
:is-in-working-hours="isInWorkingHours"
|
||||
:class="textClasses"
|
||||
class="text-n-slate-11"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<GroupedAvatars v-if="showAvatars && isOnline" :users="agents" />
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user