fix: hide video canvas entry when disabled
This commit is contained in:
parent
71c537fdb7
commit
2a793dcbba
@ -50,6 +50,7 @@ export default async function AdminLayout({
|
||||
tutorialEnabled={siteSettings.tutorialEnabled ?? false}
|
||||
rankingEnabled={siteSettings.rankingEnabled ?? true}
|
||||
productPlanningEnabled={(siteSettings as any).productPlanningEnabled ?? true}
|
||||
videoCanvasEnabled={(siteSettings as any).videoCanvasEnabled ?? true}
|
||||
/>
|
||||
<div className="flex-1 pl-16">{children}</div>
|
||||
</div>
|
||||
|
||||
@ -482,6 +482,7 @@ type SiteSettings = {
|
||||
canvasEnabled: boolean;
|
||||
agentEnabled: boolean;
|
||||
canvasAgentModeEnabled: boolean;
|
||||
videoCanvasEnabled: boolean;
|
||||
videoCanvasSidebarEnabled: boolean;
|
||||
agentCategoryTreeConfig: {
|
||||
productCategories: string[];
|
||||
@ -989,6 +990,7 @@ export function AdminSettingsClient() {
|
||||
canvasEnabled: true,
|
||||
agentEnabled: true,
|
||||
canvasAgentModeEnabled: true,
|
||||
videoCanvasEnabled: true,
|
||||
videoCanvasSidebarEnabled: true,
|
||||
agentCategoryTreeConfig: {
|
||||
productCategories: [],
|
||||
@ -1093,6 +1095,10 @@ export function AdminSettingsClient() {
|
||||
agentEnabled: (siteSettingsData as any).agentEnabled ?? true,
|
||||
canvasAgentModeEnabled:
|
||||
(siteSettingsData as any).canvasAgentModeEnabled ?? true,
|
||||
videoCanvasEnabled:
|
||||
(siteSettingsData as any).videoCanvasEnabled ??
|
||||
(siteSettingsData as any).videoCanvasSidebarEnabled ??
|
||||
true,
|
||||
videoCanvasSidebarEnabled:
|
||||
(siteSettingsData as any).videoCanvasSidebarEnabled ?? true,
|
||||
agentCategoryTreeConfig: {
|
||||
@ -9432,25 +9438,48 @@ export function AdminSettingsClient() {
|
||||
|
||||
<div className="flex items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="videoCanvasSidebarEnabled">
|
||||
视频画布模块侧边栏
|
||||
<Label htmlFor="videoCanvasEnabled">
|
||||
视频画布功能
|
||||
</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
开启后,视频画布左侧显示“视频模块”分层侧边栏;关闭后只保留画布本体与节点快捷添加。
|
||||
开启后,首页和顶部导航显示“视频画布”入口;关闭后隐藏入口按钮。
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
id="videoCanvasSidebarEnabled"
|
||||
checked={siteSettings.videoCanvasSidebarEnabled}
|
||||
id="videoCanvasEnabled"
|
||||
checked={siteSettings.videoCanvasEnabled}
|
||||
onCheckedChange={(checked) =>
|
||||
setSiteSettings({
|
||||
...siteSettings,
|
||||
videoCanvasSidebarEnabled: checked,
|
||||
videoCanvasEnabled: checked,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{siteSettings.videoCanvasEnabled && (
|
||||
<div className="flex items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="videoCanvasSidebarEnabled">
|
||||
视频画布模块侧边栏
|
||||
</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
开启后,视频画布左侧显示“视频模块”分层侧边栏;关闭后只保留画布本体与节点快捷添加。
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
id="videoCanvasSidebarEnabled"
|
||||
checked={siteSettings.videoCanvasSidebarEnabled}
|
||||
onCheckedChange={(checked) =>
|
||||
setSiteSettings({
|
||||
...siteSettings,
|
||||
videoCanvasSidebarEnabled: checked,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="aiDetailGenerationEnabled">
|
||||
|
||||
@ -80,6 +80,7 @@ async function SidebarWrapper({ children }: { children: React.ReactNode }) {
|
||||
rankingEnabled={siteSettings.rankingEnabled ?? true}
|
||||
productPlanningEnabled={(siteSettings as any).productPlanningEnabled ?? true}
|
||||
agentEnabled={(siteSettings as any).agentEnabled ?? true}
|
||||
videoCanvasEnabled={(siteSettings as any).videoCanvasEnabled ?? true}
|
||||
>
|
||||
{children}
|
||||
</ChatShell>
|
||||
|
||||
@ -109,6 +109,7 @@ const REALTIME_CANVAS_CONFIG_KEY = "realtime_canvas_config";
|
||||
const LAYER_SPLIT_CONFIG_KEY = "layer_split_config";
|
||||
const AGENT_CATEGORY_TREE_CONFIG_KEY = "agent_category_tree_config";
|
||||
const CANVAS_AGENT_MODE_ENABLED_KEY = "canvas_agent_mode_enabled";
|
||||
const VIDEO_CANVAS_ENABLED_KEY = "video_canvas_enabled";
|
||||
const VIDEO_CANVAS_SIDEBAR_ENABLED_KEY = "video_canvas_sidebar_enabled";
|
||||
|
||||
function normalizeHomeVariant(value: unknown): "classic" | "lovart" {
|
||||
@ -228,6 +229,17 @@ function normalizeCanvasAgentModeEnabled(value: unknown): boolean {
|
||||
return value !== false;
|
||||
}
|
||||
|
||||
function normalizeVideoCanvasEnabled(
|
||||
value: unknown,
|
||||
fallbackValue: unknown = true
|
||||
): boolean {
|
||||
if (value !== undefined && value !== null) {
|
||||
return value !== false;
|
||||
}
|
||||
|
||||
return fallbackValue !== false;
|
||||
}
|
||||
|
||||
function normalizeVideoCanvasSidebarEnabled(value: unknown): boolean {
|
||||
return value !== false;
|
||||
}
|
||||
@ -289,6 +301,7 @@ export async function GET() {
|
||||
realtimeCanvasConfigSetting,
|
||||
layerSplitConfigSetting,
|
||||
canvasAgentModeEnabledSetting,
|
||||
videoCanvasEnabledSetting,
|
||||
videoCanvasSidebarEnabledSetting,
|
||||
storageFailoverConfigSetting,
|
||||
ossImageMigrationConfigSetting,
|
||||
@ -402,6 +415,12 @@ export async function GET() {
|
||||
.where(eq(systemSettings.key, CANVAS_AGENT_MODE_ENABLED_KEY))
|
||||
.limit(1)
|
||||
.then(rows => rows[0]),
|
||||
db
|
||||
.select()
|
||||
.from(systemSettings)
|
||||
.where(eq(systemSettings.key, VIDEO_CANVAS_ENABLED_KEY))
|
||||
.limit(1)
|
||||
.then(rows => rows[0]),
|
||||
db
|
||||
.select()
|
||||
.from(systemSettings)
|
||||
@ -525,6 +544,10 @@ export async function GET() {
|
||||
const videoCanvasSidebarEnabled = normalizeVideoCanvasSidebarEnabled(
|
||||
videoCanvasSidebarEnabledSetting?.value
|
||||
);
|
||||
const videoCanvasEnabled = normalizeVideoCanvasEnabled(
|
||||
videoCanvasEnabledSetting?.value,
|
||||
videoCanvasSidebarEnabledSetting?.value
|
||||
);
|
||||
const storageFailoverConfig = normalizeStorageFailoverConfig(
|
||||
storageFailoverConfigSetting?.value
|
||||
);
|
||||
@ -601,6 +624,7 @@ export async function GET() {
|
||||
canvasEnabled: true,
|
||||
agentEnabled: true,
|
||||
canvasAgentModeEnabled: true,
|
||||
videoCanvasEnabled: true,
|
||||
videoCanvasSidebarEnabled: true,
|
||||
agentPresetLibraryConfig: defaultAgentPresetLibraryConfig,
|
||||
agentCategoryTreeConfig: normalizeAgentCategoryTreeConfig(undefined),
|
||||
@ -680,6 +704,7 @@ export async function GET() {
|
||||
realtimeCanvasServiceEnabled,
|
||||
layerSplitEnabled,
|
||||
canvasAgentModeEnabled,
|
||||
videoCanvasEnabled,
|
||||
videoCanvasSidebarEnabled,
|
||||
storageFailoverConfig,
|
||||
ossImageMigrationConfig,
|
||||
@ -758,6 +783,7 @@ const updateSchema = z.object({
|
||||
canvasEnabled: z.boolean().optional(),
|
||||
agentEnabled: z.boolean().optional(),
|
||||
canvasAgentModeEnabled: z.boolean().optional(),
|
||||
videoCanvasEnabled: z.boolean().optional(),
|
||||
videoCanvasSidebarEnabled: z.boolean().optional(),
|
||||
agentPresetLibraryConfig: z
|
||||
.object({
|
||||
@ -1128,6 +1154,7 @@ export async function PUT(request: NextRequest) {
|
||||
storageFailoverConfig,
|
||||
ossImageMigrationConfig,
|
||||
canvasAgentModeEnabled,
|
||||
videoCanvasEnabled,
|
||||
videoCanvasSidebarEnabled,
|
||||
homeAnimationConfig,
|
||||
...siteSettingsPayload
|
||||
@ -1347,6 +1374,26 @@ export async function PUT(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
if (videoCanvasEnabled !== undefined) {
|
||||
const normalized = normalizeVideoCanvasEnabled(videoCanvasEnabled);
|
||||
await db
|
||||
.insert(systemSettings)
|
||||
.values({
|
||||
key: VIDEO_CANVAS_ENABLED_KEY,
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: systemSettings.key,
|
||||
set: {
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (videoCanvasSidebarEnabled !== undefined) {
|
||||
const normalized = normalizeVideoCanvasSidebarEnabled(videoCanvasSidebarEnabled);
|
||||
await db
|
||||
@ -1863,6 +1910,10 @@ export async function PUT(request: NextRequest) {
|
||||
canvasAgentModeEnabled !== undefined
|
||||
? normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled)
|
||||
: normalizeCanvasAgentModeEnabled(undefined),
|
||||
videoCanvasEnabled:
|
||||
videoCanvasEnabled !== undefined
|
||||
? normalizeVideoCanvasEnabled(videoCanvasEnabled)
|
||||
: normalizeVideoCanvasEnabled(undefined, videoCanvasSidebarEnabled),
|
||||
videoCanvasSidebarEnabled:
|
||||
videoCanvasSidebarEnabled !== undefined
|
||||
? normalizeVideoCanvasSidebarEnabled(videoCanvasSidebarEnabled)
|
||||
@ -2417,6 +2468,26 @@ export async function PUT(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
if (videoCanvasEnabled !== undefined) {
|
||||
const normalized = normalizeVideoCanvasEnabled(videoCanvasEnabled);
|
||||
await db
|
||||
.insert(systemSettings)
|
||||
.values({
|
||||
key: VIDEO_CANVAS_ENABLED_KEY,
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: systemSettings.key,
|
||||
set: {
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
...created,
|
||||
homeVariant: homeVariant ?? normalizeHomeVariant(undefined),
|
||||
@ -2519,6 +2590,10 @@ export async function PUT(request: NextRequest) {
|
||||
canvasAgentModeEnabled !== undefined
|
||||
? normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled)
|
||||
: normalizeCanvasAgentModeEnabled(undefined),
|
||||
videoCanvasEnabled:
|
||||
videoCanvasEnabled !== undefined
|
||||
? normalizeVideoCanvasEnabled(videoCanvasEnabled)
|
||||
: normalizeVideoCanvasEnabled(undefined, videoCanvasSidebarEnabled),
|
||||
videoCanvasSidebarEnabled:
|
||||
videoCanvasSidebarEnabled !== undefined
|
||||
? normalizeVideoCanvasSidebarEnabled(videoCanvasSidebarEnabled)
|
||||
|
||||
@ -43,6 +43,7 @@ type ChatShellProps = {
|
||||
rankingEnabled: boolean;
|
||||
productPlanningEnabled: boolean;
|
||||
agentEnabled: boolean;
|
||||
videoCanvasEnabled: boolean;
|
||||
};
|
||||
|
||||
export function ChatShell({
|
||||
@ -65,6 +66,7 @@ export function ChatShell({
|
||||
rankingEnabled,
|
||||
productPlanningEnabled,
|
||||
agentEnabled,
|
||||
videoCanvasEnabled,
|
||||
}: ChatShellProps) {
|
||||
const pathname = usePathname();
|
||||
const isLovartHome = pathname === "/" && homeVariant === "lovart";
|
||||
@ -97,6 +99,7 @@ export function ChatShell({
|
||||
toolbox2Name={toolbox2Name}
|
||||
tutorialEnabled={tutorialEnabled}
|
||||
tutorialVideos={tutorialVideos}
|
||||
videoCanvasEnabled={videoCanvasEnabled}
|
||||
/>
|
||||
<div className="flex h-svh w-full overflow-hidden pl-16 [--sidebar-offset:4rem]">
|
||||
<AppSidebar user={user} />
|
||||
|
||||
@ -454,6 +454,7 @@ export function LovartHome({
|
||||
toolbox2Enabled?: boolean;
|
||||
productPlanningEnabled?: boolean;
|
||||
agentEnabled?: boolean;
|
||||
videoCanvasEnabled?: boolean;
|
||||
tutorialEnabled?: boolean;
|
||||
tutorialVideoUrl?: string | null;
|
||||
pointsPackages?: PointsPackage[];
|
||||
@ -1584,19 +1585,21 @@ export function LovartHome({
|
||||
<TooltipContent side="right">风格化</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full hover:bg-black/5"
|
||||
onClick={() => router.push("/video-canvas")}
|
||||
title="视频画布"
|
||||
>
|
||||
<Clapperboard className="h-[18px] w-[18px]" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">视频画布</TooltipContent>
|
||||
</Tooltip>
|
||||
{siteSettingsData?.videoCanvasEnabled !== false ? (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full hover:bg-black/5"
|
||||
onClick={() => router.push("/video-canvas")}
|
||||
title="视频画布"
|
||||
>
|
||||
<Clapperboard className="h-[18px] w-[18px]" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">视频画布</TooltipContent>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<button
|
||||
|
||||
@ -78,6 +78,7 @@ type TopNavbarProps = {
|
||||
rankingEnabled?: boolean;
|
||||
productPlanningEnabled?: boolean;
|
||||
agentEnabled?: boolean;
|
||||
videoCanvasEnabled?: boolean;
|
||||
};
|
||||
|
||||
export function TopNavbar({
|
||||
@ -96,6 +97,7 @@ export function TopNavbar({
|
||||
rankingEnabled = true,
|
||||
productPlanningEnabled = true,
|
||||
agentEnabled = true,
|
||||
videoCanvasEnabled = true,
|
||||
}: TopNavbarProps) {
|
||||
const router = useRouter();
|
||||
const { resolvedTheme } = useTheme();
|
||||
@ -604,17 +606,19 @@ export function TopNavbar({
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
className={navItemBaseClass}
|
||||
onClick={() => {
|
||||
window.location.href = "/video-canvas";
|
||||
}}
|
||||
title="视频画布"
|
||||
type="button"
|
||||
>
|
||||
<Clapperboard className="h-5 w-5" />
|
||||
<span className={navLabelClass}>{getShortLabel("视频画布")}</span>
|
||||
</button>
|
||||
{videoCanvasEnabled && (
|
||||
<button
|
||||
className={navItemBaseClass}
|
||||
onClick={() => {
|
||||
window.location.href = "/video-canvas";
|
||||
}}
|
||||
title="视频画布"
|
||||
type="button"
|
||||
>
|
||||
<Clapperboard className="h-5 w-5" />
|
||||
<span className={navLabelClass}>{getShortLabel("视频画布")}</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
className={navItemBaseClass}
|
||||
|
||||
@ -4450,6 +4450,7 @@ export async function getSiteSettings() {
|
||||
rankingEnabled: true,
|
||||
productPlanningEnabled: true,
|
||||
agentEnabled: true,
|
||||
videoCanvasEnabled: true,
|
||||
canvasDetailAgentModelId: null,
|
||||
lovartPromoText: "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠",
|
||||
lovartPromoActionText: "立即升级",
|
||||
@ -4457,8 +4458,19 @@ export async function getSiteSettings() {
|
||||
lovartHeroSubtitle: "懂你的设计代理,帮你搞定一切",
|
||||
};
|
||||
try {
|
||||
const [settings] = await db.select().from(siteSettings).limit(1);
|
||||
return settings || defaultSettings;
|
||||
const [settings, videoCanvasEnabledSetting, videoCanvasSidebarEnabledSetting] =
|
||||
await Promise.all([
|
||||
db.select().from(siteSettings).limit(1).then((rows) => rows[0]),
|
||||
getSystemSetting({ key: "video_canvas_enabled" }).catch(() => null),
|
||||
getSystemSetting({ key: "video_canvas_sidebar_enabled" }).catch(() => null),
|
||||
]);
|
||||
const videoCanvasEnabled =
|
||||
videoCanvasEnabledSetting?.value !== undefined &&
|
||||
videoCanvasEnabledSetting?.value !== null
|
||||
? videoCanvasEnabledSetting.value !== false
|
||||
: videoCanvasSidebarEnabledSetting?.value !== false;
|
||||
|
||||
return { ...(settings || defaultSettings), videoCanvasEnabled };
|
||||
} catch (_error) {
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user