refactor the grid layout to inlcude banner and header rows
This commit is contained in:
parent
c9c670d3ab
commit
9d1aced1e7
4 changed files with 64 additions and 92 deletions
|
|
@ -110,31 +110,46 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.app-grid-cols-arrangement {
|
.app-grid-arrangement {
|
||||||
--sidebar-width: 0px;
|
--sidebar-width: 0px;
|
||||||
--notifications-width: 0px;
|
--notifications-width: 0px;
|
||||||
--filters-width: 0px;
|
--filters-width: 0px;
|
||||||
|
--app-header-height: 53px;
|
||||||
|
--top-banner-height: 0px;
|
||||||
|
|
||||||
@media (width >= 48rem) {
|
@media (width >= 48rem) {
|
||||||
--sidebar-width: 288px;
|
--sidebar-width: 288px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.notifications-open {
|
&.notifications-open {
|
||||||
--notifications-width: 320px;
|
--notifications-width: 320px;
|
||||||
}
|
}
|
||||||
&.filters-open {
|
&.filters-open {
|
||||||
--filters-width: 320px;
|
--filters-width: 320px;
|
||||||
}
|
}
|
||||||
|
&.banner-visible {
|
||||||
|
--top-banner-height: 52px;
|
||||||
|
}
|
||||||
display: grid;
|
display: grid;
|
||||||
height: calc(100% - var(--app-header-height));
|
height: 100%;
|
||||||
grid-template-columns: var(--sidebar-width) 1fr var(--notifications-width) var(
|
width: 100%;
|
||||||
--filters-width
|
grid-template-rows:
|
||||||
);
|
var(--top-banner-height)
|
||||||
transition: grid-template-columns 0.3s ease-in-out;
|
var(--app-header-height)
|
||||||
|
1fr;
|
||||||
|
grid-template-columns:
|
||||||
|
var(--sidebar-width)
|
||||||
|
1fr
|
||||||
|
var(--notifications-width)
|
||||||
|
var(--filters-width);
|
||||||
|
grid-template-areas:
|
||||||
|
"banner banner banner banner"
|
||||||
|
"header header header header"
|
||||||
|
"nav main notifications filters";
|
||||||
|
transition: grid-template-columns 0.25s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-arrangement {
|
.header-arrangement {
|
||||||
@apply flex w-full h-[53px] items-center justify-between border-b border-border;
|
@apply flex w-full items-center justify-between border-b border-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-start-display {
|
.header-start-display {
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import { ProtectedRoute } from "@/components/protected-route";
|
import { ProtectedRoute } from "@/components/protected-route";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
|
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
|
||||||
import { useLayout } from "@/contexts/layout-context";
|
|
||||||
import { useTask } from "@/contexts/task-context";
|
|
||||||
import {
|
import {
|
||||||
type ChunkResult,
|
type ChunkResult,
|
||||||
type File,
|
type File,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import { UserNav } from "@/components/user-nav";
|
||||||
import { useAuth } from "@/contexts/auth-context";
|
import { useAuth } from "@/contexts/auth-context";
|
||||||
import { useChat } from "@/contexts/chat-context";
|
import { useChat } from "@/contexts/chat-context";
|
||||||
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
|
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
|
||||||
import { LayoutProvider } from "@/contexts/layout-context";
|
|
||||||
// import { GitHubStarButton } from "@/components/github-star-button"
|
// import { GitHubStarButton } from "@/components/github-star-button"
|
||||||
// import { DiscordLink } from "@/components/discord-link"
|
// import { DiscordLink } from "@/components/discord-link"
|
||||||
import { useTask } from "@/contexts/task-context";
|
import { useTask } from "@/contexts/task-context";
|
||||||
|
|
@ -34,7 +33,7 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
|
||||||
refreshConversations,
|
refreshConversations,
|
||||||
startNewConversation,
|
startNewConversation,
|
||||||
} = useChat();
|
} = useChat();
|
||||||
const { isLoading: isSettingsLoading, data: settings } = useGetSettingsQuery({
|
const { isLoading: isSettingsLoading } = useGetSettingsQuery({
|
||||||
enabled: isAuthenticated || isNoAuthMode,
|
enabled: isAuthenticated || isNoAuthMode,
|
||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
|
|
@ -75,14 +74,6 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
|
||||||
const isUnhealthy = health?.status === "unhealthy" || isError;
|
const isUnhealthy = health?.status === "unhealthy" || isError;
|
||||||
const isBannerVisible = !isHealthLoading && isUnhealthy;
|
const isBannerVisible = !isHealthLoading && isUnhealthy;
|
||||||
|
|
||||||
// Dynamic height calculations based on banner visibility
|
|
||||||
const headerHeight = 53;
|
|
||||||
const bannerHeight = 52; // Approximate banner height
|
|
||||||
const totalTopOffset = isBannerVisible
|
|
||||||
? headerHeight + bannerHeight
|
|
||||||
: headerHeight;
|
|
||||||
const mainContentHeight = `calc(100vh - ${totalTopOffset}px)`;
|
|
||||||
|
|
||||||
// Show loading state when backend isn't ready
|
// Show loading state when backend isn't ready
|
||||||
if (isLoading || isSettingsLoading) {
|
if (isLoading || isSettingsLoading) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -102,9 +93,18 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
|
||||||
|
|
||||||
// For all other pages, render with Langflow-styled navigation and task menu
|
// For all other pages, render with Langflow-styled navigation and task menu
|
||||||
return (
|
return (
|
||||||
<div className="h-full relative">
|
<div
|
||||||
<DoclingHealthBanner className="w-full pt-2" />
|
className={cn(
|
||||||
<header className="header-arrangement bg-background sticky top-0 z-50 h-10">
|
"app-grid-arrangement",
|
||||||
|
isBannerVisible && "banner-visible",
|
||||||
|
isPanelOpen && isOnKnowledgePage && !isMenuOpen && "filters-open",
|
||||||
|
isMenuOpen && "notifications-open"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="w-full [grid-area:banner]">
|
||||||
|
<DoclingHealthBanner className="w-full" />
|
||||||
|
</div>
|
||||||
|
<header className="header-arrangement bg-background [grid-area:header]">
|
||||||
<div className="header-start-display px-[16px]">
|
<div className="header-start-display px-[16px]">
|
||||||
{/* Logo/Title */}
|
{/* Logo/Title */}
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
|
|
@ -144,44 +144,37 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"app-grid-cols-arrangement",
|
|
||||||
isPanelOpen && isOnKnowledgePage && !isMenuOpen && "filters-open",
|
|
||||||
isMenuOpen && "notifications-open"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{/* Sidebar Navigation */}
|
|
||||||
<aside className="bg-background border-r overflow-hidden">
|
|
||||||
<Navigation
|
|
||||||
conversations={conversations}
|
|
||||||
isConversationsLoading={isConversationsLoading}
|
|
||||||
onNewConversation={handleNewConversation}
|
|
||||||
/>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
{/* Main Content */}
|
{/* Sidebar Navigation */}
|
||||||
<main className="overflow-y-auto">
|
<aside className="bg-background border-r overflow-hidden [grid-area:nav]">
|
||||||
<div
|
<Navigation
|
||||||
className={cn(
|
conversations={conversations}
|
||||||
"p-6 h-full container",
|
isConversationsLoading={isConversationsLoading}
|
||||||
isSmallWidthPath && "max-w-[850px] ml-0"
|
onNewConversation={handleNewConversation}
|
||||||
)}
|
/>
|
||||||
>
|
</aside>
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
{/* Task Notifications Panel */}
|
{/* Main Content */}
|
||||||
<aside className="overflow-y-auto overflow-x-hidden">
|
<main className="overflow-y-auto [grid-area:main]">
|
||||||
{isMenuOpen && <TaskNotificationMenu />}
|
<div
|
||||||
</aside>
|
className={cn(
|
||||||
|
"p-6 h-full container",
|
||||||
|
isSmallWidthPath && "max-w-[850px] ml-0"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
{/* Knowledge Filter Panel */}
|
{/* Task Notifications Panel */}
|
||||||
<aside className="overflow-y-auto overflow-x-hidden">
|
<aside className="overflow-y-auto overflow-x-hidden [grid-area:notifications]">
|
||||||
{isPanelOpen && <KnowledgeFilterPanel />}
|
{isMenuOpen && <TaskNotificationMenu />}
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
|
||||||
|
{/* Knowledge Filter Panel */}
|
||||||
|
<aside className="overflow-y-auto overflow-x-hidden [grid-area:filters]">
|
||||||
|
{isPanelOpen && <KnowledgeFilterPanel />}
|
||||||
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
"use client";
|
|
||||||
|
|
||||||
import { createContext, useContext } from "react";
|
|
||||||
|
|
||||||
interface LayoutContextType {
|
|
||||||
headerHeight: number;
|
|
||||||
totalTopOffset: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LayoutContext = createContext<LayoutContextType | undefined>(undefined);
|
|
||||||
|
|
||||||
export function useLayout() {
|
|
||||||
const context = useContext(LayoutContext);
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error("useLayout must be used within a LayoutProvider");
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function LayoutProvider({
|
|
||||||
children,
|
|
||||||
headerHeight,
|
|
||||||
totalTopOffset
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
headerHeight: number;
|
|
||||||
totalTopOffset: number;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<LayoutContext.Provider value={{ headerHeight, totalTopOffset }}>
|
|
||||||
{children}
|
|
||||||
</LayoutContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue