From 45923d3a1f0221a35b1753a6db671a9ef70463a9 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 8 Mar 2025 18:48:34 -0600 Subject: [PATCH] feat(services): add sorting functionality for services - Implement local storage-based sorting for services - Add sorting options by name, type, and creation date - Provide ascending and descending sort order selection - Enhance service list usability with dynamic sorting --- .../pages/dashboard/project/[projectId].tsx | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/pages/dashboard/project/[projectId].tsx b/apps/dokploy/pages/dashboard/project/[projectId].tsx index cf0a5f99..e1eccbdc 100644 --- a/apps/dokploy/pages/dashboard/project/[projectId].tsx +++ b/apps/dokploy/pages/dashboard/project/[projectId].tsx @@ -73,7 +73,7 @@ import type { } from "next"; import Head from "next/head"; import { useRouter } from "next/router"; -import { type ReactElement, useMemo, useState } from "react"; +import { type ReactElement, useMemo, useState, useEffect } from "react"; import { toast } from "sonner"; import superjson from "superjson"; import { @@ -220,6 +220,38 @@ const Project = ( const [isBulkActionLoading, setIsBulkActionLoading] = useState(false); const { projectId } = props; const { data: auth } = api.user.get.useQuery(); + const [sortBy, setSortBy] = useState(() => { + if (typeof window !== "undefined") { + return localStorage.getItem("servicesSort") || "createdAt-desc"; + } + return "createdAt-desc"; + }); + + useEffect(() => { + localStorage.setItem("servicesSort", sortBy); + }, [sortBy]); + + const sortServices = (services: Services[]) => { + const [field, direction] = sortBy.split("-"); + return [...services].sort((a, b) => { + let comparison = 0; + switch (field) { + case "name": + comparison = a.name.localeCompare(b.name); + break; + case "type": + comparison = a.type.localeCompare(b.type); + break; + case "createdAt": + comparison = + new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(); + break; + default: + comparison = 0; + } + return direction === "asc" ? comparison : -comparison; + }); + }; const { data, isLoading, refetch } = api.project.one.useQuery({ projectId }); const { data: allProjects } = api.project.all.useQuery(); @@ -488,7 +520,7 @@ const Project = ( const filteredServices = useMemo(() => { if (!applications) return []; - return applications.filter( + const filtered = applications.filter( (service) => (service.name.toLowerCase().includes(searchQuery.toLowerCase()) || service.description @@ -496,7 +528,8 @@ const Project = ( .includes(searchQuery.toLowerCase())) && (selectedTypes.length === 0 || selectedTypes.includes(service.type)), ); - }, [applications, searchQuery, selectedTypes]); + return sortServices(filtered); + }, [applications, searchQuery, selectedTypes, sortBy]); return (
@@ -741,6 +774,23 @@ const Project = ( />
+