mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-01 03:27:52 +00:00
# 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>
88 lines
2.3 KiB
Vue
88 lines
2.3 KiB
Vue
<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>
|