diff --git a/frontend/src/components/AgGrid/agGridStyles.css b/frontend/src/components/AgGrid/agGridStyles.css
index 590046c2..e307f617 100644
--- a/frontend/src/components/AgGrid/agGridStyles.css
+++ b/frontend/src/components/AgGrid/agGridStyles.css
@@ -10,6 +10,9 @@ body {
--ag-row-hover-color: hsl(var(--muted));
--ag-wrapper-border: none;
--ag-font-family: var(--font-sans);
+ --ag-selected-row-background-color: hsl(var(--accent));
+ --ag-focus-shadow: none;
+ --ag-range-selection-border-color: hsl(var(--primary));
/* Checkbox styling */
--ag-checkbox-background-color: hsl(var(--background));
diff --git a/frontend/src/components/layout-wrapper.tsx b/frontend/src/components/layout-wrapper.tsx
index 79417654..dbd04fea 100644
--- a/frontend/src/components/layout-wrapper.tsx
+++ b/frontend/src/components/layout-wrapper.tsx
@@ -12,12 +12,10 @@ import { KnowledgeFilterPanel } from "@/components/knowledge-filter-panel";
import Logo from "@/components/logo/logo";
import { Navigation } from "@/components/navigation";
import { TaskNotificationMenu } from "@/components/task-notification-menu";
-import { Button } from "@/components/ui/button";
import { UserNav } from "@/components/user-nav";
import { useAuth } from "@/contexts/auth-context";
import { useChat } from "@/contexts/chat-context";
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";
-import { LayoutProvider } from "@/contexts/layout-context";
// import { GitHubStarButton } from "@/components/github-star-button"
// import { DiscordLink } from "@/components/discord-link"
import { useTask } from "@/contexts/task-context";
@@ -35,7 +33,7 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
refreshConversations,
startNewConversation,
} = useChat();
- const { isLoading: isSettingsLoading, data: settings } = useGetSettingsQuery({
+ const { isLoading: isSettingsLoading } = useGetSettingsQuery({
enabled: isAuthenticated || isNoAuthMode,
});
const {
@@ -59,6 +57,7 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
// List of paths that should not show navigation
const authPaths = ["/login", "/auth/callback", "/onboarding"];
const isAuthPage = authPaths.includes(pathname);
+ const isOnKnowledgePage = pathname.startsWith("/knowledge");
// List of paths with smaller max-width
const smallWidthPaths = ["/settings", "/settings/connector/new"];
@@ -66,7 +65,7 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
// Calculate active tasks for the bell icon
const activeTasks = tasks.filter(
- task =>
+ (task) =>
task.status === "pending" ||
task.status === "running" ||
task.status === "processing"
@@ -75,14 +74,6 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
const isUnhealthy = health?.status === "unhealthy" || isError;
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
if (isLoading || isSettingsLoading) {
return (
@@ -102,9 +93,18 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) {
// For all other pages, render with Langflow-styled navigation and task menu
return (
-
-
-
+
+
+
+
+
-
+
+ {/* Sidebar Navigation */}
+
-
-
+
+ {/* Main Content */}
+
+
-
- {children}
-
-
+ {children}
+
-
-
+
+ {/* Task Notifications Panel */}
+
+
+ {/* Knowledge Filter Panel */}
+
);
}
diff --git a/frontend/src/components/task-notification-menu.tsx b/frontend/src/components/task-notification-menu.tsx
index fed7e6f1..6cb968e8 100644
--- a/frontend/src/components/task-notification-menu.tsx
+++ b/frontend/src/components/task-notification-menu.tsx
@@ -143,10 +143,10 @@ export function TaskNotificationMenu() {
}
return (
-
+
{/* Header */}
-
+
diff --git a/frontend/src/components/ui/animated-processing-icon.tsx b/frontend/src/components/ui/animated-processing-icon.tsx
index 51815414..431202c1 100644
--- a/frontend/src/components/ui/animated-processing-icon.tsx
+++ b/frontend/src/components/ui/animated-processing-icon.tsx
@@ -1,37 +1,70 @@
-import type { SVGProps } from "react";
+import { cn } from "@/lib/utils";
+import { motion, easeInOut } from "framer-motion";
-export const AnimatedProcessingIcon = (props: SVGProps
) => {
- return (
-
- );
+export const AnimatedProcessingIcon = ({
+ className,
+}: {
+ className?: string;
+}) => {
+ const createAnimationFrames = (delay: number) => ({
+ opacity: [1, 1, 0.5, 0], // Opacity Steps
+ transition: {
+ delay,
+ duration: 1,
+ ease: easeInOut,
+ repeat: Infinity,
+ times: [0, 0.33, 0.66, 1], // Duration Percentages that Correspond to opacity Array
+ },
+ });
+
+ return (
+
+ );
};
diff --git a/frontend/src/components/ui/status-badge.tsx b/frontend/src/components/ui/status-badge.tsx
index e57ad3b5..19270284 100644
--- a/frontend/src/components/ui/status-badge.tsx
+++ b/frontend/src/components/ui/status-badge.tsx
@@ -50,7 +50,7 @@ export const StatusBadge = ({ status, className }: StatusBadgeProps) => {
}`}
>
{status === "processing" && (
-
+
)}
{config.label}
diff --git a/frontend/src/contexts/knowledge-filter-context.tsx b/frontend/src/contexts/knowledge-filter-context.tsx
index 043f6fae..eebf355a 100644
--- a/frontend/src/contexts/knowledge-filter-context.tsx
+++ b/frontend/src/contexts/knowledge-filter-context.tsx
@@ -5,6 +5,7 @@ import React, {
createContext,
type ReactNode,
useContext,
+ useEffect,
useState,
} from "react";
@@ -44,6 +45,8 @@ interface KnowledgeFilterContextType {
createMode: boolean;
startCreateMode: () => void;
endCreateMode: () => void;
+ queryOverride: string;
+ setQueryOverride: (query: string) => void;
}
const KnowledgeFilterContext = createContext<
@@ -73,6 +76,7 @@ export function KnowledgeFilterProvider({
useState
(null);
const [isPanelOpen, setIsPanelOpen] = useState(false);
const [createMode, setCreateMode] = useState(false);
+ const [queryOverride, setQueryOverride] = useState("");
const setSelectedFilter = (filter: KnowledgeFilter | null) => {
setSelectedFilterState(filter);
@@ -136,6 +140,11 @@ export function KnowledgeFilterProvider({
setCreateMode(false);
};
+ // Clear the search override when we change filters
+ useEffect(() => {
+ setQueryOverride("");
+ }, [selectedFilter]);
+
const value: KnowledgeFilterContextType = {
selectedFilter,
parsedFilterData,
@@ -148,6 +157,8 @@ export function KnowledgeFilterProvider({
createMode,
startCreateMode,
endCreateMode,
+ queryOverride,
+ setQueryOverride,
};
return (
diff --git a/frontend/src/contexts/layout-context.tsx b/frontend/src/contexts/layout-context.tsx
deleted file mode 100644
index f40ea28c..00000000
--- a/frontend/src/contexts/layout-context.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-"use client";
-
-import { createContext, useContext } from "react";
-
-interface LayoutContextType {
- headerHeight: number;
- totalTopOffset: number;
-}
-
-const LayoutContext = createContext(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 (
-
- {children}
-
- );
-}
\ No newline at end of file