mono/packages/ui/src/modules/layout/GenericCanvasView.tsx
2026-03-21 20:18:25 +01:00

110 lines
3.9 KiB
TypeScript

import React, { useEffect } from 'react';
import { useLayout } from '@/modules/layout/LayoutContext';
import { LayoutContainer } from './LayoutContainer';
import FlexibleContainerRenderer from './FlexibleContainerRenderer';
export interface GenericCanvasViewProps {
pageId: string;
pageName: string;
className?: string;
initialLayout?: any;
contextVariables?: Record<string, any>;
pageContext?: Record<string, any>;
}
const GenericCanvasView: React.FC<GenericCanvasViewProps> = ({
pageId,
pageName,
className = '',
initialLayout,
contextVariables,
pageContext,
}) => {
const {
loadedPages,
loadPageLayout,
hydratePageLayout,
isLoading,
} = useLayout();
const layout = loadedPages.get(pageId);
// Load the page layout on mount or hydrate from prop
useEffect(() => {
if (initialLayout && !layout) {
hydratePageLayout(pageId, initialLayout);
return;
}
if (!layout) {
loadPageLayout(pageId, pageName);
}
}, [pageId, pageName, layout, loadPageLayout, hydratePageLayout, initialLayout]);
if (isLoading || !layout) {
return (
<div className={`flex items-center justify-center min-h-[400px] ${className}`}>
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-4"></div>
<p className="text-slate-500 dark:text-slate-400">Loading {pageName.toLowerCase()}...</p>
</div>
</div>
);
}
const totalWidgets = layout.containers.reduce((total, container) => {
const getContainerWidgetCount = (cont: any): number => {
let count = cont.widgets.length;
if (cont.children) {
cont.children.forEach((child: any) => {
count += getContainerWidgetCount(child);
});
}
return count;
};
return total + getContainerWidgetCount(container);
}, 0);
if (totalWidgets === 0) {
return null;
}
return (
<div className={`${className.includes('p-0') ? 'space-y-2' : 'space-y-6'} ${className}`}>
{/* Container Canvas */}
<div className={`${className.includes('p-0') ? 'space-y-2' : 'space-y-4'}`}>
{layout.containers
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((container) => {
if (container.type === 'flex-container') {
return (
<FlexibleContainerRenderer
key={container.id}
container={container}
isEditMode={false}
pageId={pageId}
isCompactMode={className.includes('p-0')}
contextVariables={contextVariables}
pageContext={pageContext}
/>
);
}
return (
<LayoutContainer
key={container.id}
container={container}
isEditMode={false}
pageId={pageId}
isCompactMode={className.includes('p-0')}
contextVariables={contextVariables}
pageContext={pageContext}
/>
);
})}
</div>
</div>
);
};
export default GenericCanvasView;