49 lines
1.4 KiB
Vue
49 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import AssigneeFilter from '@/components/AssigneeFilter.vue'
|
|
import TextFilter from '@/components/TextFilter.vue'
|
|
import StatusFilter from '@/components/StatusFilter.vue'
|
|
import ProjectMenu from '@/components/ProjectMenu.vue'
|
|
|
|
interface Props {
|
|
text?: string | null
|
|
assigneeId?: string | null
|
|
status?: string | null
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), { text: null, assigneeId: null })
|
|
const emit = defineEmits<{
|
|
'update:text': [value: string | null]
|
|
'update:assigneeId': [value: string | null]
|
|
'update:status': [value: string | null]
|
|
'update:clear': []
|
|
}>()
|
|
|
|
const selectedAssignees = computed(() => (props.assigneeId ? [props.assigneeId] : []))
|
|
|
|
function onAssigneeChanged(value: string[]) {
|
|
emit('update:assigneeId', value.at(-1) ?? null)
|
|
}
|
|
|
|
function onStatusChanged(alias: string) {
|
|
emit('update:status', alias)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="filter-grid ga-4 align-center">
|
|
<project-menu />
|
|
<text-filter :model-value="text" @update:model-value="emit('update:text', $event)" />
|
|
<status-filter :status="status" @changed="onStatusChanged" />
|
|
<assignee-filter :selected="selectedAssignees" @changed="onAssigneeChanged" />
|
|
<v-btn density="compact" variant="text" @click="emit('update:clear')">Clear Filters</v-btn>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.filter-grid {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr auto auto auto;
|
|
}
|
|
</style>
|