Workspaces layout, automation page
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user