mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-03 20:48:07 +00:00 
			
		
		
		
	# Pull Request Template ## Description This PR updates the basic filter UI for conversations. ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ### Loom video https://www.loom.com/share/df69a023a39c4dfca2c12b1ee42a0b2e?sid=977e802e-2865-46f1-ae8e-f89ab5eabc2a ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] 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 - [ ] 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 --------- Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
		
			
				
	
	
		
			86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<script setup>
 | 
						|
import { ref, computed } from 'vue';
 | 
						|
import Button from 'dashboard/components-next/button/Button.vue';
 | 
						|
 | 
						|
const props = defineProps({
 | 
						|
  options: {
 | 
						|
    type: Array,
 | 
						|
    required: true,
 | 
						|
  },
 | 
						|
  modelValue: {
 | 
						|
    type: String,
 | 
						|
    required: true,
 | 
						|
  },
 | 
						|
  label: {
 | 
						|
    type: String,
 | 
						|
    required: true,
 | 
						|
  },
 | 
						|
  subMenuPosition: {
 | 
						|
    type: String,
 | 
						|
    default: 'right',
 | 
						|
    validator: value => {
 | 
						|
      return ['right', 'left', 'bottom'].includes(value);
 | 
						|
    },
 | 
						|
  },
 | 
						|
});
 | 
						|
 | 
						|
const emit = defineEmits(['update:modelValue']);
 | 
						|
 | 
						|
const isOpen = ref(false);
 | 
						|
 | 
						|
const labelValue = computed(() => props.label);
 | 
						|
 | 
						|
const toggleMenu = () => {
 | 
						|
  isOpen.value = !isOpen.value;
 | 
						|
};
 | 
						|
 | 
						|
const handleSelect = value => {
 | 
						|
  emit('update:modelValue', value);
 | 
						|
  isOpen.value = false;
 | 
						|
};
 | 
						|
</script>
 | 
						|
 | 
						|
<template>
 | 
						|
  <div
 | 
						|
    v-on-clickaway="() => (isOpen = false)"
 | 
						|
    class="relative flex flex-col gap-1 w-fit"
 | 
						|
  >
 | 
						|
    <Button
 | 
						|
      icon="i-lucide-chevron-down"
 | 
						|
      size="sm"
 | 
						|
      trailing-icon
 | 
						|
      color="slate"
 | 
						|
      variant="faded"
 | 
						|
      class="!w-fit max-w-40"
 | 
						|
      :class="{ 'dark:!bg-n-alpha-2 !bg-n-slate-9/20': isOpen }"
 | 
						|
      :label="labelValue"
 | 
						|
      @click="toggleMenu"
 | 
						|
    />
 | 
						|
    <div
 | 
						|
      v-if="isOpen"
 | 
						|
      class="absolute select-none max-w-64 flex flex-col gap-1 bg-n-alpha-3 backdrop-blur-[100px] p-1 top-0 shadow-lg z-40 rounded-lg border border-n-weak dark:border-n-strong/50"
 | 
						|
      :class="{
 | 
						|
        'ltr:left-full rtl:right-full ltr:ml-1 rtl:mr-1':
 | 
						|
          subMenuPosition === 'right',
 | 
						|
        'ltr:right-full rtl:left-full ltr:mr-1 rtl:ml-1':
 | 
						|
          subMenuPosition === 'left',
 | 
						|
        'top-full mt-1 ltr:right-0 rtl:left-0': subMenuPosition === 'bottom',
 | 
						|
      }"
 | 
						|
    >
 | 
						|
      <Button
 | 
						|
        v-for="option in options"
 | 
						|
        :key="option.value"
 | 
						|
        :label="option.label"
 | 
						|
        :icon="option.value === modelValue ? 'i-lucide-check' : ''"
 | 
						|
        size="sm"
 | 
						|
        variant="ghost"
 | 
						|
        color="slate"
 | 
						|
        trailing-icon
 | 
						|
        class="!justify-end !px-2.5 !h-7"
 | 
						|
        :class="{ '!bg-n-alpha-2': option.value === modelValue }"
 | 
						|
        @click="handleSelect(option.value)"
 | 
						|
      />
 | 
						|
    </div>
 | 
						|
  </div>
 | 
						|
</template>
 |