Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
CREDO23 2026-02-03 14:24:24 +02:00
commit 60330622bf
54 changed files with 1542 additions and 34 deletions

View file

@ -536,10 +536,11 @@ export const InlineMentionEditor = forwardRef<InlineMentionEditorRef, InlineMent
role="textbox"
aria-multiline="true"
/>
{/* Placeholder */}
{/* Placeholder with fade animation on change */}
{isEmpty && (
<div
className="absolute top-0 left-0 pointer-events-none text-muted-foreground text-sm"
key={placeholder}
className="absolute top-0 left-0 pointer-events-none text-muted-foreground text-sm animate-in fade-in duration-1000"
aria-hidden="true"
>
{placeholder}

View file

@ -65,6 +65,16 @@ import type { Document } from "@/contracts/types/document.types";
import { useCommentsElectric } from "@/hooks/use-comments-electric";
import { cn } from "@/lib/utils";
/** Placeholder texts that cycle in new chats when input is empty */
const CYCLING_PLACEHOLDERS = [
"Ask SurfSense anything or @mention docs.",
"Generate a podcast from marketing tips in the company handbook.",
"Sum up our vacation policy from Drive.",
"Give me a brief overview of the most urgent tickets in Jira and Linear.",
"Create a concise table of today's top ten emails and calendar events.",
"Check if this week's Slack messages reference any GitHub issues.",
];
interface ThreadProps {
messageThinkingSteps?: Map<string, ThinkingStep[]>;
header?: React.ReactNode;
@ -228,6 +238,30 @@ const Composer: FC = () => {
const isThreadEmpty = useAssistantState(({ thread }) => thread.isEmpty);
const isThreadRunning = useAssistantState(({ thread }) => thread.isRunning);
// Cycling placeholder state - only cycles in new chats
const [placeholderIndex, setPlaceholderIndex] = useState(0);
// Cycle through placeholders every 4 seconds when thread is empty (new chat)
useEffect(() => {
// Only cycle when thread is empty (new chat)
if (!isThreadEmpty) {
// Reset to first placeholder when chat becomes active
setPlaceholderIndex(0);
return;
}
const intervalId = setInterval(() => {
setPlaceholderIndex((prev) => (prev + 1) % CYCLING_PLACEHOLDERS.length);
}, 6000);
return () => clearInterval(intervalId);
}, [isThreadEmpty]);
// Compute current placeholder - only cycle in new chats
const currentPlaceholder = isThreadEmpty
? CYCLING_PLACEHOLDERS[placeholderIndex]
: CYCLING_PLACEHOLDERS[0];
// Live collaboration state
const { data: currentUser } = useAtomValue(currentUserAtom);
const { data: members } = useAtomValue(membersAtom);
@ -410,7 +444,7 @@ const Composer: FC = () => {
<div ref={editorContainerRef} className="aui-composer-input-wrapper px-3 pt-3 pb-6">
<InlineMentionEditor
ref={editorRef}
placeholder="Ask SurfSense or @mention docs"
placeholder={currentPlaceholder}
onMentionTrigger={handleMentionTrigger}
onMentionClose={handleMentionClose}
onChange={handleEditorChange}

View file

@ -237,7 +237,7 @@ export function InboxSidebar({
const currentDataSource = activeTab === "mentions" ? mentions : status;
const { loading, loadingMore = false, hasMore = false, loadMore } = currentDataSource;
// Status tab includes: connector indexing, document processing, page limit exceeded
// Status tab includes: connector indexing, document processing, page limit exceeded, connector deletion
// Filter to only show status notification types
const statusItems = useMemo(
() =>
@ -245,7 +245,8 @@ export function InboxSidebar({
(item) =>
item.type === "connector_indexing" ||
item.type === "document_processing" ||
item.type === "page_limit_exceeded"
item.type === "page_limit_exceeded" ||
item.type === "connector_deletion"
),
[status.items]
);