|  |  |  | @@ -4,72 +4,85 @@ import type { dockerRouterType } from "@/server/api/routers/docker"; | 
		
	
		
			
				|  |  |  |  | import { api } from "@/trpc/react"; | 
		
	
		
			
				|  |  |  |  | import type { JSX } from "react"; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | function DockerRow({ | 
		
	
		
			
				|  |  |  |  | function DockerCard({ | 
		
	
		
			
				|  |  |  |  | 	containerInfo, | 
		
	
		
			
				|  |  |  |  | }: { | 
		
	
		
			
				|  |  |  |  | 	containerInfo: dockerRouterType["list"][number]; | 
		
	
		
			
				|  |  |  |  | }) { | 
		
	
		
			
				|  |  |  |  | 	const { data: latest, isError, isLoading } = api.docker.latest.useQuery({ id: containerInfo.container.id }, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false }); | 
		
	
		
			
				|  |  |  |  | 	const outdated = containerInfo.image.current.hash !== latest?.latest.hash; | 
		
	
		
			
				|  |  |  |  | 	const { data: latest, isError, isLoading, error } = api.docker.latest.useQuery({ id: containerInfo.container.id }, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false }); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	let latestFragment: JSX.Element | null = null; | 
		
	
		
			
				|  |  |  |  | 	if (isError) { | 
		
	
		
			
				|  |  |  |  | 		latestFragment = ( | 
		
	
		
			
				|  |  |  |  | 			<> | 
		
	
		
			
				|  |  |  |  | 				<td>{"Error"}</td> | 
		
	
		
			
				|  |  |  |  | 				<td>{"Error"}</td> | 
		
	
		
			
				|  |  |  |  | 			</> | 
		
	
		
			
				|  |  |  |  | 			<div className="flex flex-row flex-wrap *:basis-1/2"> | 
		
	
		
			
				|  |  |  |  | 				<dt>Tag</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd>Error: {error.message}</dd> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				<dt>Short Hash</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd>Error: {error.message}</dd> | 
		
	
		
			
				|  |  |  |  | 			</div> | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
		
			
				|  |  |  |  | 	} else if (isLoading) { | 
		
	
		
			
				|  |  |  |  | 		latestFragment = ( | 
		
	
		
			
				|  |  |  |  | 			<> | 
		
	
		
			
				|  |  |  |  | 				<td> | 
		
	
		
			
				|  |  |  |  | 					<span className="loading loading-dots loading-lg" /> | 
		
	
		
			
				|  |  |  |  | 				</td> | 
		
	
		
			
				|  |  |  |  | 				<td> | 
		
	
		
			
				|  |  |  |  | 					<span className="loading loading-dots loading-lg" /> | 
		
	
		
			
				|  |  |  |  | 				</td> | 
		
	
		
			
				|  |  |  |  | 			</> | 
		
	
		
			
				|  |  |  |  | 			<div className="flex flex-row flex-wrap *:basis-1/2"> | 
		
	
		
			
				|  |  |  |  | 				<dt>Tag</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd className="loading loading-dots loading-sm" /> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				<dt>Short Hash</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd className="loading loading-dots loading-sm" /> | 
		
	
		
			
				|  |  |  |  | 			</div> | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
		
			
				|  |  |  |  | 	} else if (latest) { | 
		
	
		
			
				|  |  |  |  | 		latestFragment = ( | 
		
	
		
			
				|  |  |  |  | 			<> | 
		
	
		
			
				|  |  |  |  | 				<td>{latest?.latest.tag}</td> | 
		
	
		
			
				|  |  |  |  | 				<td>{latest?.latest.hash}</td> | 
		
	
		
			
				|  |  |  |  | 			</> | 
		
	
		
			
				|  |  |  |  | 			<div className="flex flex-row flex-wrap *:basis-1/2"> | 
		
	
		
			
				|  |  |  |  | 				<dt>Tag</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd>{latest?.latest.tag ?? "Unknown"}</dd> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 				<dt>Short Hash</dt> | 
		
	
		
			
				|  |  |  |  | 				<dd>{latest?.latest.hash ?? "Unknown"}</dd> | 
		
	
		
			
				|  |  |  |  | 			</div> | 
		
	
		
			
				|  |  |  |  | 		); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	const outdated = containerInfo.image.current.hash !== latest?.latest.hash; | 
		
	
		
			
				|  |  |  |  | 	const showWarning = isLoading || (!isError && !isLoading && (!latest?.latest.tag || !latest?.latest.hash)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	return ( | 
		
	
		
			
				|  |  |  |  | 		<tr key={containerInfo.container.name} className={`${outdated ? "bg-base-200" : null}`}> | 
		
	
		
			
				|  |  |  |  | 			<td className={`border-l-8 ${isLoading ? "border-l-warning/80" : outdated ? "border-l-error/80" : "border-l-info/80"}`}>{containerInfo.container.name}</td> | 
		
	
		
			
				|  |  |  |  | 			<td>{containerInfo.image.name}</td> | 
		
	
		
			
				|  |  |  |  | 			<td>{containerInfo.image.current.tag}</td> | 
		
	
		
			
				|  |  |  |  | 			<td>{containerInfo.image.current.hash}</td> | 
		
	
		
			
				|  |  |  |  | 		<div | 
		
	
		
			
				|  |  |  |  | 			key={containerInfo.container.name} | 
		
	
		
			
				|  |  |  |  | 			className={`card card-outline card-compact w-80 border-t-8 bg-base-300 shadow-md ${showWarning ? "border-t-warning/80" : outdated ? "border-t-error/80" : "border-t-info/80"}`} | 
		
	
		
			
				|  |  |  |  | 		> | 
		
	
		
			
				|  |  |  |  | 			<dl className="card-body flex flex-col flex-wrap items-center justify-around text-base"> | 
		
	
		
			
				|  |  |  |  | 				<h2 className="text-center text-3xl">{containerInfo.container.name}</h2> | 
		
	
		
			
				|  |  |  |  | 				<p>{containerInfo.image.name}</p> | 
		
	
		
			
				|  |  |  |  | 				<div className="divider divider-primary m-1" /> | 
		
	
		
			
				|  |  |  |  | 				<h3 className="text-xl underline decoration-1 underline-offset-4">Current</h3> | 
		
	
		
			
				|  |  |  |  | 				<div className="flex flex-row flex-wrap *:basis-1/2"> | 
		
	
		
			
				|  |  |  |  | 					<dt>Tag</dt> | 
		
	
		
			
				|  |  |  |  | 					<dd>{containerInfo.image.current.tag}</dd> | 
		
	
		
			
				|  |  |  |  | 					<dt>Short Hash</dt> | 
		
	
		
			
				|  |  |  |  | 					<dd>{containerInfo.image.current.hash}</dd> | 
		
	
		
			
				|  |  |  |  | 				</div> | 
		
	
		
			
				|  |  |  |  | 				<div className="divider divider-primary m-0" /> | 
		
	
		
			
				|  |  |  |  | 				<h3 className="text-xl underline decoration-1 underline-offset-4">Latest</h3> | 
		
	
		
			
				|  |  |  |  | 				{latestFragment} | 
		
	
		
			
				|  |  |  |  | 		</tr> | 
		
	
		
			
				|  |  |  |  | 			</dl> | 
		
	
		
			
				|  |  |  |  | 		</div> | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | export function DockerTable() { | 
		
	
		
			
				|  |  |  |  | 	const { data: list, isLoading: listLoading } = api.docker.list.useQuery(undefined, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false }); | 
		
	
		
			
				|  |  |  |  | 	const { data: list, isLoading: listLoading, error } = api.docker.list.useQuery(undefined, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false }); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	return ( | 
		
	
		
			
				|  |  |  |  | 		<div className="overflow-x-auto rounded-md border border-base-content/15 bg-base-100"> | 
		
	
		
			
				|  |  |  |  | 			{!listLoading ? ( | 
		
	
		
			
				|  |  |  |  | 				<table className="table-s table"> | 
		
	
		
			
				|  |  |  |  | 					<thead> | 
		
	
		
			
				|  |  |  |  | 						<tr> | 
		
	
		
			
				|  |  |  |  | 							<th>Name</th> | 
		
	
		
			
				|  |  |  |  | 							<th>Image</th> | 
		
	
		
			
				|  |  |  |  | 							<th>Tag</th> | 
		
	
		
			
				|  |  |  |  | 							<th>Short Hash</th> | 
		
	
		
			
				|  |  |  |  | 							<th>Tag</th> | 
		
	
		
			
				|  |  |  |  | 							<th>Short Hash</th> | 
		
	
		
			
				|  |  |  |  | 						</tr> | 
		
	
		
			
				|  |  |  |  | 					</thead> | 
		
	
		
			
				|  |  |  |  | 					<tbody> | 
		
	
		
			
				|  |  |  |  | 						{list | 
		
	
		
			
				|  |  |  |  | 							? list | 
		
	
		
			
				|  |  |  |  | 		<> | 
		
	
		
			
				|  |  |  |  | 			{listLoading ? ( | 
		
	
		
			
				|  |  |  |  | 				<>Loading docker container list...</> | 
		
	
		
			
				|  |  |  |  | 			) : ( | 
		
	
		
			
				|  |  |  |  | 				<> | 
		
	
		
			
				|  |  |  |  | 					<div className={"flex flex-row flex-wrap justify-around gap-8"}> | 
		
	
		
			
				|  |  |  |  | 						{list ? ( | 
		
	
		
			
				|  |  |  |  | 							list | 
		
	
		
			
				|  |  |  |  | 								.sort((ca, cb) => { | 
		
	
		
			
				|  |  |  |  | 									if (ca.container.name && cb.container.name) { | 
		
	
		
			
				|  |  |  |  | 										if (ca.container.name < cb.container.name) { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -81,13 +94,13 @@ export function DockerTable() { | 
		
	
		
			
				|  |  |  |  | 									} | 
		
	
		
			
				|  |  |  |  | 									return 0; | 
		
	
		
			
				|  |  |  |  | 								}) | 
		
	
		
			
				|  |  |  |  | 									.map((containerInfo) => <DockerRow key={containerInfo.container.name} containerInfo={containerInfo} />) | 
		
	
		
			
				|  |  |  |  | 							: null} | 
		
	
		
			
				|  |  |  |  | 					</tbody> | 
		
	
		
			
				|  |  |  |  | 				</table> | 
		
	
		
			
				|  |  |  |  | 								.map((containerInfo) => <DockerCard key={containerInfo.container.name} containerInfo={containerInfo} />) | 
		
	
		
			
				|  |  |  |  | 						) : ( | 
		
	
		
			
				|  |  |  |  | 				<>Loading data...</> | 
		
	
		
			
				|  |  |  |  | 							<>Error loading docker container list: {error?.message}</> | 
		
	
		
			
				|  |  |  |  | 						)} | 
		
	
		
			
				|  |  |  |  | 					</div> | 
		
	
		
			
				|  |  |  |  | 				</> | 
		
	
		
			
				|  |  |  |  | 			)} | 
		
	
		
			
				|  |  |  |  | 		</> | 
		
	
		
			
				|  |  |  |  | 	); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					| 
							
							
							
						 |  |  |   |