workspaces to dashboards, imap email sync, ffmpeg tool, tts fix, file browser refresh, automation sidebar reorder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-02 20:00:45 +00:00
co-authored by Claude Opus 4.6
parent bd362dc586
commit 927267e041
98 changed files with 1176 additions and 802 deletions
@@ -20,6 +20,7 @@ const LIMIT = 50;
const FOLDERS = [
{ key: 'inbox', label: 'Inbox', icon: Inbox },
{ key: 'all', label: 'All', icon: Mail },
{ key: 'sent', label: 'Sent', icon: Send },
{ key: 'spam', label: 'Spam', icon: ShieldAlert },
{ key: 'trash', label: 'Trash', icon: Trash2 },
@@ -55,6 +56,19 @@ export const EmailList = () => {
client.get<{ messages: EmailSummary[]; total: number }>(`/email/messages?page=${page}&limit=${LIMIT}&folder=${folder}`),
});
// Auto-switch to "all" if inbox filter returns nothing but emails exist
const { data: allCount } = useQuery({
queryKey: ['email-messages-all-count'],
queryFn: () => client.get<{ messages: EmailSummary[]; total: number }>('/email/messages?page=1&limit=1&folder=all'),
enabled: folder === 'inbox' && !isLoading && (data?.total ?? 0) === 0,
});
useEffect(() => {
if (folder === 'inbox' && data?.total === 0 && allCount && allCount.total > 0) {
setFolder('all');
}
}, [folder, data?.total, allCount]);
const handleFolderChange = (newFolder: string) => {
setFolder(newFolder);
setPage(1);
@@ -1,7 +1,7 @@
import { useMemo, useCallback } from 'react';
import type { LayoutNode, PanelComponents } from 'officerdev';
import { WorkspaceView } from 'officerdev';
import { useWorkspacesState } from 'state/useWorkspacesState';
import { useDashboardState } from 'state/useDashboardState';
import { useIsMobile } from 'hooks/useIsMobile';
import { useGlobal } from 'hooks/useGlobal';
import { defaultLayout } from './defaultLayout';
@@ -13,7 +13,7 @@ const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite e
export const EmailScreen = () => {
const isMobile = useIsMobile();
const [selectedId, setSelectedId] = useGlobal<string | null>('EMAIL_SELECTED', null);
const workspace = useWorkspacesState<LayoutNode>('screens/email', defaultLayout);
const workspace = useDashboardState<LayoutNode>('screens/email', defaultLayout);
const components: PanelComponents = useMemo(
() => ({