Files
leadchat/app/javascript/shared/components/ui/MultiselectDropdown.vue
Sivin Varghese d9e732c005 chore(v5): update priority icons (#13905)
# Pull Request Template

## Description

This PR updates the priority icons with a new set and makes them
consistent across the app.


## How Has This Been Tested?

**Screenshots**
<img width="420" height="550" alt="image"
src="https://github.com/user-attachments/assets/cb392934-6c4d-46b4-9fde-244461da62ef"
/>
<img width="358" height="340" alt="image"
src="https://github.com/user-attachments/assets/cb18df47-9a17-42f8-9367-e8b7c4e3958d"
/>
<img width="344" height="468" alt="image"
src="https://github.com/user-attachments/assets/9de92374-e732-48eb-a8a9-85c5b5100931"
/>
<img width="445" height="548" alt="image"
src="https://github.com/user-attachments/assets/ecc4ce51-165c-4593-a9a2-e70b08a29006"
/>


## 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>
2026-03-26 09:20:36 +05:30

133 lines
3.7 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 Icon from 'dashboard/components-next/icon/Icon.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;
});
const hasIcon = computed(() => {
return props.selectedItem?.icon || 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 && !hasIcon"
:src="selectedItem.thumbnail"
:status="selectedItem.availability_status"
:name="selectedItem.name"
:size="24"
hide-offline-status
rounded-full
/>
<Icon
v-if="hasValue && hasIcon"
:icon="selectedItem.icon"
class="size-5 text-n-slate-11"
/>
</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>