Skip to content

Instantly share code, notes, and snippets.

@HarshilPatel007
Created February 25, 2025 08:20
Show Gist options
  • Select an option

  • Save HarshilPatel007/62038af80d5b0076788dde59731038c7 to your computer and use it in GitHub Desktop.

Select an option

Save HarshilPatel007/62038af80d5b0076788dde59731038c7 to your computer and use it in GitHub Desktop.
table.vue
<script setup lang="ts">
import TaskEditModal from '@/components/TaskEditModal.vue'
import DataTable from '@/components/dataTable/DataTable.vue'
import DataTableRowAction from '@/components/dataTable/DataTableRowAction.vue'
import Avatar from '@/components/ui/avatar/Avatar.vue'
import AvatarFallback from '@/components/ui/avatar/AvatarFallback.vue'
import AvatarImage from '@/components/ui/avatar/AvatarImage.vue'
import Badge from '@/components/ui/badge/Badge.vue'
import { httpClient } from '@/utils/api'
import { LoaderCircle } from 'lucide-vue-next'
import { h, onMounted, ref } from 'vue'
interface Task {
id: number
title: string
description: string
status: string
priority: string
tags: string[]
startDate: string
dueDate: string
author: { fullName: string; profilePictureUrl: string }
assignees: { fullName: string; profilePictureUrl: string }[]
}
// Logged-in user info
const userDetails = ref<any>(null)
const isLoadingUser = ref(true)
const errorMessageUser = ref('')
// Tasks data
const tasks = ref<Task[]>([])
const selectedTask = ref<any>(null) // Track selected task
const isDialogOpen = ref(false) // Control dialog visibility
// Fetch user details
const fetchUserInfo = async () => {
try {
const response = await httpClient(`http://localhost:8000/user/me`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
if (!response.ok) {
throw new Error('Network response was not ok')
}
const data = await response.json()
userDetails.value = data
} catch (error: any) {
errorMessageUser.value = 'Failed to fetch user data: ' + error.message
} finally {
isLoadingUser.value = false
}
}
// Fetch tasks based on userId
const fetchUserTasks = async () => {
if (userDetails.value?.UserDetails?.userId) {
try {
const response = await httpClient(
`http://localhost:8000/tasks/user/${userDetails.value.UserDetails.userId}`,
{
method: 'GET',
},
)
if (!response.ok) {
throw new Error('Failed to fetch tasks')
}
const data = await response.json()
tasks.value = data
} catch (error: any) {
errorMessageUser.value = 'Failed to fetch tasks: ' + error.message
}
}
}
// Fetch user info and tasks after mounted
onMounted(async () => {
await fetchUserInfo()
if (!isLoadingUser.value && !errorMessageUser.value) {
await fetchUserTasks()
}
})
const handleEdit = (taskRow: any) => {
selectedTask.value = taskRow.original
isDialogOpen.value = true // Open the modal directly
console.log('Editing task details:', selectedTask.value)
}
const handleTaskUpdated = (updatedTask: Task) => {
const index = tasks.value.findIndex((task) => task.id === updatedTask.id)
if (index === -1) return // Early return if task is not found
selectedTask.value = null // Close the modal
}
// Table columns definition
const columns = [
{
accessorKey: 'title',
header: 'Title',
enableSorting: false,
},
{
accessorKey: 'description',
header: 'Description',
enableSorting: false,
},
{
accessorKey: 'status',
header: 'Status',
},
{
accessorKey: 'priority',
header: 'Priority',
filterFn: 'filterMultipleValues',
},
{
accessorKey: 'tags',
header: 'Tags',
cell: ({ getValue }) => {
const tags = getValue()
return tags.map((tag: string) => h(Badge, { key: tag }, tag))
},
},
{
accessorKey: 'startDate',
header: 'Start Date',
cell: ({ getValue }) =>
new Date(getValue()).toLocaleDateString('en-GB', {
day: 'numeric',
month: 'short',
year: 'numeric',
}),
},
{
accessorKey: 'dueDate',
header: 'Due Date',
cell: ({ getValue }) =>
new Date(getValue()).toLocaleDateString('en-GB', {
day: 'numeric',
month: 'short',
year: 'numeric',
}),
},
{
accessorKey: 'author',
header: 'Author',
cell: ({ getValue }) => {
const author = getValue()
return h(Avatar, {}, [
h(AvatarImage, { src: author.profilePictureUrl, alt: author.fullName }),
h(AvatarFallback, {}, author.fullName.charAt(0) || 'A'),
])
},
},
{
accessorKey: 'assignees',
header: 'Assignee',
cell: ({ getValue }) => {
const assignees = getValue()
return assignees.map((assignee: { fullName: string; profilePictureUrl: string }) =>
h(Avatar, {}, [
h(AvatarImage, { src: assignee.profilePictureUrl, alt: assignee.fullName }),
h(AvatarFallback, {}, assignee.fullName.charAt(0) || 'A'),
]),
)
},
},
{
accessorKey: 'edit',
header: '',
cell: ({ row }) => h(DataTableRowAction, { row: row, handleEdit: handleEdit }),
enableHiding: false,
enableSorting: false,
enableGlobalFilter: false,
enableColumnFilter: false,
},
]
</script>
<template>
<div class="container">
<div class="my-10">
<!-- Loading user info -->
<div v-if="isLoadingUser" class="flex items-center">
<LoaderCircle class="mr-2 h-6 w-6 animate-spin" />
Loading user information...
</div>
<!-- Error message if user info fails to load -->
<div v-if="errorMessageUser" class="text-red-500 text-sm mt-4">
{{ errorMessageUser }}
</div>
<!-- Tasks Table if data is loaded successfully -->
<div v-if="!isLoadingUser && !errorMessageUser && tasks.length > 0">
<DataTable :columns="columns" :data="tasks" />
</div>
<TaskEditModal
v-if="selectedTask"
:task="selectedTask"
:open="isDialogOpen"
@update:open="isDialogOpen = $event"
@task-updated="handleTaskUpdated"
/>
</div>
</div>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment