diff --git a/frontend/src/AppBuilder/AppCanvas/Container.jsx b/frontend/src/AppBuilder/AppCanvas/Container.jsx index fc163939f6..c9466dc1dd 100644 --- a/frontend/src/AppBuilder/AppCanvas/Container.jsx +++ b/frontend/src/AppBuilder/AppCanvas/Container.jsx @@ -6,7 +6,15 @@ import useStore from '@/AppBuilder/_stores/store'; import { shallow } from 'zustand/shallow'; import { useDrop } from 'react-dnd'; import { addChildrenWidgetsToParent, addNewWidgetToTheEditor, computeViewerBackgroundColor } from './appCanvasUtils'; -import { CANVAS_WIDTHS, NO_OF_GRIDS, WIDGETS_WITH_DEFAULT_CHILDREN } from './appCanvasConstants'; +import { + CANVAS_WIDTHS, + NO_OF_GRIDS, + WIDGETS_WITH_DEFAULT_CHILDREN, + GRID_HEIGHT, + CONTAINER_CANVAS_PADDING, + CONTAINER_CANVAS_BORDER_WIDTH, + BOX_PADDING, +} from './appCanvasConstants'; import { useGridStore } from '@/_stores/gridStore'; import NoComponentCanvasContainer from './NoComponentCanvasContainer'; import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants'; @@ -95,7 +103,10 @@ export const Container = React.memo( if (canvasWidth !== undefined) { if (componentType === 'Listview' && listViewMode == 'grid') return canvasWidth / columns - 2; if (id === 'canvas') return canvasWidth; - return canvasWidth - 2; + if (componentType === 'Container') { + return canvasWidth - (2 * CONTAINER_CANVAS_PADDING + 2 * CONTAINER_CANVAS_BORDER_WIDTH + 2 * BOX_PADDING); + } + return canvasWidth - 2; // Need to update this 2 to correct value for other subcontainers } return realCanvasRef?.current?.offsetWidth; } @@ -143,7 +154,7 @@ export const Container = React.memo( }} style={{ height: id === 'canvas' ? `${canvasHeight}` : '100%', - backgroundSize: `${gridWidth}px ${10}px`, + backgroundSize: `${gridWidth}px ${GRID_HEIGHT}px`, backgroundColor: currentMode === 'view' ? computeViewerBackgroundColor(darkMode, canvasBgColor) diff --git a/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx b/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx index 6821f43ce2..6403d63201 100644 --- a/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx +++ b/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx @@ -830,7 +830,7 @@ export default function Grid({ gridWidth, currentLayout }) { onDragEnd={(e) => { try { if (isDraggingRef.current) { - useGridStore.getState().actions.setDraggingComponentId(null); + useStore.getState().setDraggingComponentId(null); isDraggingRef.current = false; } prevDragParentId.current = null; diff --git a/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx b/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx index 427cced97b..b26586dc08 100644 --- a/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx +++ b/frontend/src/AppBuilder/AppCanvas/RenderWidget.jsx @@ -6,7 +6,7 @@ import { OverlayTrigger } from 'react-bootstrap'; import { renderTooltip } from '@/_helpers/appUtils'; import { useTranslation } from 'react-i18next'; import ErrorBoundary from '@/_ui/ErrorBoundary'; - +import { BOX_PADDING } from './appCanvasConstants'; const shouldAddBoxShadowAndVisibility = [ 'Table', 'TextInput', @@ -164,7 +164,7 @@ const RenderWidget = ({
state.getComponentDefinition(id)?.layouts?.[currentLayout], shallow); const isWidgetActive = useStore((state) => state.selectedComponents.find((sc) => sc === id) && !readOnly, shallow); - const isDragging = useGridStore((state) => state.draggingComponentId === id); + const isDragging = useStore((state) => state.draggingComponentId === id); const isResizing = useGridStore((state) => state.resizingComponentId === id); const componentType = useStore((state) => state.getComponentDefinition(id)?.component?.component, shallow); const setHoveredComponentForGrid = useStore((state) => state.setHoveredComponentForGrid, shallow); diff --git a/frontend/src/AppBuilder/AppCanvas/appCanvasConstants.js b/frontend/src/AppBuilder/AppCanvas/appCanvasConstants.js index 75b3402331..1c598f8475 100644 --- a/frontend/src/AppBuilder/AppCanvas/appCanvasConstants.js +++ b/frontend/src/AppBuilder/AppCanvas/appCanvasConstants.js @@ -1,5 +1,7 @@ export const NO_OF_GRIDS = 43; +export const GRID_HEIGHT = 10; + export const CANVAS_WIDTHS = Object.freeze({ deviceWindowWidth: 450, leftSideBarWidth: 48, @@ -15,3 +17,9 @@ export const APP_HEADER_HEIGHT = 47; export const LEFT_SIDEBAR_WIDTH = 348; // exclusive of border export const SUBCONTAINER_WIDGETS = ['Container', 'Tabs', 'Listview', 'Kanban', 'Form']; + +export const CONTAINER_CANVAS_PADDING = 2; + +export const CONTAINER_CANVAS_BORDER_WIDTH = 1; + +export const BOX_PADDING = 2; diff --git a/frontend/src/AppBuilder/Widgets/Container.jsx b/frontend/src/AppBuilder/Widgets/Container.jsx index 1334098423..bcdb423561 100644 --- a/frontend/src/AppBuilder/Widgets/Container.jsx +++ b/frontend/src/AppBuilder/Widgets/Container.jsx @@ -2,6 +2,9 @@ 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 { CONTAINER_CANVAS_PADDING, CONTAINER_CANVAS_BORDER_WIDTH } from '@/AppBuilder/AppCanvas/appCanvasConstants'; +import useStore from '@/AppBuilder/_stores/store'; export const Container = ({ id, @@ -23,6 +26,11 @@ export const Container = ({ setExposedVariable ); + const isWidgetInContainerDragging = useStore( + (state) => state.containerChildrenMapping[id].includes(state.draggingComponentId), + shallow + ); + const contentBgColor = useMemo(() => { return { backgroundColor: @@ -42,8 +50,9 @@ export const Container = ({ const computedStyles = { backgroundColor: contentBgColor.backgroundColor, borderRadius: borderRadius ? parseFloat(borderRadius) : 0, - border: `1px solid ${borderColor}`, + border: `${CONTAINER_CANVAS_BORDER_WIDTH}px solid ${borderColor}`, height, + padding: `${CONTAINER_CANVAS_PADDING}px`, display: isVisible ? 'flex' : 'none', flexDirection: 'column', position: 'relative', @@ -61,9 +70,9 @@ export const Container = ({ const computedContentStyles = { ...contentBgColor, flex: 1, - overflow: 'auto', + // Prevent the scroll when dragging a widget inside the container or moving out of the container + overflow: isWidgetInContainerDragging ? 'hidden' : 'hidden auto', }; - return (
({ @@ -21,6 +22,7 @@ export const createGridSlice = (set, get) => ({ debouncedToggleCanvasUpdater: debounce(() => { get().toggleCanvasUpdater(); }, 200), + setDraggingComponentId: (id) => set(() => ({ draggingComponentId: id })), moveComponentPosition: (direction) => { const { setComponentLayout, currentLayout, getSelectedComponentsDefinition, debouncedToggleCanvasUpdater } = get(); let layouts = {}; diff --git a/frontend/src/Editor/DraggableBox.jsx b/frontend/src/Editor/DraggableBox.jsx index ae2740bc84..3cdad272b7 100644 --- a/frontend/src/Editor/DraggableBox.jsx +++ b/frontend/src/Editor/DraggableBox.jsx @@ -10,7 +10,7 @@ import { resolveWidgetFieldValue } from '@/_helpers/utils'; import ErrorBoundary from './ErrorBoundary'; import { useEditorStore } from '@/_stores/editorStore'; import { shallow } from 'zustand/shallow'; -import { useNoOfGrid, useGridStore } from '@/_stores/gridStore'; +import { useGridStore } from '@/_stores/gridStore'; import WidgetBox from './WidgetBox'; import * as Sentry from '@sentry/react'; import { findHighestLevelofSelection } from './DragContainer'; @@ -61,7 +61,7 @@ const DraggableBox = React.memo( }) => { const isResizing = useGridStore((state) => state.resizingComponentId === id); const [canDrag, setCanDrag] = useState(true); - const noOfGrid = useNoOfGrid(); + const noOfGrid = 43; const { currentLayout, setHoveredComponent, diff --git a/frontend/src/Editor/SubContainer.jsx b/frontend/src/Editor/SubContainer.jsx index 01335af55a..fc78875819 100644 --- a/frontend/src/Editor/SubContainer.jsx +++ b/frontend/src/Editor/SubContainer.jsx @@ -23,7 +23,7 @@ import { useEditorStore } from '@/_stores/editorStore'; // eslint-disable-next-line import/no-unresolved import { diff } from 'deep-object-diff'; -import { useGridStore, useResizingComponentId } from '@/_stores/gridStore'; +import { useGridStore } from '@/_stores/gridStore'; import GhostWidget from './GhostWidget'; import { deepClone } from '@/_helpers/utilities/utils.helpers'; @@ -68,7 +68,7 @@ export const SubContainer = ({ shallow ); - const resizingComponentId = useResizingComponentId(); + const resizingComponentId = useGridStore((state) => state.resizingComponentId, shallow); const noOfGrids = 43; const { isGridActive } = useGridStore((state) => ({ isGridActive: state.activeGrid === parent }), shallow); diff --git a/frontend/src/_stores/gridStore.js b/frontend/src/_stores/gridStore.js index aa070e4a89..213f07ac16 100644 --- a/frontend/src/_stores/gridStore.js +++ b/frontend/src/_stores/gridStore.js @@ -7,7 +7,6 @@ const initialState = { noOfGrid: 43, draggedSubContainer: false, resizingComponentId: null, - draggingComponentId: null, dragTarget: null, isGroupHandleHoverd: false, idGroupDragged: false, @@ -20,11 +19,7 @@ export const useGridStore = create( (set) => ({ ...initialState, actions: { - setActiveGrid: (gridId) => set({ activeGrid: gridId }), - setNoOfGrid: (noOfGrid) => set({ noOfGrid }), - setDraggedSubContainer: (draggedSubContainer) => set({ draggedSubContainer }), setResizingComponentId: (id) => set({ resizingComponentId: id }), - setDraggingComponentId: (id) => set({ draggingComponentId: id }), setDragTarget: (dragTarget) => set({ dragTarget }), setIsGroupHandleHoverd: (isGroupHandleHoverd) => set({ isGroupHandleHoverd }), setIdGroupDragged: (idGroupDragged) => set({ idGroupDragged }), @@ -46,21 +41,5 @@ useGridStore.subscribe(({ draggingComponentId }) => { } }); -// useEditorStore.subscribe(({ hoveredComponent }) => { -// console.log('hoveredComponent--', hoveredComponent); -// if (hoveredComponent) { -// document.querySelector(`[data-hovered-control]`)?.removeAttribute('data-hovered-control'); -// document.querySelector(`[target-id='${hoveredComponent}']`)?.setAttribute('data-hovered-control', true); -// } else if (document.querySelector(`[data-hovered-control]`)) { -// document.querySelector(`[data-hovered-control]`)?.removeAttribute('data-hovered-control'); -// } -// }); - -export const useActiveGrid = () => useGridStore((state) => state.activeGrid, shallow); -export const useNoOfGrid = () => useGridStore((state) => state.noOfGrid, shallow); -export const useDraggedSubContainer = () => useGridStore((state) => state.draggedSubContainer, shallow); -export const useGridStoreActions = () => useGridStore((state) => state.actions, shallow); -export const useDragTarget = () => useGridStore((state) => state.dragTarget, shallow); -export const useResizingComponentId = () => useGridStore((state) => state.resizingComponentId, shallow); export const useIsGroupHandleHoverd = () => useGridStore((state) => state.isGroupHandleHoverd, shallow); export const useOpenModalWidgetId = () => useGridStore((state) => state.openModalWidgetId, shallow);