mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-04 04:57:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<script setup>
 | 
						|
import { computed, defineEmits } from 'vue';
 | 
						|
import { OnClickOutside } from '@vueuse/components';
 | 
						|
import { useToggle } from '@vueuse/core';
 | 
						|
 | 
						|
import Button from 'dashboard/components-next/button/Button.vue';
 | 
						|
import Avatar from 'next/avatar/Avatar.vue';
 | 
						|
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems.vue';
 | 
						|
 | 
						|
const props = defineProps({
 | 
						|
  options: {
 | 
						|
    type: Array,
 | 
						|
    default: () => [],
 | 
						|
  },
 | 
						|
  selectedItem: {
 | 
						|
    type: Object,
 | 
						|
    default: () => ({}),
 | 
						|
  },
 | 
						|
  hasThumbnail: {
 | 
						|
    type: Boolean,
 | 
						|
    default: true,
 | 
						|
  },
 | 
						|
  multiselectorTitle: {
 | 
						|
    type: String,
 | 
						|
    default: '',
 | 
						|
  },
 | 
						|
  multiselectorPlaceholder: {
 | 
						|
    type: String,
 | 
						|
    default: 'None',
 | 
						|
  },
 | 
						|
  noSearchResult: {
 | 
						|
    type: String,
 | 
						|
    default: 'No results found',
 | 
						|
  },
 | 
						|
  inputPlaceholder: {
 | 
						|
    type: String,
 | 
						|
    default: 'Search',
 | 
						|
  },
 | 
						|
});
 | 
						|
 | 
						|
const emit = defineEmits(['select']);
 | 
						|
const [showSearchDropdown, toggleDropdown] = useToggle(false);
 | 
						|
 | 
						|
const onCloseDropdown = () => toggleDropdown(false);
 | 
						|
const onClickSelectItem = value => {
 | 
						|
  emit('select', value);
 | 
						|
  onCloseDropdown();
 | 
						|
};
 | 
						|
 | 
						|
const hasValue = computed(() => {
 | 
						|
  if (props.selectedItem && props.selectedItem.id) {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
});
 | 
						|
</script>
 | 
						|
 | 
						|
<template>
 | 
						|
  <OnClickOutside @trigger="onCloseDropdown">
 | 
						|
    <div class="relative w-full mb-2" @keyup.esc="onCloseDropdown">
 | 
						|
      <Button
 | 
						|
        slate
 | 
						|
        outline
 | 
						|
        trailing-icon
 | 
						|
        :icon="
 | 
						|
          showSearchDropdown ? 'i-lucide-chevron-up' : 'i-lucide-chevron-down'
 | 
						|
        "
 | 
						|
        class="w-full !px-2"
 | 
						|
        @click="
 | 
						|
          () => toggleDropdown() // ensure that the event is not passed to the button
 | 
						|
        "
 | 
						|
      >
 | 
						|
        <div class="flex items-center justify-between w-full min-w-0">
 | 
						|
          <h4 v-if="!hasValue" class="text-sm text-ellipsis text-n-slate-12">
 | 
						|
            {{ multiselectorPlaceholder }}
 | 
						|
          </h4>
 | 
						|
          <h4
 | 
						|
            v-else
 | 
						|
            class="items-center overflow-hidden text-sm leading-tight whitespace-nowrap text-ellipsis text-n-slate-12"
 | 
						|
            :title="selectedItem.name"
 | 
						|
          >
 | 
						|
            {{ selectedItem.name }}
 | 
						|
          </h4>
 | 
						|
        </div>
 | 
						|
        <Avatar
 | 
						|
          v-if="hasValue && hasThumbnail"
 | 
						|
          :src="selectedItem.thumbnail"
 | 
						|
          :status="selectedItem.availability_status"
 | 
						|
          :name="selectedItem.name"
 | 
						|
          :size="24"
 | 
						|
          hide-offline-status
 | 
						|
          rounded-full
 | 
						|
        />
 | 
						|
      </Button>
 | 
						|
      <div
 | 
						|
        :class="{
 | 
						|
          'block visible': showSearchDropdown,
 | 
						|
          'hidden invisible': !showSearchDropdown,
 | 
						|
        }"
 | 
						|
        class="box-border top-[2.625rem] w-full border rounded-lg bg-n-alpha-3 backdrop-blur-[100px] absolute shadow-lg border-n-strong dark:border-n-strong p-2 z-[9999]"
 | 
						|
      >
 | 
						|
        <div class="flex items-center justify-between mb-1">
 | 
						|
          <h4
 | 
						|
            class="m-0 overflow-hidden text-sm text-n-slate-11 whitespace-nowrap text-ellipsis"
 | 
						|
          >
 | 
						|
            {{ multiselectorTitle }}
 | 
						|
          </h4>
 | 
						|
          <Button ghost slate xs icon="i-lucide-x" @click="onCloseDropdown" />
 | 
						|
        </div>
 | 
						|
        <MultiselectDropdownItems
 | 
						|
          v-if="showSearchDropdown"
 | 
						|
          :options="options"
 | 
						|
          :selected-items="[selectedItem]"
 | 
						|
          :has-thumbnail="hasThumbnail"
 | 
						|
          :input-placeholder="inputPlaceholder"
 | 
						|
          :no-search-result="noSearchResult"
 | 
						|
          @select="onClickSelectItem"
 | 
						|
        />
 | 
						|
      </div>
 | 
						|
    </div>
 | 
						|
  </OnClickOutside>
 | 
						|
</template>
 |