refactor-UI-code

This commit is contained in:
hhftechnologies
2025-11-21 19:26:38 +05:30
parent a97a91b9bf
commit 7364582ba9
4 changed files with 1 additions and 274 deletions

View File

@@ -12,7 +12,6 @@
"dependencies": {
"@codemirror/lang-yaml": "^6.1.2",
"@hookform/resolvers": "^5.1.1",
"@iarna/toml": "^2.2.5",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.14",

View File

@@ -733,7 +733,7 @@ function App() {
}
}
// Fetch template details (compose, template.toml, logo)
// Fetch template details (compose, logo)
async function fetchTemplateDetails(templateId: string): Promise<any> {
const GITHUB_OWNER = "hhftechnology";
const GITHUB_REPO = "Marketplace";
@@ -758,23 +758,6 @@ function App() {
}
const composeContent = await composeResponse.text();
// Fetch template.toml
let templateTomlContent = null;
let parsedTemplate = null;
try {
const tomlUrl = `${GITHUB_RAW_BASE}/${GITHUB_OWNER}/${GITHUB_REPO}/${GITHUB_BRANCH}/${basePath}/template.toml`;
const tomlResponse = await fetch(tomlUrl);
if (tomlResponse.ok) {
templateTomlContent = await tomlResponse.text();
const { parseTemplateToml } = await import(
"../../utils/template-parser"
);
parsedTemplate = parseTemplateToml(templateTomlContent);
}
} catch (e) {
console.warn(`Template ${templateId} has no template.toml file`);
}
// Build logo URL if logo exists
let logoUrl = null;
if (template.logo) {
@@ -784,8 +767,6 @@ function App() {
return {
...template,
composeContent,
templateTomlContent,
parsedTemplate,
logoUrl,
};
} catch (error: any) {
@@ -1224,86 +1205,6 @@ function App() {
);
}
// Apply template.toml configuration if available
if (template.parsedTemplate) {
const parsed = template.parsedTemplate;
// Apply environment variables from template.toml
if (parsed.env && parsed.env.length > 0) {
setServices((prev) => {
return prev.map((svc) => {
// Find matching service by name from domains config
const domainConfig = parsed.domains?.find(
(d: any) => d.serviceName === svc.name
);
if (domainConfig && domainConfig.env) {
// Merge domain-specific env vars
const domainEnv = domainConfig.env.map((e: string) => {
const [key, ...rest] = e.split("=");
return { key: key.trim(), value: rest.join("=").trim() };
});
// Merge with existing env vars, avoiding duplicates
const existingKeys = new Set(svc.environment.map((e) => e.key));
const newEnv = domainEnv.filter(
(e: { key: string; value: string }) =>
!existingKeys.has(e.key)
);
return {
...svc,
environment: [...svc.environment, ...newEnv],
};
}
// Apply general env vars if no domain-specific config
const existingKeys = new Set(svc.environment.map((e) => e.key));
const newEnv = parsed.env.filter(
(e: any) => !existingKeys.has(e.key)
);
return {
...svc,
environment: [...svc.environment, ...newEnv],
};
});
});
}
// Apply domains configuration (ports, etc.)
if (parsed.domains && parsed.domains.length > 0) {
setServices((prev) => {
return prev.map((svc) => {
const domainConfig = parsed.domains?.find(
(d: any) => d.serviceName === svc.name
);
if (domainConfig) {
// Add port if not already present
const hasPort = svc.ports.some(
(p) => p.container === String(domainConfig.port)
);
if (!hasPort && domainConfig.port) {
return {
...svc,
ports: [
...svc.ports,
{
host: "",
container: String(domainConfig.port),
protocol: "none",
},
],
};
}
}
return svc;
});
});
}
}
// Close dialogs
setTemplateDetailOpen(false);
setTemplateStoreOpen(false);

View File

@@ -1,80 +0,0 @@
// Template metadata types based on Dokploy/templates format
export interface TemplateVariable {
name: string;
value: string;
helper?: string; // Helper type like "domain", "password:32", "uuid", etc.
description?: string;
}
export interface TemplateDomain {
serviceName: string;
port: number;
host: string;
path?: string;
env?: string[]; // Environment variables for this domain
}
export interface TemplateMount {
filePath: string;
content: string;
description?: string;
}
export interface TemplateConfig {
domains: TemplateDomain[];
env: { key: string; value: string; description?: string }[];
mounts: TemplateMount[];
}
export interface TemplateMetadata {
id?: string;
name?: string;
version?: string;
description?: string;
logo?: string;
links?: {
github?: string;
website?: string;
docs?: string;
};
tags?: string[];
}
export interface TemplateFormat {
variables: TemplateVariable[];
config: TemplateConfig;
metadata?: TemplateMetadata;
}
export type TemplateHelper =
| "domain"
| "password"
| "password:32"
| "base64"
| "base64:32"
| "hash"
| "uuid"
| "randomPort"
| "email"
| "username"
| "timestamp"
| "jwt"
| "custom";
export const TEMPLATE_HELPERS: { value: TemplateHelper; label: string; description: string }[] = [
{ value: "domain", label: "Domain", description: "Generate a random domain" },
{ value: "password", label: "Password (default length)", description: "Generate a random password" },
{ value: "password:32", label: "Password (32 chars)", description: "Generate a 32-character password" },
{ value: "base64", label: "Base64", description: "Encode to base64" },
{ value: "base64:32", label: "Base64 (32 bytes)", description: "Encode 32 bytes to base64" },
{ value: "hash", label: "Hash", description: "Generate a hash" },
{ value: "uuid", label: "UUID", description: "Generate a UUID" },
{ value: "randomPort", label: "Random Port", description: "Generate a random port" },
{ value: "email", label: "Email", description: "Generate a random email" },
{ value: "username", label: "Username", description: "Generate a random username" },
{ value: "timestamp", label: "Timestamp", description: "Generate current timestamp" },
{ value: "jwt", label: "JWT", description: "Generate a JWT token" },
{ value: "custom", label: "Custom", description: "Custom value" },
];

View File

@@ -1,93 +0,0 @@
// Template TOML parser utility for Dokploy templates
import * as TOML from "@iarna/toml";
import type { TemplateFormat, TemplateVariable, TemplateDomain, TemplateMount } from "../types/template";
export interface ParsedTemplateToml {
variables?: Record<string, string>;
domains?: TemplateDomain[];
env?: { key: string; value: string }[];
mounts?: TemplateMount[];
}
/**
* Parse template.toml content into structured format
*/
export function parseTemplateToml(tomlContent: string): ParsedTemplateToml {
try {
const parsed = TOML.parse(tomlContent) as any;
const result: ParsedTemplateToml = {};
// Extract variables section
if (parsed.variables) {
result.variables = parsed.variables;
}
// Extract config.domains array
if (parsed.config?.domains && Array.isArray(parsed.config.domains)) {
result.domains = parsed.config.domains.map((domain: any) => ({
serviceName: domain.serviceName || "",
port: domain.port || 0,
host: domain.host || "",
path: domain.path,
env: domain.env || [],
}));
}
// Extract config.env (can be array or object)
if (parsed.config?.env) {
if (Array.isArray(parsed.config.env)) {
// Array format: ["KEY=value", "KEY2=value2"]
result.env = parsed.config.env.map((envStr: string) => {
const [key, ...valueParts] = envStr.split("=");
return {
key: key.trim(),
value: valueParts.join("=").trim(),
};
});
} else if (typeof parsed.config.env === "object") {
// Object format: { KEY: "value", KEY2: "value2" }
result.env = Object.entries(parsed.config.env).map(([key, value]) => ({
key,
value: String(value),
}));
}
}
// Extract config.mounts array
if (parsed.config?.mounts && Array.isArray(parsed.config.mounts)) {
result.mounts = parsed.config.mounts.map((mount: any) => ({
filePath: mount.filePath || "",
content: mount.content || "",
description: mount.description,
}));
}
return result;
} catch (error) {
console.error("Error parsing template.toml:", error);
throw new Error(`Failed to parse template.toml: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Convert parsed template to TemplateFormat interface
*/
export function toTemplateFormat(parsed: ParsedTemplateToml): TemplateFormat {
const variables: TemplateVariable[] = parsed.variables
? Object.entries(parsed.variables).map(([name, value]) => ({
name,
value: String(value),
}))
: [];
return {
variables,
config: {
domains: parsed.domains || [],
env: parsed.env || [],
mounts: parsed.mounts || [],
},
};
}