97 lines
2.7 KiB
Vue
97 lines
2.7 KiB
Vue
<script setup>
|
|
import { filterInputClass, filterLabelClass, thFilterClass } from '@/Components/Supervisor/ui.js';
|
|
|
|
const props = defineProps({
|
|
label: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
align: {
|
|
type: String,
|
|
default: 'left',
|
|
},
|
|
sortable: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
sortKey: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
activeSort: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
sortDirection: {
|
|
type: String,
|
|
default: 'asc',
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(['sort']);
|
|
|
|
const isActive = () => props.sortable && props.activeSort === props.sortKey;
|
|
|
|
const handleSort = () => {
|
|
if (props.sortable && props.sortKey) {
|
|
emit('sort', props.sortKey);
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<th
|
|
:class="[
|
|
thFilterClass,
|
|
align === 'right' ? 'text-right' : 'text-left',
|
|
]"
|
|
>
|
|
<button
|
|
v-if="sortable"
|
|
type="button"
|
|
class="mb-1.5 flex items-center gap-1 text-xs font-semibold uppercase tracking-wide transition"
|
|
:class="[
|
|
align === 'right' ? 'ml-auto' : '',
|
|
isActive() ? 'text-indigo-600' : 'text-slate-600 hover:text-indigo-600',
|
|
]"
|
|
@click="handleSort"
|
|
>
|
|
<span>{{ label }}</span>
|
|
<svg
|
|
v-if="isActive() && sortDirection === 'asc'"
|
|
class="h-3.5 w-3.5 flex-shrink-0"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 15l7-7 7 7" />
|
|
</svg>
|
|
<svg
|
|
v-else-if="isActive() && sortDirection === 'desc'"
|
|
class="h-3.5 w-3.5 flex-shrink-0"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
|
|
</svg>
|
|
<svg
|
|
v-else
|
|
class="h-3.5 w-3.5 flex-shrink-0 text-slate-300"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 9l4-4 4 4M8 15l4 4 4-4" />
|
|
</svg>
|
|
</button>
|
|
<span v-else :class="filterLabelClass">{{ label }}</span>
|
|
<slot>
|
|
<span class="block h-[34px]" aria-hidden="true" />
|
|
</slot>
|
|
</th>
|
|
</template>
|