1- import type { findProjectById } from "@dokploy/server" ;
1+ import type { findEnvironmentById } from "@dokploy/server" ;
22import { validateRequest } from "@dokploy/server/lib/auth" ;
33import { createServerSideHelpers } from "@trpc/react-query/server" ;
44import {
@@ -102,6 +102,7 @@ import { api } from "@/utils/api";
102102export type Services = {
103103 appName : string ;
104104 serverId ?: string | null ;
105+ serverName ?: string | null ;
105106 name : string ;
106107 type :
107108 | "mariadb"
@@ -118,8 +119,7 @@ export type Services = {
118119 lastDeployDate ?: Date | null ;
119120} ;
120121
121- type Project = Awaited < ReturnType < typeof findProjectById > > ;
122- type Environment = Project [ "environments" ] [ 0 ] ;
122+ type Environment = Awaited < ReturnType < typeof findEnvironmentById > > ;
123123
124124export const extractServicesFromEnvironment = (
125125 environment : Environment | undefined ,
@@ -154,6 +154,7 @@ export const extractServicesFromEnvironment = (
154154 status : item . applicationStatus ,
155155 description : item . description ,
156156 serverId : item . serverId ,
157+ serverName : item ?. server ?. name || null ,
157158 lastDeployDate,
158159 } ;
159160 } ) || [ ] ;
@@ -168,6 +169,7 @@ export const extractServicesFromEnvironment = (
168169 status : item . applicationStatus ,
169170 description : item . description ,
170171 serverId : item . serverId ,
172+ serverName : item ?. server ?. name || null ,
171173 } ) ) || [ ] ;
172174
173175 const postgres : Services [ ] =
@@ -180,6 +182,7 @@ export const extractServicesFromEnvironment = (
180182 status : item . applicationStatus ,
181183 description : item . description ,
182184 serverId : item . serverId ,
185+ serverName : item ?. server ?. name || null ,
183186 } ) ) || [ ] ;
184187
185188 const mongo : Services [ ] =
@@ -192,6 +195,7 @@ export const extractServicesFromEnvironment = (
192195 status : item . applicationStatus ,
193196 description : item . description ,
194197 serverId : item . serverId ,
198+ serverName : item ?. server ?. name || null ,
195199 } ) ) || [ ] ;
196200
197201 const redis : Services [ ] =
@@ -204,6 +208,7 @@ export const extractServicesFromEnvironment = (
204208 status : item . applicationStatus ,
205209 description : item . description ,
206210 serverId : item . serverId ,
211+ serverName : item ?. server ?. name || null ,
207212 } ) ) || [ ] ;
208213
209214 const mysql : Services [ ] =
@@ -216,6 +221,7 @@ export const extractServicesFromEnvironment = (
216221 status : item . applicationStatus ,
217222 description : item . description ,
218223 serverId : item . serverId ,
224+ serverName : item ?. server ?. name || null ,
219225 } ) ) || [ ] ;
220226
221227 const compose : Services [ ] =
@@ -244,6 +250,7 @@ export const extractServicesFromEnvironment = (
244250 status : item . composeStatus ,
245251 description : item . description ,
246252 serverId : item . serverId ,
253+ serverName : item ?. server ?. name || null ,
247254 lastDeployDate,
248255 } ;
249256 } ) || [ ] ;
@@ -392,6 +399,7 @@ const EnvironmentPage = (
392399 const [ isDropdownOpen , setIsDropdownOpen ] = useState ( false ) ;
393400 const [ isBulkDeleteDialogOpen , setIsBulkDeleteDialogOpen ] = useState ( false ) ;
394401 const [ deleteVolumes , setDeleteVolumes ] = useState ( false ) ;
402+ const [ selectedServerId , setSelectedServerId ] = useState < string > ( "all" ) ;
395403
396404 const handleSelectAll = ( ) => {
397405 if ( selectedServices . length === filteredServices . length ) {
@@ -781,6 +789,27 @@ const EnvironmentPage = (
781789 setIsBulkActionLoading ( false ) ;
782790 } ;
783791
792+ // Get unique servers from services
793+ const availableServers = useMemo ( ( ) => {
794+ if ( ! applications ) return [ ] ;
795+ const servers = new Map < string , { serverId : string ; serverName : string } > ( ) ;
796+ applications . forEach ( ( service ) => {
797+ if ( service . serverId && service . serverName ) {
798+ servers . set ( service . serverId , {
799+ serverId : service . serverId ,
800+ serverName : service . serverName ,
801+ } ) ;
802+ }
803+ } ) ;
804+ return Array . from ( servers . values ( ) ) ;
805+ } , [ applications ] ) ;
806+
807+ // Check if there are services without a server (Dokploy server)
808+ const hasServicesWithoutServer = useMemo ( ( ) => {
809+ if ( ! applications ) return false ;
810+ return applications . some ( ( service ) => ! service . serverId ) ;
811+ } , [ applications ] ) ;
812+
784813 const filteredServices = useMemo ( ( ) => {
785814 if ( ! applications ) return [ ] ;
786815 const filtered = applications . filter (
@@ -789,10 +818,14 @@ const EnvironmentPage = (
789818 service . description
790819 ?. toLowerCase ( )
791820 . includes ( searchQuery . toLowerCase ( ) ) ) &&
792- ( selectedTypes . length === 0 || selectedTypes . includes ( service . type ) ) ,
821+ ( selectedTypes . length === 0 || selectedTypes . includes ( service . type ) ) &&
822+ ( selectedServerId === "" ||
823+ selectedServerId === "all" ||
824+ ( selectedServerId === "dokploy-server" && ! service . serverId ) ||
825+ service . serverId === selectedServerId ) ,
793826 ) ;
794827 return sortServices ( filtered ) ;
795- } , [ applications , searchQuery , selectedTypes , sortBy ] ) ;
828+ } , [ applications , searchQuery , selectedTypes , selectedServerId , sortBy ] ) ;
796829
797830 const selectedServicesWithRunningStatus = useMemo ( ( ) => {
798831 return filteredServices . filter (
@@ -1366,6 +1399,39 @@ const EnvironmentPage = (
13661399 </ Command >
13671400 </ PopoverContent >
13681401 </ Popover >
1402+ { ( availableServers . length > 0 ||
1403+ hasServicesWithoutServer ) && (
1404+ < Select
1405+ value = { selectedServerId || "all" }
1406+ onValueChange = { setSelectedServerId }
1407+ >
1408+ < SelectTrigger className = "lg:w-[200px]" >
1409+ < SelectValue placeholder = "Filter by server..." />
1410+ </ SelectTrigger >
1411+ < SelectContent >
1412+ < SelectItem value = "all" > All servers</ SelectItem >
1413+ { hasServicesWithoutServer && (
1414+ < SelectItem value = "dokploy-server" >
1415+ < div className = "flex items-center gap-2" >
1416+ < ServerIcon className = "size-4" />
1417+ < span > Dokploy server</ span >
1418+ </ div >
1419+ </ SelectItem >
1420+ ) }
1421+ { availableServers . map ( ( server ) => (
1422+ < SelectItem
1423+ key = { server . serverId }
1424+ value = { server . serverId }
1425+ >
1426+ < div className = "flex items-center gap-2" >
1427+ < ServerIcon className = "size-4" />
1428+ < span > { server . serverName } </ span >
1429+ </ div >
1430+ </ SelectItem >
1431+ ) ) }
1432+ </ SelectContent >
1433+ </ Select >
1434+ ) }
13691435 </ div >
13701436 </ div >
13711437
@@ -1471,7 +1537,15 @@ const EnvironmentPage = (
14711537 </ CardTitle >
14721538 </ CardHeader >
14731539 < CardFooter className = "mt-auto" >
1474- < div className = "space-y-1 text-sm" >
1540+ < div className = "space-y-1 text-sm w-full" >
1541+ { service . serverName && (
1542+ < div className = "flex items-center gap-1.5 text-xs text-muted-foreground mb-1" >
1543+ < ServerIcon className = "size-3" />
1544+ < span className = "truncate" >
1545+ { service . serverName }
1546+ </ span >
1547+ </ div >
1548+ ) }
14751549 < DateTooltip date = { service . createdAt } >
14761550 Created
14771551 </ DateTooltip >
0 commit comments