mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script setup>
 | |
| import { computed } from 'vue';
 | |
| import Auth from 'dashboard/api/auth';
 | |
| import { useMapGetter } from 'dashboard/composables/store';
 | |
| import { useI18n } from 'vue-i18n';
 | |
| import Avatar from 'next/avatar/Avatar.vue';
 | |
| import SidebarProfileMenuStatus from './SidebarProfileMenuStatus.vue';
 | |
| import { FEATURE_FLAGS } from 'dashboard/featureFlags';
 | |
| 
 | |
| import {
 | |
|   DropdownContainer,
 | |
|   DropdownBody,
 | |
|   DropdownSeparator,
 | |
|   DropdownItem,
 | |
| } from 'next/dropdown-menu/base';
 | |
| import CustomBrandPolicyWrapper from '../../components/CustomBrandPolicyWrapper.vue';
 | |
| 
 | |
| const emit = defineEmits(['close', 'openKeyShortcutModal']);
 | |
| 
 | |
| defineOptions({
 | |
|   inheritAttrs: false,
 | |
| });
 | |
| 
 | |
| const { t } = useI18n();
 | |
| 
 | |
| const currentUser = useMapGetter('getCurrentUser');
 | |
| const currentUserAvailability = useMapGetter('getCurrentUserAvailability');
 | |
| const accountId = useMapGetter('getCurrentAccountId');
 | |
| const globalConfig = useMapGetter('globalConfig/get');
 | |
| const isFeatureEnabledonAccount = useMapGetter(
 | |
|   'accounts/isFeatureEnabledonAccount'
 | |
| );
 | |
| 
 | |
| const showChatSupport = computed(() => {
 | |
|   return (
 | |
|     isFeatureEnabledonAccount.value(
 | |
|       accountId.value,
 | |
|       FEATURE_FLAGS.CONTACT_CHATWOOT_SUPPORT_TEAM
 | |
|     ) && globalConfig.value.chatwootInboxToken
 | |
|   );
 | |
| });
 | |
| 
 | |
| const menuItems = computed(() => {
 | |
|   return [
 | |
|     {
 | |
|       show: showChatSupport.value,
 | |
|       showOnCustomBrandedInstance: false,
 | |
|       label: t('SIDEBAR_ITEMS.CONTACT_SUPPORT'),
 | |
|       icon: 'i-lucide-life-buoy',
 | |
|       click: () => {
 | |
|         window.$chatwoot.toggle();
 | |
|       },
 | |
|     },
 | |
|     {
 | |
|       show: true,
 | |
|       showOnCustomBrandedInstance: true,
 | |
|       label: t('SIDEBAR_ITEMS.KEYBOARD_SHORTCUTS'),
 | |
|       icon: 'i-lucide-keyboard',
 | |
|       click: () => {
 | |
|         emit('openKeyShortcutModal');
 | |
|       },
 | |
|     },
 | |
|     {
 | |
|       show: true,
 | |
|       showOnCustomBrandedInstance: true,
 | |
|       label: t('SIDEBAR_ITEMS.PROFILE_SETTINGS'),
 | |
|       icon: 'i-lucide-user-pen',
 | |
|       link: { name: 'profile_settings_index' },
 | |
|     },
 | |
|     {
 | |
|       show: true,
 | |
|       showOnCustomBrandedInstance: true,
 | |
|       label: t('SIDEBAR_ITEMS.APPEARANCE'),
 | |
|       icon: 'i-lucide-palette',
 | |
|       click: () => {
 | |
|         const ninja = document.querySelector('ninja-keys');
 | |
|         ninja.open({ parent: 'appearance_settings' });
 | |
|       },
 | |
|     },
 | |
|     {
 | |
|       show: true,
 | |
|       showOnCustomBrandedInstance: false,
 | |
|       label: t('SIDEBAR_ITEMS.DOCS'),
 | |
|       icon: 'i-lucide-book',
 | |
|       link: 'https://www.chatwoot.com/hc/user-guide/en',
 | |
|       nativeLink: true,
 | |
|       target: '_blank',
 | |
|     },
 | |
|     {
 | |
|       show: currentUser.value.type === 'SuperAdmin',
 | |
|       showOnCustomBrandedInstance: true,
 | |
|       label: t('SIDEBAR_ITEMS.SUPER_ADMIN_CONSOLE'),
 | |
|       icon: 'i-lucide-castle',
 | |
|       link: '/super_admin',
 | |
|       nativeLink: true,
 | |
|       target: '_blank',
 | |
|     },
 | |
|     {
 | |
|       show: true,
 | |
|       showOnCustomBrandedInstance: true,
 | |
|       label: t('SIDEBAR_ITEMS.LOGOUT'),
 | |
|       icon: 'i-lucide-power',
 | |
|       click: Auth.logout,
 | |
|     },
 | |
|   ];
 | |
| });
 | |
| 
 | |
| const allowedMenuItems = computed(() => {
 | |
|   return menuItems.value.filter(item => item.show);
 | |
| });
 | |
| </script>
 | |
| 
 | |
| <template>
 | |
|   <DropdownContainer class="relative w-full min-w-0" @close="emit('close')">
 | |
|     <template #trigger="{ toggle, isOpen }">
 | |
|       <button
 | |
|         class="flex gap-2 items-center rounded-lg cursor-pointer text-left w-full hover:bg-n-alpha-1 p-1"
 | |
|         :class="{ 'bg-n-alpha-1': isOpen }"
 | |
|         @click="toggle"
 | |
|       >
 | |
|         <Avatar
 | |
|           :size="32"
 | |
|           :name="currentUser.available_name"
 | |
|           :src="currentUser.avatar_url"
 | |
|           :status="currentUserAvailability"
 | |
|           class="flex-shrink-0"
 | |
|           rounded-full
 | |
|         />
 | |
|         <div class="min-w-0">
 | |
|           <div class="text-n-slate-12 text-sm leading-4 font-medium truncate">
 | |
|             {{ currentUser.available_name }}
 | |
|           </div>
 | |
|           <div class="text-n-slate-11 text-xs truncate">
 | |
|             {{ currentUser.email }}
 | |
|           </div>
 | |
|         </div>
 | |
|       </button>
 | |
|     </template>
 | |
|     <DropdownBody class="ltr:left-0 rtl:right-0 bottom-12 z-50 w-80 mb-2">
 | |
|       <SidebarProfileMenuStatus />
 | |
|       <DropdownSeparator />
 | |
|       <template v-for="item in allowedMenuItems" :key="item.label">
 | |
|         <CustomBrandPolicyWrapper
 | |
|           :show-on-custom-branded-instance="item.showOnCustomBrandedInstance"
 | |
|         >
 | |
|           <DropdownItem v-if="item.show" v-bind="item" />
 | |
|         </CustomBrandPolicyWrapper>
 | |
|       </template>
 | |
|     </DropdownBody>
 | |
|   </DropdownContainer>
 | |
| </template>
 | 
