55 lines
2.5 KiB
TypeScript
55 lines
2.5 KiB
TypeScript
import { useMemo, useCallback } from 'react';
|
|
import { useNavigate } from 'react-router';
|
|
import type { LayoutNode, PanelComponents } from 'officerdev';
|
|
import { WorkspaceView, ChatPanelWrapper } from 'officerdev';
|
|
import { useDashboardState } from 'state/useDashboardState';
|
|
import { useIsMobile } from 'hooks/useIsMobile';
|
|
import { defaultLayout } from './defaultLayout';
|
|
import { EmailList } from './EmailList';
|
|
import { EmailReader } from './EmailReader';
|
|
import { ComposeModal } from './Compose';
|
|
import { useSelectedEmailId } from './shared';
|
|
|
|
const PROMPT_PREFIX = `You are an email assistant. The user has a local SQLite email database available via the "email_db" tool — use it for all email queries (search, count, stats, aggregations, deletions) unless the user explicitly asks you to use Gmail. Do not use the Gmail integration for questions about existing emails.`;
|
|
|
|
// The prefix is this screen's, so this screen mounts the chat panel that gets it — rather than handing
|
|
// the string to the workspace to courier down to whichever app happens to read it. The panel id is the
|
|
// one in `defaultLayout`, and the layout is locked, so it is the same panel either way.
|
|
const EmailChatPanel = () => <ChatPanelWrapper panelId="email-chat" promptPrefix={PROMPT_PREFIX} />;
|
|
|
|
export const EmailScreen = () => {
|
|
const isMobile = useIsMobile();
|
|
const navigate = useNavigate();
|
|
// No `<Navigate>` guard: unlike a section route, the bare /email is a real state — the list with
|
|
// nothing open — exactly as /chat and /jobs are. An id that doesn't resolve is the reader's problem,
|
|
// not a reason to rewrite the address the user is looking at.
|
|
const selectedId = useSelectedEmailId();
|
|
const workspace = useDashboardState<LayoutNode>('screens/email', defaultLayout);
|
|
|
|
const components: PanelComponents = useMemo(
|
|
() => ({
|
|
'email-list': EmailList,
|
|
'email-reader': EmailReader,
|
|
'email-chat': EmailChatPanel,
|
|
}),
|
|
[],
|
|
);
|
|
|
|
const mobilePanelId = isMobile && selectedId ? 'email-reader' : undefined;
|
|
// Back on mobile closes the email, which is now just navigating to the bare route.
|
|
const onMobileBack = useCallback(() => navigate('/email'), [navigate]);
|
|
|
|
return (
|
|
<div className="h-full w-full pt-2">
|
|
<WorkspaceView
|
|
workspace={workspace}
|
|
locked
|
|
components={components}
|
|
mobilePanelId={mobilePanelId}
|
|
onMobilePanelChange={mobilePanelId ? () => onMobileBack() : undefined}
|
|
/>
|
|
<ComposeModal />
|
|
</div>
|
|
);
|
|
};
|