105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import { useEffect, useMemo, useRef } from 'react';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { useClient } from 'hooks/useClient';
|
|
import { useAuth } from 'hooks/useAuth';
|
|
import { usePanelChannel } from 'hooks/usePanelChannel';
|
|
import type { LayoutNode, PanelComponents } from '@/components/Workspace';
|
|
import { WorkspaceLayout } from '@/components/Workspace';
|
|
import { useUserState } from '@/state/useUserState';
|
|
import { appRegistry } from '../Workspaces/app-registry';
|
|
import { AutomationRightPanel } from './AutomationRightPanel';
|
|
import type { AutomationSelection } from './AutomationRightPanel';
|
|
import { AutomationEditChat } from './AutomationEditChat';
|
|
import { AutomationSidebar } from './AutomationSidebar';
|
|
|
|
const CHAT_PANEL_ID = 'automation-chat';
|
|
|
|
const baseLayout: LayoutNode = {
|
|
type: 'group',
|
|
id: 'automation-root',
|
|
direction: 'horizontal',
|
|
children: [
|
|
{ node: { type: 'panel', id: 'automation-left', appType: null }, size: 20 },
|
|
{ node: { type: 'panel', id: 'automation-right', appType: null }, size: 80 },
|
|
],
|
|
};
|
|
|
|
const splitLayout: LayoutNode = {
|
|
type: 'group',
|
|
id: 'automation-root',
|
|
direction: 'horizontal',
|
|
children: [
|
|
{ node: { type: 'panel', id: 'automation-left', appType: null }, size: 20 },
|
|
{
|
|
node: {
|
|
type: 'group',
|
|
id: 'automation-right-group',
|
|
direction: 'vertical',
|
|
children: [
|
|
{ node: { type: 'panel', id: 'automation-right', appType: null }, size: 50 },
|
|
{ node: { type: 'panel', id: CHAT_PANEL_ID, appType: null }, size: 50 },
|
|
],
|
|
},
|
|
size: 80,
|
|
},
|
|
],
|
|
};
|
|
|
|
export const Automation = () => {
|
|
const client = useClient();
|
|
const { isAuthenticated } = useAuth();
|
|
const { isFetched } = useQuery({
|
|
queryKey: ['USER_STATE'],
|
|
enabled: isAuthenticated,
|
|
queryFn: () => client.get('/user/state'),
|
|
staleTime: Infinity,
|
|
});
|
|
const [savedSizes, setSavedSizes] = useUserState<number[] | null>('automation:chat-sizes', null);
|
|
const [selection] = usePanelChannel<AutomationSelection>('automation:selected-capability', null);
|
|
const editing = selection?.editing ?? false;
|
|
const prevEditing = useRef(editing);
|
|
|
|
const layout = useMemo(() => {
|
|
if (!editing) return baseLayout;
|
|
const l = structuredClone(splitLayout);
|
|
if (savedSizes && l.type === 'group') {
|
|
const rightGroup = l.children[1]!.node;
|
|
if (rightGroup.type === 'group') {
|
|
rightGroup.children[0]!.size = savedSizes[0] ?? 50;
|
|
rightGroup.children[1]!.size = savedSizes[1] ?? 50;
|
|
}
|
|
}
|
|
return l;
|
|
}, [editing, savedSizes]);
|
|
|
|
const handleLayoutChange = (newLayout: LayoutNode) => {
|
|
if (!editing || newLayout.type !== 'group') return;
|
|
const rightChild = newLayout.children[1]?.node;
|
|
if (rightChild?.type === 'group') {
|
|
const sizes = rightChild.children.map((c) => c.size);
|
|
setSavedSizes(sizes);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
prevEditing.current = editing;
|
|
}, [editing]);
|
|
|
|
const panelComponents: PanelComponents = useMemo(
|
|
() => ({
|
|
'automation-left': AutomationSidebar,
|
|
'automation-right': AutomationRightPanel,
|
|
[CHAT_PANEL_ID]: AutomationEditChat,
|
|
}),
|
|
[],
|
|
);
|
|
|
|
if (!isFetched) return null;
|
|
|
|
return (
|
|
<div className="h-full w-full pt-2">
|
|
<WorkspaceLayout layout={layout} onLayoutChange={handleLayoutChange} registry={appRegistry} components={panelComponents} />
|
|
</div>
|
|
);
|
|
};
|