diff --git a/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/AuditTable.tsx b/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/AuditTable.tsx
new file mode 100644
index 000000000..8ba55b54e
--- /dev/null
+++ b/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/AuditTable.tsx
@@ -0,0 +1,88 @@
+'use client'
+import { useState } from 'react'
+import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
+import {
+ Pagination,
+ PaginationContent,
+ PaginationItem,
+ PaginationLink,
+ PaginationNext,
+ PaginationPrevious,
+} from '@/components/ui/pagination'
+import { UserTaskEvent } from 'littlehorse-client/proto'
+
+type AuditTableProps = {
+ events: UserTaskEvent[]
+}
+
+export function AuditTable({ events }: AuditTableProps) {
+ const [currentPage, setCurrentPage] = useState(1)
+ const itemsPerPage = 10
+
+ const allEvents = events.filter(event => event.saved !== undefined).reverse()
+
+ const totalPages = Math.ceil(allEvents.length / itemsPerPage)
+ const startIndex = (currentPage - 1) * itemsPerPage
+ const paginatedEvents = allEvents.slice(startIndex, startIndex + itemsPerPage)
+
+ return (
+
+
+ Audit Log
+
+
+ Saved At
+ Saved By
+
+
+
+ {paginatedEvents.map(event => (
+
+ {new Date(event.time ?? 'N/A').toLocaleString()}
+ {event.saved?.userId}
+
+ ))}
+
+
+
+ {totalPages > 1 && (
+
+
+
+ {
+ e.preventDefault()
+ if (currentPage > 1) setCurrentPage(currentPage - 1)
+ }}
+ />
+
+ {[...Array(totalPages)].map((_, index) => (
+
+ {
+ e.preventDefault()
+ setCurrentPage(index + 1)
+ }}
+ >
+ {index + 1}
+
+
+ ))}
+
+ {
+ e.preventDefault()
+ if (currentPage < totalPages) setCurrentPage(currentPage + 1)
+ }}
+ />
+
+
+
+ )}
+
+ )
+}
diff --git a/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/page.tsx b/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/page.tsx
index d3759c669..39fd08d4f 100644
--- a/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/page.tsx
+++ b/dashboard/src/app/[tenantId]/userTaskDef/audit/[...ids]/page.tsx
@@ -1,10 +1,10 @@
import { getUserTaskRun } from '@/app/actions/getUserTaskRun'
import { Metadata } from 'next'
-import { notFound, useParams } from 'next/navigation'
+import { notFound } from 'next/navigation'
import { ClientError, Status } from 'nice-grpc-common'
-import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { Details } from '@/app/[tenantId]/components/Details'
import LinkWithTenant from '@/app/[tenantId]/components/LinkWithTenant'
+import { AuditTable } from './AuditTable'
type Props = { params: { ids: string[]; tenantId: string } }
@@ -13,6 +13,7 @@ export default async function Page({ params: { ids, tenantId } }: Props) {
try {
const userTaskRun = await getUserTaskRun(tenantId, wfRunId, userTaskGuid)
+
return (
-
- Audit Log
-
-
- Timestamp
- {/* User */}
-
-
-
- {userTaskRun.events.map(event => (
-
- {new Date(event.time as string).toLocaleString()}
-
- ))}
-
-
+ {userTaskRun.events.some(event => event.saved !== undefined) ? (
+
+ ) : (
+
+
No save history found.
+
This user task has not been saved since it was created.
+
+ )}
)
} catch (error) {
diff --git a/dashboard/src/components/ui/pagination.tsx b/dashboard/src/components/ui/pagination.tsx
index fec5aa562..74addbf4d 100644
--- a/dashboard/src/components/ui/pagination.tsx
+++ b/dashboard/src/components/ui/pagination.tsx
@@ -1,55 +1,42 @@
-import * as React from "react"
-import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
+import * as React from 'react'
+import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
-import { cn } from "@/components/utils"
-import { ButtonProps, buttonVariants } from "@/components/ui/button"
+import { cn } from '@/components/utils'
+import { ButtonProps, buttonVariants } from '@/components/ui/button'
-const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
+const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => (
)
-Pagination.displayName = "Pagination"
+Pagination.displayName = 'Pagination'
-const PaginationContent = React.forwardRef<
- HTMLUListElement,
- React.ComponentProps<"ul">
->(({ className, ...props }, ref) => (
-
-))
-PaginationContent.displayName = "PaginationContent"
+const PaginationContent = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+)
+PaginationContent.displayName = 'PaginationContent'
-const PaginationItem = React.forwardRef<
- HTMLLIElement,
- React.ComponentProps<"li">
->(({ className, ...props }, ref) => (
-
+const PaginationItem = React.forwardRef>(({ className, ...props }, ref) => (
+
))
-PaginationItem.displayName = "PaginationItem"
+PaginationItem.displayName = 'PaginationItem'
type PaginationLinkProps = {
isActive?: boolean
-} & Pick &
- React.ComponentProps<"a">
+} & Pick &
+ React.ComponentProps<'a'>
-const PaginationLink = ({
- className,
- isActive,
- size = "icon",
- ...props
-}: PaginationLinkProps) => (
+const PaginationLink = ({ className, isActive, size = 'icon', ...props }: PaginationLinkProps) => (
)
-PaginationLink.displayName = "PaginationLink"
+PaginationLink.displayName = 'PaginationLink'
-const PaginationPrevious = ({
- className,
- ...props
-}: React.ComponentProps) => (
-
+const PaginationPrevious = ({ className, ...props }: React.ComponentProps) => (
+
Previous
)
-PaginationPrevious.displayName = "PaginationPrevious"
+PaginationPrevious.displayName = 'PaginationPrevious'
-const PaginationNext = ({
- className,
- ...props
-}: React.ComponentProps) => (
-
+const PaginationNext = ({ className, ...props }: React.ComponentProps) => (
+
Next
)
-PaginationNext.displayName = "PaginationNext"
+PaginationNext.displayName = 'PaginationNext'
-const PaginationEllipsis = ({
- className,
- ...props
-}: React.ComponentProps<"span">) => (
-
+const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<'span'>) => (
+
More pages
)
-PaginationEllipsis.displayName = "PaginationEllipsis"
+PaginationEllipsis.displayName = 'PaginationEllipsis'
export {
Pagination,