feat: Update agent and team multi-select with new multi-select dropdown (#2516)
* feat: Update agent/team multiselect styles * Component name fixes * Adds key control for our multiselect dropdown and component name spell fix * Minor fixes * Review fixes * Minor fixes * Minor fixes * Review fixes Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
This commit is contained in:
parent
672e5874fb
commit
f2b5e328bb
5 changed files with 117 additions and 41 deletions
169
app/javascript/shared/components/ui/MultiselectDropdown.vue
Normal file
169
app/javascript/shared/components/ui/MultiselectDropdown.vue
Normal file
|
@ -0,0 +1,169 @@
|
|||
<template>
|
||||
<div
|
||||
v-on-clickaway="onCloseDropdown"
|
||||
class="selector-wrap"
|
||||
@keyup.esc="onCloseDropdown"
|
||||
>
|
||||
<woot-button
|
||||
variant="hollow"
|
||||
color-scheme="secondary"
|
||||
:v-model="selectedItem"
|
||||
class="selector-button"
|
||||
@click="toggleDropdown"
|
||||
>
|
||||
<div class="selector-user-wrap">
|
||||
<Thumbnail
|
||||
v-if="hasValue"
|
||||
:src="selectedItem.thumbnail"
|
||||
size="24px"
|
||||
:status="selectedItem.availability_status"
|
||||
:badge="selectedItem.channel"
|
||||
:username="selectedItem.name"
|
||||
/>
|
||||
<div class="selector-name-wrap">
|
||||
<h4
|
||||
v-if="!hasValue"
|
||||
class="not-selected text-ellipsis text-block-title"
|
||||
>
|
||||
{{ multiselectorPlaceholder }}
|
||||
</h4>
|
||||
<h4
|
||||
v-else
|
||||
class="selector-name text-truncate text-block-title"
|
||||
:title="selectedItem.name"
|
||||
>
|
||||
{{ selectedItem.name }}
|
||||
</h4>
|
||||
<i v-if="showSearchDropdown" class="icon ion-chevron-up" />
|
||||
<i v-else class="icon ion-chevron-down" />
|
||||
</div>
|
||||
</div>
|
||||
</woot-button>
|
||||
<div
|
||||
:class="{ 'dropdown-pane--open': showSearchDropdown }"
|
||||
class="dropdown-pane"
|
||||
>
|
||||
<h4 class="text-block-title text-truncate">
|
||||
{{ multiselectorTitle }}
|
||||
</h4>
|
||||
<multiselect-dropdown-items
|
||||
v-if="showSearchDropdown"
|
||||
:options="options"
|
||||
:selected-item="selectedItem"
|
||||
:input-placeholder="inputPlaceholder"
|
||||
:no-search-result="noSearchResult"
|
||||
@click="onClickSelectItem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
|
||||
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems';
|
||||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
export default {
|
||||
components: {
|
||||
Thumbnail,
|
||||
MultiselectDropdownItems,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
selectedItem: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
multiselectorTitle: {
|
||||
type: String,
|
||||
default: 'Select',
|
||||
},
|
||||
multiselectorPlaceholder: {
|
||||
type: String,
|
||||
default: 'None',
|
||||
},
|
||||
noSearchResult: {
|
||||
type: String,
|
||||
default: 'No results found',
|
||||
},
|
||||
inputPlaceholder: {
|
||||
type: String,
|
||||
default: 'Search',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showSearchDropdown: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasValue() {
|
||||
if (this.selectedItem && this.selectedItem.id) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleDropdown() {
|
||||
this.showSearchDropdown = !this.showSearchDropdown;
|
||||
},
|
||||
|
||||
onCloseDropdown() {
|
||||
this.showSearchDropdown = false;
|
||||
},
|
||||
|
||||
onClickSelectItem(value) {
|
||||
this.$emit('click', value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.selector-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-right: var(--space-one);
|
||||
margin-bottom: var(--space-small);
|
||||
|
||||
.selector-button {
|
||||
width: 100%;
|
||||
border: 1px solid var(--color-border);
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
}
|
||||
|
||||
.selector-user-wrap {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.selector-name-wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.not-selected {
|
||||
margin: 0 var(--space-small) 0 0;
|
||||
}
|
||||
|
||||
.selector-name {
|
||||
align-items: center;
|
||||
margin: 0 var(--space-small);
|
||||
}
|
||||
|
||||
.dropdown-pane {
|
||||
box-sizing: border-box;
|
||||
top: 4.2rem;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue