mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
refactor: remove primaryColor from whitelabeling settings and related components for cleaner configuration
This commit is contained in:
@@ -53,7 +53,6 @@ const baseSettings: WebServerSettings = {
|
||||
appDescription: null,
|
||||
logoUrl: null,
|
||||
faviconUrl: null,
|
||||
primaryColor: null,
|
||||
customCss: null,
|
||||
loginLogoUrl: null,
|
||||
supportUrl: null,
|
||||
|
||||
@@ -12,14 +12,12 @@ interface WhitelabelingPreviewProps {
|
||||
config: {
|
||||
appName?: string;
|
||||
logoUrl?: string;
|
||||
primaryColor?: string;
|
||||
footerText?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function WhitelabelingPreview({ config }: WhitelabelingPreviewProps) {
|
||||
const appName = config.appName || "Dokploy";
|
||||
const primaryColor = config.primaryColor || "hsl(var(--primary))";
|
||||
|
||||
return (
|
||||
<Card className="bg-transparent">
|
||||
@@ -40,10 +38,7 @@ export function WhitelabelingPreview({ config }: WhitelabelingPreviewProps) {
|
||||
className="size-8 rounded-sm object-contain"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className="size-8 rounded-sm flex items-center justify-center text-white font-bold text-sm"
|
||||
style={{ backgroundColor: primaryColor }}
|
||||
>
|
||||
<div className="size-8 rounded-sm flex items-center justify-center bg-primary text-primary-foreground font-bold text-sm">
|
||||
{appName.charAt(0).toUpperCase()}
|
||||
</div>
|
||||
)}
|
||||
@@ -53,17 +48,11 @@ export function WhitelabelingPreview({ config }: WhitelabelingPreviewProps) {
|
||||
{/* Simulated content area */}
|
||||
<div className="p-4 bg-background">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<div
|
||||
className="h-2 w-16 rounded-full"
|
||||
style={{ backgroundColor: primaryColor }}
|
||||
/>
|
||||
<div className="h-2 w-16 rounded-full bg-primary" />
|
||||
<div className="h-2 w-24 rounded-full bg-muted" />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<div
|
||||
className="px-3 py-1.5 rounded-md text-xs text-white font-medium"
|
||||
style={{ backgroundColor: primaryColor }}
|
||||
>
|
||||
<div className="px-3 py-1.5 rounded-md text-xs bg-primary text-primary-foreground font-medium">
|
||||
Button
|
||||
</div>
|
||||
<div className="px-3 py-1.5 rounded-md text-xs border font-medium">
|
||||
|
||||
@@ -18,76 +18,14 @@ export function WhitelabelingProvider() {
|
||||
{config.faviconUrl && <link rel="icon" href={config.faviconUrl} />}
|
||||
</Head>
|
||||
|
||||
{(config.customCss || config.primaryColor) && (
|
||||
{config.customCss && (
|
||||
<style
|
||||
id="whitelabeling-styles"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: [
|
||||
config.primaryColor
|
||||
? `:root { --primary: ${hexToHSL(config.primaryColor)}; }`
|
||||
: "",
|
||||
config.customCss || "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n"),
|
||||
__html: config.customCss,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a hex color string to HSL values (without the hsl() wrapper)
|
||||
* matching the format used by shadcn/ui CSS variables (e.g., "262 83% 58%")
|
||||
*/
|
||||
function hexToHSL(hex: string): string {
|
||||
// Remove # prefix if present
|
||||
const cleanHex = hex.replace(/^#/, "");
|
||||
|
||||
if (
|
||||
!/^[0-9a-fA-F]{6}$/.test(cleanHex) &&
|
||||
!/^[0-9a-fA-F]{3}$/.test(cleanHex)
|
||||
) {
|
||||
return hex; // Return as-is if not a valid hex color (might be HSL already)
|
||||
}
|
||||
|
||||
let r: number;
|
||||
let g: number;
|
||||
let b: number;
|
||||
|
||||
if (cleanHex.length === 3) {
|
||||
r = Number.parseInt(cleanHex[0]! + cleanHex[0], 16);
|
||||
g = Number.parseInt(cleanHex[1]! + cleanHex[1], 16);
|
||||
b = Number.parseInt(cleanHex[2]! + cleanHex[2], 16);
|
||||
} else {
|
||||
r = Number.parseInt(cleanHex.slice(0, 2), 16);
|
||||
g = Number.parseInt(cleanHex.slice(2, 4), 16);
|
||||
b = Number.parseInt(cleanHex.slice(4, 6), 16);
|
||||
}
|
||||
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
const max = Math.max(r, g, b);
|
||||
const min = Math.min(r, g, b);
|
||||
const l = (max + min) / 2;
|
||||
let h = 0;
|
||||
let s = 0;
|
||||
|
||||
if (max !== min) {
|
||||
const d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
if (max === r) {
|
||||
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
||||
} else if (max === g) {
|
||||
h = ((b - r) / d + 2) / 6;
|
||||
} else {
|
||||
h = ((r - g) / d + 4) / 6;
|
||||
}
|
||||
}
|
||||
|
||||
return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,6 @@ export function WhitelabelingSettings() {
|
||||
appDescription: values.appDescription || null,
|
||||
logoUrl: values.logoUrl || null,
|
||||
faviconUrl: values.faviconUrl || null,
|
||||
primaryColor: null,
|
||||
customCss: values.customCss || null,
|
||||
loginLogoUrl: values.loginLogoUrl || null,
|
||||
supportUrl: values.supportUrl || null,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE "webServerSettings" ADD COLUMN "whitelabelingConfig" jsonb DEFAULT '{"appName":null,"appDescription":null,"logoUrl":null,"faviconUrl":null,"primaryColor":null,"customCss":null,"loginLogoUrl":null,"supportUrl":null,"docsUrl":null,"errorPageTitle":null,"errorPageDescription":null,"metaTitle":null,"footerText":null}'::jsonb;
|
||||
1
apps/dokploy/drizzle/0148_futuristic_bullseye.sql
Normal file
1
apps/dokploy/drizzle/0148_futuristic_bullseye.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "webServerSettings" ADD COLUMN "whitelabelingConfig" jsonb DEFAULT '{"appName":null,"appDescription":null,"logoUrl":null,"faviconUrl":null,"customCss":null,"loginLogoUrl":null,"supportUrl":null,"docsUrl":null,"errorPageTitle":null,"errorPageDescription":null,"metaTitle":null,"footerText":null}'::jsonb;
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "cec2dc6b-f0db-4064-bc17-7f79ed1b8638",
|
||||
"id": "a293a443-ceaf-418e-8e34-ff46e183995f",
|
||||
"prevId": "2e0aba0b-93fc-4bfe-a975-1c5d45354753",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
@@ -7179,7 +7179,7 @@
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'{\"appName\":null,\"appDescription\":null,\"logoUrl\":null,\"faviconUrl\":null,\"primaryColor\":null,\"customCss\":null,\"loginLogoUrl\":null,\"supportUrl\":null,\"docsUrl\":null,\"errorPageTitle\":null,\"errorPageDescription\":null,\"metaTitle\":null,\"footerText\":null}'::jsonb"
|
||||
"default": "'{\"appName\":null,\"appDescription\":null,\"logoUrl\":null,\"faviconUrl\":null,\"customCss\":null,\"loginLogoUrl\":null,\"supportUrl\":null,\"docsUrl\":null,\"errorPageTitle\":null,\"errorPageDescription\":null,\"metaTitle\":null,\"footerText\":null}'::jsonb"
|
||||
},
|
||||
"cleanupCacheApplications": {
|
||||
"name": "cleanupCacheApplications",
|
||||
|
||||
@@ -1041,8 +1041,8 @@
|
||||
{
|
||||
"idx": 148,
|
||||
"version": "7",
|
||||
"when": 1773124119746,
|
||||
"tag": "0148_cold_kitty_pryde",
|
||||
"when": 1773129798212,
|
||||
"tag": "0148_futuristic_bullseye",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -66,7 +66,6 @@ export const whitelabelingRouter = createTRPCRouter({
|
||||
appDescription: null,
|
||||
logoUrl: null,
|
||||
faviconUrl: null,
|
||||
primaryColor: null,
|
||||
customCss: null,
|
||||
loginLogoUrl: null,
|
||||
supportUrl: null,
|
||||
@@ -97,7 +96,6 @@ export const whitelabelingRouter = createTRPCRouter({
|
||||
logoUrl: config.logoUrl,
|
||||
loginLogoUrl: config.loginLogoUrl,
|
||||
faviconUrl: config.faviconUrl,
|
||||
primaryColor: config.primaryColor,
|
||||
customCss: config.customCss,
|
||||
metaTitle: config.metaTitle,
|
||||
errorPageTitle: config.errorPageTitle,
|
||||
|
||||
@@ -73,7 +73,6 @@ export const webServerSettings = pgTable("webServerSettings", {
|
||||
appDescription: string | null;
|
||||
logoUrl: string | null;
|
||||
faviconUrl: string | null;
|
||||
primaryColor: string | null;
|
||||
customCss: string | null;
|
||||
loginLogoUrl: string | null;
|
||||
supportUrl: string | null;
|
||||
@@ -88,7 +87,6 @@ export const webServerSettings = pgTable("webServerSettings", {
|
||||
appDescription: null,
|
||||
logoUrl: null,
|
||||
faviconUrl: null,
|
||||
primaryColor: null,
|
||||
customCss: null,
|
||||
loginLogoUrl: null,
|
||||
supportUrl: null,
|
||||
@@ -199,7 +197,6 @@ export const whitelabelingConfigSchema = z.object({
|
||||
appDescription: z.string().nullable(),
|
||||
logoUrl: safeUrl,
|
||||
faviconUrl: safeUrl,
|
||||
primaryColor: z.string().nullable(),
|
||||
customCss: z.string().nullable(),
|
||||
loginLogoUrl: safeUrl,
|
||||
supportUrl: safeUrl,
|
||||
|
||||
Reference in New Issue
Block a user