mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 08:58:26 +00:00
146 lines
4.6 KiB
JavaScript
146 lines
4.6 KiB
JavaScript
import React, { useMemo } from 'react';
|
|
import { Container as ContainerComponent } from '@/AppBuilder/AppCanvas/Container';
|
|
import Spinner from '@/_ui/Spinner';
|
|
import { useExposeState } from '@/AppBuilder/_hooks/useExposeVariables';
|
|
import { shallow } from 'zustand/shallow';
|
|
import { useDynamicHeight } from '@/_hooks/useDynamicHeight';
|
|
import {
|
|
CONTAINER_FORM_CANVAS_PADDING,
|
|
SUBCONTAINER_CANVAS_BORDER_WIDTH,
|
|
} from '@/AppBuilder/AppCanvas/appCanvasConstants';
|
|
import useStore from '@/AppBuilder/_stores/store';
|
|
import './container.scss';
|
|
import { useActiveSlot } from '@/AppBuilder/_hooks/useActiveSlot';
|
|
import { HorizontalSlot } from '@/AppBuilder/Widgets/Form/Components/HorizontalSlot';
|
|
|
|
export const Container = ({
|
|
id,
|
|
properties,
|
|
styles,
|
|
darkMode,
|
|
height,
|
|
width,
|
|
setExposedVariables,
|
|
setExposedVariable,
|
|
adjustComponentPositions,
|
|
currentLayout,
|
|
componentCount = 0,
|
|
}) => {
|
|
const { isDisabled, isVisible, isLoading } = useExposeState(
|
|
properties.loadingState,
|
|
properties.visibility,
|
|
properties.disabledState,
|
|
setExposedVariables,
|
|
setExposedVariable
|
|
);
|
|
const { dynamicHeight } = properties;
|
|
|
|
useDynamicHeight({
|
|
dynamicHeight: properties.dynamicHeight,
|
|
id,
|
|
height,
|
|
adjustComponentPositions,
|
|
currentLayout,
|
|
isContainer: true,
|
|
componentCount,
|
|
});
|
|
|
|
const isWidgetInContainerDragging = useStore(
|
|
(state) => state.containerChildrenMapping?.[id]?.includes(state?.draggingComponentId),
|
|
shallow
|
|
);
|
|
|
|
const setComponentProperty = useStore((state) => state.setComponentProperty, shallow);
|
|
const activeSlot = useActiveSlot(id); // Track the active slot for this widget
|
|
const { borderRadius, borderColor, boxShadow } = styles;
|
|
const { headerHeight = 80 } = properties;
|
|
const headerMaxHeight = parseInt(height, 10) - 100 - 10;
|
|
const contentBgColor = useMemo(() => {
|
|
return {
|
|
backgroundColor:
|
|
['#fff', '#ffffffff'].includes(styles.backgroundColor) && darkMode ? '#232E3C' : styles.backgroundColor,
|
|
};
|
|
}, [styles.backgroundColor, darkMode]);
|
|
|
|
const headerBgColor = useMemo(() => {
|
|
return {
|
|
backgroundColor:
|
|
['#fff', '#ffffffff'].includes(styles.headerBackgroundColor) && darkMode
|
|
? '#232E3C'
|
|
: styles.headerBackgroundColor,
|
|
};
|
|
}, [styles.headerBackgroundColor, darkMode]);
|
|
|
|
const computedStyles = {
|
|
backgroundColor: contentBgColor.backgroundColor,
|
|
borderRadius: borderRadius ? parseFloat(borderRadius) : 0,
|
|
border: `${SUBCONTAINER_CANVAS_BORDER_WIDTH}px solid ${borderColor}`,
|
|
height: dynamicHeight ? '100%' : height,
|
|
display: isVisible ? 'flex' : 'none',
|
|
flexDirection: 'column',
|
|
position: 'relative',
|
|
boxShadow,
|
|
};
|
|
|
|
const containerHeaderStyles = {
|
|
flexShrink: 0,
|
|
padding: `${CONTAINER_FORM_CANVAS_PADDING}px ${CONTAINER_FORM_CANVAS_PADDING}px 3px ${CONTAINER_FORM_CANVAS_PADDING}px`,
|
|
maxHeight: `${headerMaxHeight}px`,
|
|
...headerBgColor,
|
|
};
|
|
const containerContentStyles = {
|
|
overflow: 'hidden auto',
|
|
display: 'flex',
|
|
height: '100%',
|
|
padding: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
|
};
|
|
|
|
const updateHeaderSizeInStore = ({ newHeight }) => {
|
|
const _height = parseInt(newHeight, 10);
|
|
setComponentProperty(id, `headerHeight`, _height, 'properties', 'value', false);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={`jet-container ${isLoading ? 'jet-container-loading' : ''}`}
|
|
id={id}
|
|
data-disabled={isDisabled}
|
|
style={computedStyles}
|
|
>
|
|
{isLoading ? (
|
|
<Spinner />
|
|
) : (
|
|
<>
|
|
{properties.showHeader && (
|
|
<HorizontalSlot
|
|
slotName={'header'}
|
|
slotStyle={containerHeaderStyles}
|
|
id={`${id}-header`}
|
|
height={headerHeight}
|
|
width={width}
|
|
darkMode={darkMode}
|
|
isDisabled={isDisabled}
|
|
isActive={activeSlot === `${id}-header`}
|
|
onResize={updateHeaderSizeInStore}
|
|
componentType="Container"
|
|
/>
|
|
)}
|
|
<div style={containerContentStyles} className={`${properties.dynamicHeight && `dynamic-${id}`}`}>
|
|
<ContainerComponent
|
|
id={id}
|
|
styles={{
|
|
...contentBgColor,
|
|
// Prevent the scroll when dragging a widget inside the container or moving out of the container
|
|
overflow: isWidgetInContainerDragging ? 'hidden' : 'hidden auto',
|
|
}}
|
|
canvasHeight={dynamicHeight ? '100%' : height}
|
|
canvasWidth={width}
|
|
darkMode={darkMode}
|
|
componentType="Container"
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|