mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-01 01:32:16 +00:00
feat(icon): enhance icon management for services
- Updated ShowIconSettings component to handle both application and compose service types. - Added new icon column to the compose table in the database. - Implemented fetching and updating of icons for services in the environment and application pages. - Introduced fetchTemplateLogo function to retrieve logos for templates, improving icon handling for compose services.
This commit is contained in:
@@ -98,6 +98,7 @@ export const compose = pgTable("compose", {
|
||||
.default(false),
|
||||
triggerType: triggerType("triggerType").default("push"),
|
||||
composeStatus: applicationStatus("composeStatus").notNull().default("idle"),
|
||||
icon: text("icon"),
|
||||
environmentId: text("environmentId")
|
||||
.notNull()
|
||||
.references(() => environments.environmentId, { onDelete: "cascade" }),
|
||||
@@ -190,6 +191,11 @@ const createSchema = createInsertSchema(compose, {
|
||||
.optional(),
|
||||
triggerType: z.enum(["push", "tag"]).optional(),
|
||||
composeStatus: z.enum(["idle", "running", "done", "error"]).optional(),
|
||||
icon: z
|
||||
.string()
|
||||
.max(2 * 1024 * 1024, "Icon must be less than 2MB")
|
||||
.nullable()
|
||||
.optional(),
|
||||
serviceNetworks: z
|
||||
.array(
|
||||
z.object({
|
||||
|
||||
@@ -168,6 +168,7 @@ export const findEnvironmentById = async (environmentId: string) => {
|
||||
composeStatus: true,
|
||||
description: true,
|
||||
serverId: true,
|
||||
icon: true,
|
||||
},
|
||||
},
|
||||
libsql: {
|
||||
@@ -239,7 +240,12 @@ export const findEnvironmentsByProjectId = async (projectId: string) => {
|
||||
with: { server: { columns: { name: true } } },
|
||||
},
|
||||
compose: {
|
||||
columns: { ...serviceColumns, composeId: true, composeStatus: true },
|
||||
columns: {
|
||||
...serviceColumns,
|
||||
composeId: true,
|
||||
composeStatus: true,
|
||||
icon: true,
|
||||
},
|
||||
with: { server: { columns: { name: true } } },
|
||||
},
|
||||
libsql: {
|
||||
|
||||
@@ -74,6 +74,49 @@ export async function fetchTemplatesList(
|
||||
}));
|
||||
}
|
||||
|
||||
const LOGO_MIME_TYPES: Record<string, string> = {
|
||||
png: "image/png",
|
||||
jpg: "image/jpeg",
|
||||
jpeg: "image/jpeg",
|
||||
svg: "image/svg+xml",
|
||||
webp: "image/webp",
|
||||
gif: "image/gif",
|
||||
};
|
||||
|
||||
export async function fetchTemplateLogo(
|
||||
templateId: string,
|
||||
baseUrl = "https://templates.dokploy.com",
|
||||
): Promise<string | null> {
|
||||
try {
|
||||
const templates = await fetchTemplatesList(baseUrl);
|
||||
const template = templates.find((t) => t.id === templateId);
|
||||
if (!template?.logo) return null;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}/blueprints/${templateId}/${template.logo}`,
|
||||
{ signal: AbortSignal.timeout(10000) },
|
||||
);
|
||||
if (!response.ok) return null;
|
||||
|
||||
const buffer = Buffer.from(await response.arrayBuffer());
|
||||
if (buffer.length === 0) return null;
|
||||
|
||||
const contentType = response.headers.get("content-type")?.split(";")[0];
|
||||
const extension = template.logo.split(".").pop()?.toLowerCase() ?? "";
|
||||
const mimeType = contentType?.startsWith("image/")
|
||||
? contentType
|
||||
: LOGO_MIME_TYPES[extension];
|
||||
if (!mimeType) return null;
|
||||
|
||||
const dataUrl = `data:${mimeType};base64,${buffer.toString("base64")}`;
|
||||
if (dataUrl.length > 2 * 1024 * 1024) return null;
|
||||
|
||||
return dataUrl;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a specific template's files
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user