implemented expandable LOA details
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu"
|
} from "@/components/ui/dropdown-menu"
|
||||||
import { Ellipsis } from "lucide-vue-next";
|
import { ChevronDown, ChevronUp, Ellipsis, X } from "lucide-vue-next";
|
||||||
import { cancelLOA, extendLOA, getAllLOAs, getMyLOAs } from "@/api/loa";
|
import { cancelLOA, extendLOA, getAllLOAs, getMyLOAs } from "@/api/loa";
|
||||||
import { onMounted, ref, computed } from "vue";
|
import { onMounted, ref, computed } from "vue";
|
||||||
import { LOARequest } from "@shared/types/loa";
|
import { LOARequest } from "@shared/types/loa";
|
||||||
@@ -104,6 +104,9 @@ async function commitExtend() {
|
|||||||
isExtending.value = false;
|
isExtending.value = false;
|
||||||
await loadLOAs();
|
await loadLOAs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const expanded = ref<number | null>(null);
|
||||||
|
const hoverID = ref<number | null>(null);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -139,51 +142,91 @@ async function commitExtend() {
|
|||||||
<TableHead>Type</TableHead>
|
<TableHead>Type</TableHead>
|
||||||
<TableHead>Start</TableHead>
|
<TableHead>Start</TableHead>
|
||||||
<TableHead>End</TableHead>
|
<TableHead>End</TableHead>
|
||||||
<TableHead class="w-[500px]">Reason</TableHead>
|
<!-- <TableHead class="w-[500px]">Reason</TableHead> -->
|
||||||
<TableHead>Posted on</TableHead>
|
<TableHead>Posted on</TableHead>
|
||||||
<TableHead>Status</TableHead>
|
<TableHead>Status</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow v-for="post in LOAList" :key="post.id" class="hover:bg-muted/50">
|
<template v-for="post in LOAList" :key="post.id">
|
||||||
<TableCell class="font-medium">
|
<TableRow class="hover:bg-muted/50 cursor-pointer" @click="expanded = post.id"
|
||||||
<MemberCard :member-id="post.member_id"></MemberCard>
|
@mouseenter="hoverID = post.id" @mouseleave="hoverID = null" :class="{
|
||||||
</TableCell>
|
'border-b-0': expanded === post.id,
|
||||||
<TableCell>{{ post.type_name }}</TableCell>
|
'bg-muted/50': hoverID === post.id
|
||||||
<TableCell>{{ formatDate(post.start_date) }}</TableCell>
|
}">
|
||||||
<TableCell>{{ post.extended_till ? formatDate(post.extended_till) : formatDate(post.end_date) }}
|
<TableCell class="font-medium">
|
||||||
</TableCell>
|
<MemberCard :member-id="post.member_id"></MemberCard>
|
||||||
<TableCell>{{ post.reason }}</TableCell>
|
</TableCell>
|
||||||
<TableCell>{{ formatDate(post.filed_date) }}</TableCell>
|
<TableCell>{{ post.type_name }}</TableCell>
|
||||||
<TableCell>
|
<TableCell>{{ formatDate(post.start_date) }}</TableCell>
|
||||||
<Badge v-if="loaStatus(post) === 'Upcoming'" class="bg-blue-400">Upcoming</Badge>
|
<TableCell>{{ post.extended_till ? formatDate(post.extended_till) :
|
||||||
<Badge v-else-if="loaStatus(post) === 'Active'" class="bg-green-500">Active</Badge>
|
formatDate(post.end_date) }}
|
||||||
<Badge v-else-if="loaStatus(post) === 'Overdue'" class="bg-yellow-400">Overdue</Badge>
|
</TableCell>
|
||||||
<Badge v-else class="bg-gray-400">Ended</Badge>
|
<!-- <TableCell>{{ post.reason }}</TableCell> -->
|
||||||
</TableCell>
|
<TableCell>{{ formatDate(post.filed_date) }}</TableCell>
|
||||||
<TableCell @click.stop="" class="text-right">
|
<TableCell>
|
||||||
<DropdownMenu>
|
<Badge v-if="loaStatus(post) === 'Upcoming'" class="bg-blue-400">Upcoming</Badge>
|
||||||
<DropdownMenuTrigger class="cursor-pointer">
|
<Badge v-else-if="loaStatus(post) === 'Active'" class="bg-green-500">Active</Badge>
|
||||||
<Ellipsis></Ellipsis>
|
<Badge v-else-if="loaStatus(post) === 'Overdue'" class="bg-yellow-400">Overdue</Badge>
|
||||||
</DropdownMenuTrigger>
|
<Badge v-else class="bg-gray-400">Ended</Badge>
|
||||||
<DropdownMenuContent>
|
</TableCell>
|
||||||
<DropdownMenuItem v-if="!post.closed && props.adminMode"
|
<TableCell @click.stop="" class="text-right">
|
||||||
@click="isExtending = true; targetLOA = post">
|
<DropdownMenu>
|
||||||
Extend
|
<DropdownMenuTrigger class="cursor-pointer">
|
||||||
</DropdownMenuItem>
|
<Button variant="ghost">
|
||||||
<DropdownMenuItem v-if="!post.closed" :variant="'destructive'"
|
<Ellipsis class="size-6"></Ellipsis>
|
||||||
@click="cancelAndReload(post.id)">{{ loaStatus(post) === 'Upcoming' ? 'Cancel' :
|
</Button>
|
||||||
'End' }}
|
</DropdownMenuTrigger>
|
||||||
</DropdownMenuItem>
|
<DropdownMenuContent>
|
||||||
<!-- Fallback: no actions available -->
|
<DropdownMenuItem v-if="!post.closed && props.adminMode"
|
||||||
<p v-if="post.closed || (!props.adminMode && post.closed)"
|
@click="isExtending = true; targetLOA = post">
|
||||||
class="p-2 text-center text-sm">
|
Extend
|
||||||
No actions
|
</DropdownMenuItem>
|
||||||
</p>
|
<DropdownMenuItem v-if="!post.closed" :variant="'destructive'"
|
||||||
</DropdownMenuContent>
|
@click="cancelAndReload(post.id)">{{ loaStatus(post) === 'Upcoming' ?
|
||||||
</DropdownMenu>
|
'Cancel' :
|
||||||
</TableCell>
|
'End' }}
|
||||||
</TableRow>
|
</DropdownMenuItem>
|
||||||
|
<!-- Fallback: no actions available -->
|
||||||
|
<p v-if="post.closed || (!props.adminMode && post.closed)"
|
||||||
|
class="p-2 text-center text-sm">
|
||||||
|
No actions
|
||||||
|
</p>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button v-if="expanded === post.id" @click.stop="expanded = null" variant="ghost">
|
||||||
|
<ChevronUp class="size-6" />
|
||||||
|
</Button>
|
||||||
|
<Button v-else @click.stop="expanded = post.id" variant="ghost">
|
||||||
|
<ChevronDown class="size-6" />
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow v-if="expanded === post.id" @mouseenter="hoverID = post.id"
|
||||||
|
@mouseleave="hoverID = null" :class="{ 'bg-muted/50 border-t-0': hoverID === post.id }">
|
||||||
|
<TableCell :colspan="8" class="p-0">
|
||||||
|
<div class="w-full p-3 mb-6 space-y-3">
|
||||||
|
<div class="flex justify-between items-start gap-4">
|
||||||
|
<div class="flex-1">
|
||||||
|
<!-- Title -->
|
||||||
|
<p class="text-md font-semibold text-foreground">
|
||||||
|
Reason
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<p
|
||||||
|
class="mt-1 text-md whitespace-pre-wrap leading-relaxed text-muted-foreground">
|
||||||
|
{{ post.reason }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</template>
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user