Skip to content

Commit 5590702

Browse files
autofix-ci[bot]mcfdez
authored andcommitted
[autofix.ci] apply automated fixes
1 parent e4cdc8f commit 5590702

4 files changed

Lines changed: 295 additions & 87 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
interface ComposeVolumesProps {
2+
composeVolumes: Record<
3+
string,
4+
{
5+
config: any;
6+
usage: Array<{ service: string; mountPath: string }>;
7+
hostPath?: string;
8+
isBindMount?: boolean;
9+
}
10+
>;
11+
}
12+
13+
/**
14+
* Generates a display string for the mount path of a volume.
15+
*/
16+
const getMountPathDisplay = (
17+
volumeName: string,
18+
volumeData: any,
19+
): string => {
20+
const hasUsage = volumeData?.usage && volumeData.usage.length > 0;
21+
22+
if (!hasUsage) {
23+
return volumeData?.isBindMount ? volumeData.hostPath : volumeName;
24+
}
25+
26+
return volumeData.usage
27+
.map((usage: { service: string; mountPath: string }) => {
28+
const source = volumeData?.isBindMount
29+
? volumeData.hostPath
30+
: volumeName;
31+
return `${source}:${usage.mountPath}`;
32+
})
33+
.join(", ");
34+
};
35+
36+
/**
37+
* Retrieves the driver value from the volume configuration.
38+
*/
39+
const getDriverValue = (volumeData: any): string => {
40+
const hasValidConfig =
41+
typeof volumeData?.config === "object" && volumeData?.config !== null;
42+
return hasValidConfig ? volumeData.config.driver || "default" : "default";
43+
};
44+
45+
/**
46+
* Retrieves the external value from the volume configuration.
47+
*/
48+
const getExternalValue = (volumeData: any): string => {
49+
const hasValidConfig =
50+
typeof volumeData?.config === "object" && volumeData?.config !== null;
51+
return hasValidConfig && volumeData.config.external ? "Yes" : "No";
52+
};
53+
54+
/**
55+
* Component to display individual volume fields.
56+
*/
57+
const VolumeField = ({
58+
label,
59+
value,
60+
breakText = false,
61+
}: { label: string; value: string; breakText?: boolean }) => (
62+
<div className="flex flex-col gap-1 min-w-0">
63+
<span className="font-medium">{label}</span>
64+
<span
65+
className={`text-sm text-muted-foreground ${breakText ? "break-all" : ""}`}
66+
>
67+
{value}
68+
</span>
69+
</div>
70+
);
71+
72+
/**
73+
* Component to display compose volumes information.
74+
*/
75+
export const ComposeVolumes = ({ composeVolumes }: ComposeVolumesProps) => {
76+
if (!composeVolumes || Object.keys(composeVolumes).length === 0) {
77+
return null;
78+
}
79+
80+
return (
81+
<div className="space-y-4">
82+
<div>
83+
<h3 className="text-lg font-semibold">Compose Volumes</h3>
84+
<p className="text-sm text-muted-foreground">
85+
Volumes defined in the docker-compose.yml file of the service
86+
</p>
87+
</div>
88+
<div className="flex flex-col gap-6">
89+
{Object.entries(composeVolumes).map(
90+
([volumeName, volumeData]: [string, any]) => {
91+
const isBindMount = volumeData?.isBindMount;
92+
const mountPath = getMountPathDisplay(volumeName, volumeData);
93+
const type = isBindMount ? "Bind Mount" : "Volume";
94+
95+
return (
96+
<div key={volumeName} className="border rounded-lg p-4">
97+
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-[2fr_1fr_1fr_1fr] gap-4 sm:gap-8">
98+
<VolumeField
99+
label="Mount Path"
100+
value={mountPath}
101+
breakText={true}
102+
/>
103+
<VolumeField label="Type" value={type} />
104+
105+
{isBindMount ? (
106+
<>
107+
<VolumeField label="-" value="-" />
108+
<VolumeField label="-" value="-" />
109+
</>
110+
) : (
111+
<>
112+
<VolumeField
113+
label="Driver"
114+
value={getDriverValue(volumeData)}
115+
/>
116+
<VolumeField
117+
label="External"
118+
value={getExternalValue(volumeData)}
119+
/>
120+
</>
121+
)}
122+
</div>
123+
</div>
124+
);
125+
},
126+
)}
127+
</div>
128+
</div>
129+
);
130+
};

apps/dokploy/components/dashboard/application/advanced/volumes/show-volumes.tsx

Lines changed: 25 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { api } from "@/utils/api";
1414
import type { ServiceType } from "../show-resources";
1515
import { AddVolumes } from "./add-volumes";
16+
import { ComposeVolumes } from "./compose-volumes";
1617
import { UpdateVolume } from "./update-volume";
1718

1819
interface Props {
@@ -41,7 +42,7 @@ export const ShowVolumes = ({ id, type }: Props) => {
4142
// Get volumes in docker-compose.yml for compose services
4243
const { data: composeVolumes } = api.compose.loadDefinedVolumes.useQuery(
4344
{ composeId: id },
44-
{ enabled: type === "compose" && !!id }
45+
{ enabled: type === "compose" && !!id },
4546
);
4647

4748
const { mutateAsync: deleteVolume, isLoading: isRemoving } =
@@ -57,50 +58,49 @@ export const ShowVolumes = ({ id, type }: Props) => {
5758
</CardDescription>
5859
</div>
5960

60-
{data && data?.mounts?.length > 0 && (
61-
<AddVolumes serviceId={id} refetch={refetch} serviceType={type}>
62-
Add Volume
63-
</AddVolumes>
64-
)}
61+
<AddVolumes serviceId={id} refetch={refetch} serviceType={type}>
62+
Add Volume
63+
</AddVolumes>
6564
</CardHeader>
6665
<CardContent className="flex flex-col gap-4">
67-
{data?.mounts?.length === 0 &&
68-
(type !== "compose" || !composeVolumes || Object.keys(composeVolumes).length === 0) ? (
66+
{!data?.mounts?.length &&
67+
!Object.keys(composeVolumes || {}).length && (
6968
<div className="flex w-full flex-col items-center justify-center gap-3 pt-10">
7069
<Package className="size-8 text-muted-foreground" />
7170
<span className="text-base text-muted-foreground">
7271
No volumes/mounts configured
7372
</span>
74-
<AddVolumes serviceId={id} refetch={refetch} serviceType={type}>
75-
Add Volume
76-
</AddVolumes>
7773
</div>
78-
) : (
74+
)}
75+
{((data?.mounts?.length ?? 0) > 0 ||
76+
Object.keys(composeVolumes || {}).length > 0) && (
7977
<div className="flex flex-col pt-2 gap-4">
80-
{data?.mounts?.length > 0 && (
78+
{(data?.mounts?.length ?? 0) > 0 && (
8179
<AlertBlock type="warning">
8280
Please remember to click Redeploy after adding, editing, or
8381
deleting a mount to apply the changes.
8482
</AlertBlock>
8583
)}
86-
{data?.mounts?.length > 0 && type === "compose" && composeVolumes && Object.keys(composeVolumes).length > 0 && (
87-
<div className="border-t pt-4">
88-
<div>
89-
<h3 className="text-lg font-semibold">File Mounts</h3>
90-
<p className="text-sm text-muted-foreground">
91-
File mounts configured through Dokploy interface
92-
</p>
84+
{(data?.mounts?.length ?? 0) > 0 &&
85+
type === "compose" &&
86+
composeVolumes &&
87+
Object.keys(composeVolumes).length > 0 && (
88+
<div className="border-t pt-4">
89+
<div>
90+
<h3 className="text-lg font-semibold">File Mounts</h3>
91+
<p className="text-sm text-muted-foreground">
92+
File mounts configured through Dokploy interface
93+
</p>
94+
</div>
9395
</div>
94-
</div>
95-
)}
96+
)}
9697
<div className="flex flex-col gap-6">
9798
{data?.mounts?.map((mount) => (
9899
<div key={mount.mountId}>
99100
<div
100101
key={mount.mountId}
101102
className="flex w-full flex-col sm:flex-row sm:items-center justify-between gap-4 sm:gap-10 border rounded-lg p-4"
102103
>
103-
{/* <Package className="size-8 self-center text-muted-foreground" /> */}
104104
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 flex-col gap-4 sm:gap-8">
105105
<div className="flex flex-col gap-1">
106106
<span className="font-medium">Mount Type</span>
@@ -190,47 +190,8 @@ export const ShowVolumes = ({ id, type }: Props) => {
190190
</div>
191191
)}
192192
{/* Show defined volumes from docker-compose.yml for compose services */}
193-
{type === "compose" && composeVolumes && Object.keys(composeVolumes).length > 0 && (
194-
<div className="space-y-4">
195-
<div>
196-
<h3 className="text-lg font-semibold">Defined Volumes</h3>
197-
<p className="text-sm text-muted-foreground">
198-
Volumes defined in your docker-compose.yml file
199-
</p>
200-
</div>
201-
<div className="grid gap-3">
202-
{Object.entries(composeVolumes).map(([volumeName, volumeConfig]) => (
203-
<div key={volumeName} className="border rounded-lg p-4">
204-
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
205-
<div className="flex flex-col gap-1">
206-
<span className="font-medium">Volume Name</span>
207-
<span className="text-sm text-muted-foreground">
208-
{volumeName}
209-
</span>
210-
</div>
211-
<div className="flex flex-col gap-1">
212-
<span className="font-medium">Driver</span>
213-
<span className="text-sm text-muted-foreground">
214-
{typeof volumeConfig === 'object' && volumeConfig !== null
215-
? (volumeConfig as any)?.driver || 'default'
216-
: 'default'
217-
}
218-
</span>
219-
</div>
220-
<div className="flex flex-col gap-1">
221-
<span className="font-medium">External</span>
222-
<span className="text-sm text-muted-foreground">
223-
{typeof volumeConfig === 'object' && volumeConfig !== null
224-
? (volumeConfig as any)?.external ? 'Yes' : 'No'
225-
: 'No'
226-
}
227-
</span>
228-
</div>
229-
</div>
230-
</div>
231-
))}
232-
</div>
233-
</div>
193+
{type === "compose" && composeVolumes && (
194+
<ComposeVolumes composeVolumes={composeVolumes} />
234195
)}
235196
</CardContent>
236197
</Card>

apps/dokploy/server/api/routers/compose.ts

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
getComposeContainer,
2121
getWebServerSettings,
2222
IS_CLOUD,
23+
loadDefinedVolumes,
2324
loadDockerCompose,
2425
loadDockerComposeRemote,
2526
loadServices,
@@ -348,7 +349,7 @@ export const composeRouter = createTRPCRouter({
348349
.input(apiFindCompose)
349350
.query(async ({ input, ctx }) => {
350351
const compose = await findComposeById(input.composeId);
351-
352+
352353
if (
353354
compose.environment.project.organizationId !==
354355
ctx.session.activeOrganizationId
@@ -359,28 +360,7 @@ export const composeRouter = createTRPCRouter({
359360
});
360361
}
361362

362-
try {
363-
// Clone and load the docker-compose file
364-
const command = await cloneCompose(compose);
365-
if (compose.serverId) {
366-
await execAsyncRemote(compose.serverId, command);
367-
} else {
368-
await execAsync(command);
369-
}
370-
371-
// Load and parse the docker-compose.yml file
372-
let composeData;
373-
if (compose.serverId) {
374-
composeData = await loadDockerComposeRemote(compose);
375-
} else {
376-
composeData = await loadDockerCompose(compose);
377-
}
378-
379-
return composeData?.volumes || {};
380-
} catch (err) {
381-
console.error("Error loading defined volumes:", err);
382-
return {};
383-
}
363+
return await loadDefinedVolumes(input.composeId);
384364
}),
385365

386366
randomizeCompose: protectedProcedure

0 commit comments

Comments
 (0)