68 lines
1.9 KiB
Vue
68 lines
1.9 KiB
Vue
<script setup lang="ts" generic="Task extends { [key: string]: any;}">
|
|
import type { Table } from '@tanstack/vue-table'
|
|
import { computed } from 'vue'
|
|
import Iconify from '../iconify.vue'
|
|
import DataTableFacetedFilter from './DataTableFacetedFilter.vue'
|
|
import DataTableViewOptions from './DataTableViewOptions.vue'
|
|
|
|
interface DataTableToolbarProps {
|
|
table: Table<Task>
|
|
filter?: {
|
|
label: string
|
|
key: keyof Task
|
|
options: {
|
|
label: string
|
|
value: string
|
|
icon?: string
|
|
}[]
|
|
}[]
|
|
}
|
|
|
|
const props = defineProps<DataTableToolbarProps>()
|
|
|
|
const isFiltered = computed(() => props.table.getState().columnFilters.length > 0)
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="flex justify-center items-center w-full py-10">
|
|
<Input
|
|
placeholder="搜索..."
|
|
:model-value="table.getColumn('title')?.getFilterValue() as string"
|
|
class="h-12 w-[550px]" @input="table.getColumn('title')?.setFilterValue($event.target.value)"
|
|
/>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center flex-1 space-x-2">
|
|
<DataTableFacetedFilter
|
|
v-for="(item, i) in filter"
|
|
:key="i"
|
|
:column="table.getColumn(item.key.toString())"
|
|
:title="item.label"
|
|
:options="item.options.map(i => ({
|
|
label: i.label,
|
|
value: i.value,
|
|
icon: h(Iconify, { icon: i.icon }),
|
|
}))"
|
|
/>
|
|
|
|
<div>
|
|
<Button
|
|
v-if="isFiltered"
|
|
variant="ghost"
|
|
class="h-8 px-2 lg:px-3"
|
|
@click="table.resetColumnFilters()"
|
|
>
|
|
Reset
|
|
<Iconify icon="ph:x" class="w-4 h-4 ml-2" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<div class="flex gap-2 justify-center items-center">
|
|
<slot />
|
|
<DataTableViewOptions :table="table" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|