Node library search filters (#636)

* Add search filters to node library

* Fix

* Dont close on add

* Fix wildcard

---------

Co-authored-by: Chenlei Hu <chenlei.hu@mail.utoronto.ca>
This commit is contained in:
pythongosssss
2024-08-28 02:17:34 +01:00
committed by GitHub
parent fef9395a2c
commit 968f417061
6 changed files with 233 additions and 96 deletions

View File

@@ -1,20 +1,45 @@
<template>
<IconField :class="props.class">
<InputIcon :class="props.icon" />
<InputText
class="search-box-input"
@input="handleInput"
:modelValue="props.modelValue"
:placeholder="props.placeholder"
/>
</IconField>
<div :class="props.class">
<IconField>
<InputIcon :class="props.icon" />
<InputText
class="search-box-input"
:class="{ ['with-filter']: props.filterIcon }"
@input="handleInput"
:modelValue="props.modelValue"
:placeholder="props.placeholder"
/>
<Button
v-if="props.filterIcon"
class="p-inputicon"
:icon="props.filterIcon"
text
severity="contrast"
@click="$emit('showFilter', $event)"
/>
</IconField>
<div class="search-filters" v-if="filters">
<SearchFilterChip
v-for="filter in filters"
:key="filter.id"
:text="filter.text"
:badge="filter.badge"
:badge-class="filter.badgeClass"
@remove="$emit('removeFilter', filter)"
/>
</div>
</div>
</template>
<script setup lang="ts">
<script setup lang="ts" generic="TFilter extends SearchFilter">
import type { SearchFilter } from './SearchFilterChip.vue'
import { debounce } from 'lodash'
import IconField from 'primevue/iconfield'
import InputIcon from 'primevue/inputicon'
import InputText from 'primevue/inputtext'
import Button from 'primevue/button'
import SearchFilterChip from './SearchFilterChip.vue'
import { toRefs } from 'vue'
interface Props {
class?: string
@@ -22,6 +47,8 @@ interface Props {
placeholder?: string
icon?: string
debounceTime?: number
filterIcon?: string
filters?: TFilter[]
}
const props = withDefaults(defineProps<Props>(), {
@@ -30,10 +57,17 @@ const props = withDefaults(defineProps<Props>(), {
debounceTime: 300
})
const emit = defineEmits(['update:modelValue', 'search'])
const { filters } = toRefs(props)
const emit = defineEmits([
'update:modelValue',
'search',
'showFilter',
'removeFilter'
])
const emitSearch = debounce((value: string) => {
emit('search', value)
emit('search', value, props.filters)
}, props.debounceTime)
const handleInput = (event: Event) => {
@@ -46,5 +80,20 @@ const handleInput = (event: Event) => {
<style scoped>
.search-box-input {
width: 100%;
padding-left: 36px;
}
.search-box-input.with-filter {
padding-right: 36px;
}
.p-button.p-inputicon {
padding: 0;
width: auto;
border: none !important;
}
.search-filters {
@apply pt-2 flex flex-wrap gap-2;
}
</style>

View File

@@ -0,0 +1,41 @@
<template>
<Chip removable @remove="$emit('remove', $event)">
<Badge size="small" :class="badgeClass">
{{ badge }}
</Badge>
{{ text }}
</Chip>
</template>
<script setup lang="ts">
import Chip from 'primevue/chip'
import Badge from 'primevue/badge'
export interface SearchFilter {
text: string
badge: string
badgeClass: string
id: string | number
}
defineProps<Omit<SearchFilter, 'id'>>()
defineEmits(['remove'])
</script>
<style scoped>
:deep(.i-badge) {
@apply bg-green-500 text-white;
}
:deep(.o-badge) {
@apply bg-red-500 text-white;
}
:deep(.c-badge) {
@apply bg-blue-500 text-white;
}
:deep(.s-badge) {
@apply bg-yellow-500;
}
</style>