Fixes#1018
Remove the sync useEffect that copied preferences into local state,
along with the savingRef guard that prevented mid-save overwrites.
Instead, pass key={searchSpaceId} on the LLMRoleManager component so
React remounts the form with correct initial state whenever the search
space changes — no extra re-render, no effect dependency array.
Changes:
- llm-role-manager.tsx: remove useEffect + useRef + savingRef pattern;
drop useEffect and useRef from imports (now only useCallback, useState)
- search-space-settings-dialog.tsx: add key={searchSpaceId} to
<LLMRoleManager> so the component remounts on search-space change
Before: useEffect synced preferences → assignments on each preference
update, with savingRef to avoid overwriting an in-flight save.
After: React remounts the component with correct initial state from
the preferences selector; no mid-save race possible.
Fixes#1241
The docs bundle was importing `{ icons }` from lucide-react, which pulls
the entire Lucide icon library (~1 400 SVGs, ~500 kB of JS) into the Next.js
docs bundle even though only nine icons are used in docs frontmatter and
meta.json files.
Replace with a hand-maintained DOCS_ICONS whitelist that imports only the
icons that are actually referenced (BookOpen, ClipboardCheck, Compass,
Container, Download, FlaskConical, Heart, Unplug, Wrench).
To add a new docs icon: import it from lucide-react and add it to the
DOCS_ICONS record. The icon() callback remains the same for callers.
Fixes#1243
Add sibling loading.tsx files for all 6 async route segments that were
missing instant loading UI, causing blank screens during navigation on
slow networks or cold caches.
Routes covered:
- /docs/[[...slug]] — awaits getDocPage + MDX body
- /blog — awaits source.getPages()
- /blog/[slug] — awaits params + MDX body
- /changelog — awaits source.getPages()
- /free — awaits getModels() fetch
- /free/[model_slug] — awaits Promise.all([getModel, getAllModels])
Each loading.tsx is a Server Component returning an animate-pulse
skeleton that matches its route's layout (header, content area,
grid/table/timeline as appropriate). Uses the Skeleton component and
Tailwind classes already present in the project.
Follows the pattern established in:
- app/dashboard/[search_space_id]/logs/loading.tsx
- app/dashboard/[search_space_id]/new-chat/loading.tsx
Fixes#1246
Replace the useState/useEffect pattern that synced fuzzy search results
into local state on every search or searcher change with a single useMemo
that derives results directly during render.
Before:
const [results, setResults] = useState(allBlogs);
useEffect(() => {
setResults(searcher.search(search));
}, [search, searcher]);
After:
const gridItems = useMemo(() => {
const results = search.trim() ? searcher.search(search) : allBlogs;
...
}, [search, searcher, allBlogs, featuredSlug]);
This removes an extra re-render per keystroke and eliminates the stale
intermediate state that occurred between the search input change and the
effect firing.
- Updated `content_hash` in the `Document` model to remove global uniqueness, allowing identical content across different paths.
- Enhanced `_create_document` function to handle path uniqueness and prevent session-poisoning from `IntegrityError`.
- Added detailed comments for clarity on the changes and their implications.
- Introduced new citation handling in the editor for improved user experience with citation jumps.
- Updated package dependencies in the frontend for better functionality.
- Updated icon imports and usages in AssistantMessage, CommentItem, CommentSheet, CommentThread, and InboxSidebar components.
- Enhanced visual consistency by standardizing the reply icon throughout the chat-related UI elements.
The announcements page is a public, crawlable route but its page.tsx is
'use client', so it can't export metadata itself and falls back to the
root app/layout.tsx. Add a server-component layout.tsx under
app/(home)/announcements/ that exports route-specific metadata (title,
description, canonical, OpenGraph, Twitter) in the same shape as the
neighboring /blog, /changelog, /contact, /privacy, /terms routes.
page.tsx is unchanged.
Canonical URL matches app/layout.tsx's metadataBase
(https://surfsense.com).
Fixes#1244