feat: add configurable headers and instance branding (#6690)
This commit is contained in:
1 parent
97d8390b20
commit
9303dbd284
102 files changed
+12153
-609
No files matched your search
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE `user` ADD `header_preferences` text DEFAULT ('{"version":3,"visible":true,"searchDisplay":"input","logoDisplay":"logo","zones":{"left":[{"type":"builtin","id":"logo"}],"center":[{"type":"builtin","id":"search"}],"right":[{"type":"builtin","id":"boardEdit"},{"type":"builtin","id":"boardSettings"},{"type":"builtin","id":"user"}]}}') NOT NULL;
|
||||
--> statement-breakpoint
|
||||
INSERT IGNORE INTO `serverSetting` (`setting_key`, `value`)
|
||||
VALUES ('branding', '{"json":{"appName":"Homarr","greeting":"","logoImageUrl":null,"faviconImageUrl":null,"primaryColor":"#fa5252","secondaryColor":"#fd7e14","lockPrimaryColor":false,"signInBackgroundImageUrl":null,"signInBackgroundOverlay":0.55,"authBranding":{"showAppName":true,"showLogo":true,"showGreeting":true},"defaultRadius":"md"}}');
|
||||
File diff suppressed because it is too large.
Load diff
@@ -337,6 +337,13 @@
|
||||
"when": 1786217088950,
|
||||
"tag": "0047_add_assistant_tables",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 48,
|
||||
"version": "5",
|
||||
"when": 1787556966768,
|
||||
"tag": "0048_add_header_preferences_and_branding",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE "user" ADD COLUMN "header_preferences" text DEFAULT '{"version":3,"visible":true,"searchDisplay":"input","logoDisplay":"logo","zones":{"left":[{"type":"builtin","id":"logo"}],"center":[{"type":"builtin","id":"search"}],"right":[{"type":"builtin","id":"boardEdit"},{"type":"builtin","id":"boardSettings"},{"type":"builtin","id":"user"}]}}' NOT NULL;
|
||||
--> statement-breakpoint
|
||||
INSERT INTO "serverSetting" ("setting_key", "value")
|
||||
VALUES ('branding', '{"json":{"appName":"Homarr","greeting":"","logoImageUrl":null,"faviconImageUrl":null,"primaryColor":"#fa5252","secondaryColor":"#fd7e14","lockPrimaryColor":false,"signInBackgroundImageUrl":null,"signInBackgroundOverlay":0.55,"authBranding":{"showAppName":true,"showLogo":true,"showGreeting":true},"defaultRadius":"md"}}')
|
||||
ON CONFLICT ("setting_key") DO NOTHING;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -99,6 +99,13 @@
|
||||
"when": 1786217088954,
|
||||
"tag": "0013_add_assistant_tables",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1787556966592,
|
||||
"tag": "0014_add_header_preferences_and_branding",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `user` ADD `header_preferences` text DEFAULT '{"version":3,"visible":true,"searchDisplay":"input","logoDisplay":"logo","zones":{"left":[{"type":"builtin","id":"logo"}],"center":[{"type":"builtin","id":"search"}],"right":[{"type":"builtin","id":"boardEdit"},{"type":"builtin","id":"boardSettings"},{"type":"builtin","id":"user"}]}}' NOT NULL;
|
||||
--> statement-breakpoint
|
||||
INSERT INTO `serverSetting` (`setting_key`, `value`)
|
||||
VALUES ('branding', '{"json":{"appName":"Homarr","greeting":"","logoImageUrl":null,"faviconImageUrl":null,"primaryColor":"#fa5252","secondaryColor":"#fd7e14","lockPrimaryColor":false,"signInBackgroundImageUrl":null,"signInBackgroundOverlay":0.55,"authBranding":{"showAppName":true,"showLogo":true,"showGreeting":true},"defaultRadius":"md"}}')
|
||||
ON CONFLICT (`setting_key`) DO NOTHING;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -323,6 +323,13 @@
|
||||
"when": 1786217088950,
|
||||
"tag": "0045_add_assistant_tables",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 46,
|
||||
"version": "6",
|
||||
"when": 1787556956665,
|
||||
"tag": "0046_add_header_preferences_and_branding",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import SuperJSON from "superjson";
|
||||
|
||||
import type { ServerSettings } from "@homarr/server-settings";
|
||||
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
||||
import { defaultServerSettings, defaultServerSettingsKeys, parseBrandingSettings } from "@homarr/server-settings";
|
||||
|
||||
import type { Database } from "..";
|
||||
import { eq } from "..";
|
||||
@@ -18,10 +18,15 @@ export const getServerSettingsAsync = async (db: Database) => {
|
||||
return acc;
|
||||
}
|
||||
|
||||
const parsedSetting = SuperJSON.parse<Record<string, unknown>>(setting.value);
|
||||
if (settingKey === "branding") {
|
||||
acc[settingKey] = parseBrandingSettings(parsedSetting) as never;
|
||||
return acc;
|
||||
}
|
||||
acc[settingKey] = {
|
||||
...defaultServerSettings[settingKey],
|
||||
...SuperJSON.parse(setting.value),
|
||||
};
|
||||
...parsedSetting,
|
||||
} as never;
|
||||
return acc;
|
||||
}, {} as ServerSettings);
|
||||
};
|
||||
@@ -35,7 +40,14 @@ export const getServerSettingByKeyAsync = async <TKey extends keyof ServerSettin
|
||||
return defaultServerSettings[key];
|
||||
}
|
||||
|
||||
return SuperJSON.parse<ServerSettings[TKey]>(dbSettings.value);
|
||||
const parsedSetting = SuperJSON.parse<ServerSettings[TKey]>(dbSettings.value);
|
||||
if (key === "branding") {
|
||||
return parseBrandingSettings(parsedSetting) as ServerSettings[TKey];
|
||||
}
|
||||
return {
|
||||
...defaultServerSettings[key],
|
||||
...parsedSetting,
|
||||
} as ServerSettings[TKey];
|
||||
};
|
||||
|
||||
export const updateServerSettingByKeyAsync = async <TKey extends keyof ServerSettings>(
|
||||
|
||||
@@ -43,6 +43,7 @@ import type {
|
||||
WidgetKind,
|
||||
} from "@homarr/definitions";
|
||||
import type { CustomWidgetSecretKind } from "@homarr/custom-widgets/core";
|
||||
import { defaultHeaderPreferencesSerialized } from "@homarr/validation/header-preferences";
|
||||
|
||||
const customBlob = customType<{ data: Buffer }>({
|
||||
dataType() {
|
||||
@@ -85,6 +86,7 @@ export const users = mysqlTable("user", {
|
||||
firstDayOfWeek: tinyint().$type<DayOfWeek>().default(1).notNull(), // Defaults to Monday
|
||||
pingIconsEnabled: boolean().default(false).notNull(),
|
||||
enableRightClickOnWidgets: boolean().default(true).notNull(),
|
||||
headerPreferences: text().default(defaultHeaderPreferencesSerialized).notNull(),
|
||||
completedManageTour: boolean().default(false).notNull(),
|
||||
completedBoardTour: boolean().default(false).notNull(),
|
||||
});
|
||||
|
||||
@@ -41,6 +41,7 @@ import type {
|
||||
WidgetKind,
|
||||
} from "@homarr/definitions";
|
||||
import type { CustomWidgetSecretKind } from "@homarr/custom-widgets/core";
|
||||
import { defaultHeaderPreferencesSerialized } from "@homarr/validation/header-preferences";
|
||||
|
||||
const customBlob = customType<{ data: Buffer }>({
|
||||
dataType() {
|
||||
@@ -83,6 +84,7 @@ export const users = pgTable("user", {
|
||||
firstDayOfWeek: smallint().$type<DayOfWeek>().default(1).notNull(), // Defaults to Monday
|
||||
pingIconsEnabled: boolean().default(false).notNull(),
|
||||
enableRightClickOnWidgets: boolean().default(true).notNull(),
|
||||
headerPreferences: text().default(defaultHeaderPreferencesSerialized).notNull(),
|
||||
completedManageTour: boolean().default(false).notNull(),
|
||||
completedBoardTour: boolean().default(false).notNull(),
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ import type {
|
||||
WidgetKind,
|
||||
} from "@homarr/definitions";
|
||||
import type { CustomWidgetSecretKind } from "@homarr/custom-widgets/core";
|
||||
import { defaultHeaderPreferencesSerialized } from "@homarr/validation/header-preferences";
|
||||
|
||||
export * from "@homarr/core/infrastructure/certificates/hostnames/db/sqlite";
|
||||
|
||||
@@ -65,6 +66,7 @@ export const users = sqliteTable("user", {
|
||||
firstDayOfWeek: int().$type<DayOfWeek>().default(1).notNull(), // Defaults to Monday
|
||||
pingIconsEnabled: int({ mode: "boolean" }).default(false).notNull(),
|
||||
enableRightClickOnWidgets: int({ mode: "boolean" }).default(true).notNull(),
|
||||
headerPreferences: text().default(defaultHeaderPreferencesSerialized).notNull(),
|
||||
completedManageTour: int({ mode: "boolean" }).default(false).notNull(),
|
||||
completedBoardTour: int({ mode: "boolean" }).default(false).notNull(),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user