mirror of
https://github.com/directus/directus.git
synced 2026-01-29 14:48:02 -05:00
Fix v-select search & selection of groups (#14154)
* fix search not matching parent items * make group selectable in v-select * fix wrong prop name * set selected group to active for highlighted style * Fix typings Co-authored-by: ian <licitdev@gmail.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
<template>
|
||||
<v-list-group :clickable="item.selectable" :open="item.children?.length === 1" :value="item.value">
|
||||
<v-list-group
|
||||
:active="isActive"
|
||||
:clickable="groupSelectable || item.selectable"
|
||||
:open="item.children?.length === 1"
|
||||
:value="item.value"
|
||||
@click="onGroupClick(item)"
|
||||
>
|
||||
<template #activator>
|
||||
<v-list-item-icon v-if="multiple === false && allowOther === false && item.icon">
|
||||
<v-icon :name="item.icon" />
|
||||
@@ -24,6 +30,7 @@
|
||||
:model-value="modelValue"
|
||||
:multiple="multiple"
|
||||
:allow-other="allowOther"
|
||||
:group-selectable="groupSelectable"
|
||||
@update:model-value="$emit('update:modelValue', $event)"
|
||||
/>
|
||||
<select-list-item
|
||||
@@ -39,7 +46,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import { computed, defineComponent, PropType } from 'vue';
|
||||
import { Option } from './types';
|
||||
import SelectListItem from './select-list-item.vue';
|
||||
|
||||
@@ -63,7 +70,31 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
groupSelectable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, { emit }) {
|
||||
const isActive = computed(() => {
|
||||
if (props.multiple) {
|
||||
if (!Array.isArray(props.modelValue) || !props.item.value) {
|
||||
return false;
|
||||
}
|
||||
return props.modelValue.includes(props.item.value);
|
||||
} else {
|
||||
return props.modelValue === props.item.value;
|
||||
}
|
||||
});
|
||||
|
||||
return { isActive, onGroupClick };
|
||||
|
||||
function onGroupClick(item: Option) {
|
||||
if (!props.groupSelectable) return;
|
||||
|
||||
emit('update:modelValue', item.value);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<v-list-item
|
||||
v-else
|
||||
:active="multiple ? (modelValue || []).includes(item.value) : modelValue === item.value"
|
||||
:active="isActive"
|
||||
:disabled="item.disabled"
|
||||
clickable
|
||||
:value="item.value"
|
||||
@@ -27,7 +27,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import { computed, defineComponent, PropType } from 'vue';
|
||||
import { Option } from './types';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -51,5 +51,20 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup(props) {
|
||||
const isActive = computed(() => {
|
||||
if (props.multiple) {
|
||||
if (!Array.isArray(props.modelValue) || !props.item.value) {
|
||||
return false;
|
||||
}
|
||||
return props.modelValue.includes(props.item.value);
|
||||
} else {
|
||||
return props.modelValue === props.item.value;
|
||||
}
|
||||
});
|
||||
return {
|
||||
isActive,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
:model-value="modelValue"
|
||||
:multiple="multiple"
|
||||
:allow-other="allowOther"
|
||||
:group-selectable="groupSelectable"
|
||||
@update:model-value="$emit('update:modelValue', $event)"
|
||||
/>
|
||||
<select-list-item
|
||||
@@ -178,6 +179,10 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
groupSelectable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
mandatory: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
@@ -292,8 +297,13 @@ export default defineComponent({
|
||||
const searchValue = internalSearch.value.toLowerCase();
|
||||
|
||||
return item?.children
|
||||
? item.children.some((item: Record<string, any>) => filterItem(item))
|
||||
: item.text?.toLowerCase().includes(searchValue) || item.value?.toLowerCase().includes(searchValue);
|
||||
? isMatchingCurrentItem(item, searchValue) ||
|
||||
item.children.some((item: Record<string, any>) => filterItem(item))
|
||||
: isMatchingCurrentItem(item, searchValue);
|
||||
|
||||
function isMatchingCurrentItem(item: Record<string, any>, searchValue: string): boolean {
|
||||
return item.text?.toLowerCase().includes(searchValue) || item.value?.toLowerCase().includes(searchValue);
|
||||
}
|
||||
};
|
||||
|
||||
const items = internalSearch.value ? props.items.filter(filterItem).map(parseItem) : props.items.map(parseItem);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
:model-value="value"
|
||||
:placeholder="t('select')"
|
||||
allow-other
|
||||
group-selectable
|
||||
@update:model-value="emitValue($event)"
|
||||
/>
|
||||
<template v-else-if="is === 'interface-datetime'">
|
||||
|
||||
Reference in New Issue
Block a user