Created
February 25, 2025 08:20
-
-
Save HarshilPatel007/62038af80d5b0076788dde59731038c7 to your computer and use it in GitHub Desktop.
table.vue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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