added searching and sorting system
This commit is contained in:
@@ -10,11 +10,17 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table'
|
||||
import { Plus, X } from 'lucide-vue-next';
|
||||
import { ArrowUpDown, Funnel, Plus, Search, X } from 'lucide-vue-next';
|
||||
import Button from '@/components/ui/button/Button.vue';
|
||||
import TrainingReportForm from '@/components/trainingReport/trainingReportForm.vue';
|
||||
import Checkbox from '@/components/ui/checkbox/Checkbox.vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import Select from '@/components/ui/select/Select.vue';
|
||||
import SelectTrigger from '@/components/ui/select/SelectTrigger.vue';
|
||||
import SelectValue from '@/components/ui/select/SelectValue.vue';
|
||||
import SelectContent from '@/components/ui/select/SelectContent.vue';
|
||||
import SelectItem from '@/components/ui/select/SelectItem.vue';
|
||||
import Input from '@/components/ui/input/Input.vue';
|
||||
|
||||
enum sidePanelState { view, create, closed };
|
||||
|
||||
@@ -60,8 +66,24 @@ async function closeTrainingReport() {
|
||||
focusedTrainingReport.value = null;
|
||||
}
|
||||
|
||||
const sortMode = ref<string>("descending");
|
||||
const searchString = ref<string>("");
|
||||
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
watch(searchString, (newValue) => {
|
||||
if (debounceTimer) clearTimeout(debounceTimer);
|
||||
|
||||
debounceTimer = setTimeout(() => {
|
||||
loadTrainingReports();
|
||||
}, 300); // 300ms debounce
|
||||
});
|
||||
|
||||
watch(() => sortMode.value, async (newSortMode) => {
|
||||
loadTrainingReports();
|
||||
})
|
||||
|
||||
async function loadTrainingReports() {
|
||||
trainingReports.value = await getTrainingReports();
|
||||
trainingReports.value = await getTrainingReports(sortMode.value, searchString.value);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -69,7 +91,6 @@ onMounted(async () => {
|
||||
if (route.params.id)
|
||||
viewTrainingReport(Number(route.params.id))
|
||||
loaded.value = true;
|
||||
console.log("load")
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -77,12 +98,41 @@ onMounted(async () => {
|
||||
<div class="px-20 mx-auto max-w-[100rem] flex mt-5">
|
||||
<!-- training report list -->
|
||||
<div class="px-4 my-3" :class="sidePanel == sidePanelState.closed ? 'w-full' : 'w-2/5'">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex justify-between mb-4">
|
||||
<p class="scroll-m-20 text-2xl font-semibold tracking-tight">Training Reports</p>
|
||||
<Button @click="router.push('/trainingReport/new')">
|
||||
<Plus></Plus> New Training Report
|
||||
</Button>
|
||||
</div>
|
||||
<!-- search/filter -->
|
||||
<div class="flex justify-between">
|
||||
<!-- <Search></Search>
|
||||
<Funnel></Funnel> -->
|
||||
<div></div>
|
||||
<div class="flex flex-row gap-5">
|
||||
<div>
|
||||
<label class="text-muted-foreground">Search</label>
|
||||
<Input v-model="searchString"></Input>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<label class="text-muted-foreground">Sort By</label>
|
||||
<Select v-model="sortMode">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Sort By" />
|
||||
<!-- <ArrowUpDown></ArrowUpDown> -->
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ascending">
|
||||
Date (Ascending)
|
||||
</SelectItem>
|
||||
<SelectItem value="descending">
|
||||
Date (Descending)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
||||
<Table>
|
||||
<TableHeader class="">
|
||||
@@ -120,12 +170,13 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="max-h-[70vh] overflow-auto scrollbar-themed my-5">
|
||||
<div class="flex flex-col mb-5 border rounded-lg bg-muted/70 p-2 py-3 px-4">
|
||||
<p class="scroll-m-20 text-xl font-semibold tracking-tight">{{ focusedTrainingReport.course_name }}</p>
|
||||
<p class="scroll-m-20 text-xl font-semibold tracking-tight">{{ focusedTrainingReport.course_name }}
|
||||
</p>
|
||||
<div class="flex gap-10">
|
||||
<p class="text-muted-foreground">{{ focusedTrainingReport.event_date }}</p>
|
||||
<p class="">Created by {{ focusedTrainingReport.created_by_name === null ? "Unknown User" :
|
||||
focusedTrainingReport.created_by_name
|
||||
}}
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -143,7 +194,9 @@ onMounted(async () => {
|
||||
<p>{{ person.attendee_name }}</p>
|
||||
<p class="">{{ person.role.name }}</p>
|
||||
<p class="col-span-2 text-right px-2"
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">{{ person.remarks == "" ? '--'
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">
|
||||
{{ person.remarks == "" ?
|
||||
'--'
|
||||
: person.remarks }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,7 +221,9 @@ onMounted(async () => {
|
||||
:model-value="person.passed_qual" class="pointer-events-none ml-1">
|
||||
</Checkbox>
|
||||
<p class="col-span-2 text-right px-2"
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">{{ person.remarks == "" ? '--'
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">
|
||||
{{ person.remarks == "" ?
|
||||
'--'
|
||||
: person.remarks }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -195,7 +250,9 @@ onMounted(async () => {
|
||||
<div></div>
|
||||
<div></div>
|
||||
<p class="col-span-2 text-right px-2"
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">{{ person.remarks == "" ? '--'
|
||||
:class="person.remarks == '' ? 'text-muted-foreground' : ''">
|
||||
{{ person.remarks == "" ?
|
||||
'--'
|
||||
: person.remarks }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -219,7 +276,8 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
||||
<TrainingReportForm class="w-full pl-2"
|
||||
@submit="(newID) => { router.push(`/trainingReport/${newID}`); loadTrainingReports() }"></TrainingReportForm>
|
||||
@submit="(newID) => { router.push(`/trainingReport/${newID}`); loadTrainingReports() }">
|
||||
</TrainingReportForm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user