mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-05 22:38:48 +00:00
Merge pull request #13240 from ToolJet/perf/performance-imp
[fix]: Removed unwanted re-renders
This commit is contained in:
commit
1d5fabae0a
17 changed files with 101 additions and 125 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit dbb130bfd859ab795557a36dc26936aa2252e248
|
||||
Subproject commit e95965cf14966d3f5727835adf5b8d3ca55a569e
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Suspense, lazy, useEffect } from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import useAppData from '@/AppBuilder/_hooks/useAppData';
|
||||
import { TJLoader } from '@/_ui/TJLoader/TJLoader';
|
||||
|
|
@ -28,7 +28,6 @@ import ArtifactPreview from './ArtifactPreview';
|
|||
// TODO: split Loader into separate component and remove editor loading state from Editor
|
||||
export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMode, appType = 'front-end' }) => {
|
||||
useAppData(appId, moduleId, darkMode);
|
||||
const isRightSidebarOpen = useStore((state) => state.isRightSidebarOpen);
|
||||
const isEditorLoading = useStore((state) => state.loaderStore.modules[moduleId].isEditorLoading, shallow);
|
||||
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
|
||||
const isModuleEditor = appType === 'module';
|
||||
|
|
@ -64,7 +63,6 @@ export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMod
|
|||
isUserInZeroToOneFlow={isUserInZeroToOneFlow}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
{isUserInZeroToOneFlow ? (
|
||||
<ArtifactPreview darkMode={darkMode} isUserInZeroToOneFlow={isUserInZeroToOneFlow} />
|
||||
) : (
|
||||
|
|
@ -74,7 +72,7 @@ export const Editor = ({ id: appId, darkMode, moduleId = 'canvas', switchDarkMod
|
|||
<AppCanvas moduleId={moduleId} appId={appId} switchDarkMode={switchDarkMode} darkMode={darkMode} />
|
||||
<QueryPanel darkMode={darkMode} />
|
||||
<RightSidebarToggle darkMode={darkMode} />
|
||||
{isRightSidebarOpen && <RightSideBar darkMode={darkMode} />}{' '}
|
||||
<RightSideBar darkMode={darkMode} />
|
||||
</DndProvider>
|
||||
<Popups darkMode={darkMode} />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import {
|
|||
RIGHT_SIDEBAR_WIDTH,
|
||||
} from './appCanvasConstants';
|
||||
import cx from 'classnames';
|
||||
import FreezeVersionInfo from '@/AppBuilder/Header/FreezeVersionInfo';
|
||||
import { computeCanvasContainerHeight } from '../_helpers/editorHelpers';
|
||||
import AutoComputeMobileLayoutAlert from './AutoComputeMobileLayoutAlert';
|
||||
import useAppDarkMode from '@/_hooks/useAppDarkMode';
|
||||
|
|
@ -25,18 +24,18 @@ import { DeleteWidgetConfirmation } from './DeleteWidgetConfirmation';
|
|||
import useSidebarMargin from './useSidebarMargin';
|
||||
import PagesSidebarNavigation from '../RightSideBar/PageSettingsTab/PageMenu/PagesSidebarNavigation';
|
||||
import { resolveReferences } from '@/_helpers/utils';
|
||||
import useRightSidebarMargin from './userRightSidebarMargin';
|
||||
import { DragGhostWidget } from './GhostWidgets';
|
||||
import AppCanvasBanner from '../../AppBuilder/Header/AppCanvasBanner';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode }) => {
|
||||
export const AppCanvas = ({ appId, switchDarkMode, darkMode }) => {
|
||||
const { moduleId, isModuleMode, appType } = useModuleContext();
|
||||
const canvasContainerRef = useRef();
|
||||
const handleCanvasContainerMouseUp = useStore((state) => state.handleCanvasContainerMouseUp, shallow);
|
||||
const canvasHeight = useStore((state) => state.appStore.modules[moduleId].canvasHeight);
|
||||
const creationMode = useStore((state) => state.appStore.modules[moduleId].app.creationMode);
|
||||
const environmentLoadingState = useStore(
|
||||
(state) => state.environmentLoadingState || state.loaderStore.modules[moduleId].isEditorLoading
|
||||
(state) => state.environmentLoadingState || state.loaderStore.modules[moduleId].isEditorLoading,
|
||||
shallow
|
||||
);
|
||||
const [canvasWidth, setCanvasWidth] = useState(getCanvasWidth(moduleId));
|
||||
const gridWidth = canvasWidth / NO_OF_GRIDS;
|
||||
|
|
@ -46,18 +45,14 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
const queryPanelHeight = useStore((state) => state?.queryPanel?.queryPanelHeight || 0);
|
||||
const isDraggingQueryPane = useStore((state) => state.queryPanel.isDraggingQueryPane, shallow);
|
||||
const { isAppDarkMode } = useAppDarkMode();
|
||||
const canvasBgColor = useStore((state) => state.getCanvasBackgroundColor('canvas', isAppDarkMode), shallow);
|
||||
const canvasContainerHeight = computeCanvasContainerHeight(queryPanelHeight, isDraggingQueryPane);
|
||||
const isAutoMobileLayout = useStore((state) => state.getIsAutoMobileLayout(), shallow);
|
||||
const setIsComponentLayoutReady = useStore((state) => state.setIsComponentLayoutReady, shallow);
|
||||
const canvasMaxWidth = useAppCanvasMaxWidth({ mode: currentMode });
|
||||
const editorMarginLeft = useSidebarMargin(canvasContainerRef);
|
||||
// const editorMarginRight = useRightSidebarMargin(canvasContainerRef);
|
||||
// const isPagesSidebarHidden = useStore((state) => state.getPagesSidebarVisibility('canvas'), shallow);
|
||||
const isSidebarOpen = useStore((state) => state.isSidebarOpen, shallow);
|
||||
const getPageId = useStore((state) => state.getCurrentPageId, shallow);
|
||||
const isRightSidebarOpen = useStore((state) => state.isRightSidebarOpen, shallow);
|
||||
const isRightSidebarPinned = useStore((state) => state.isRightSidebarPinned, shallow);
|
||||
const isSidebarOpen = useStore((state) => state.isSidebarOpen, shallow);
|
||||
const currentPageId = useStore((state) => state.modules[moduleId].currentPageId);
|
||||
const homePageId = useStore((state) => state.appStore.modules[moduleId].app.homePageId);
|
||||
|
||||
|
|
@ -65,10 +60,9 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
localStorage.getItem('isPagesSidebarPinned') !== 'false'
|
||||
);
|
||||
|
||||
const { globalSettings, pages, pageSettings, switchPage } = useStore(
|
||||
const { globalSettings, pageSettings, switchPage } = useStore(
|
||||
(state) => ({
|
||||
globalSettings: state.globalSettings,
|
||||
pages: state.modules.canvas.pages,
|
||||
pageSettings: state.pageSettings,
|
||||
switchPage: state.switchPage,
|
||||
}),
|
||||
|
|
@ -76,12 +70,10 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
);
|
||||
|
||||
const showHeader = !globalSettings?.hideHeader;
|
||||
const { definition: { styles = {}, properties = {} } = {} } = pageSettings ?? {};
|
||||
const { definition: { properties = {} } = {} } = pageSettings ?? {};
|
||||
const { position, disableMenu, showOnDesktop } = properties ?? {};
|
||||
const isPagesSidebarHidden = resolveReferences(disableMenu?.value);
|
||||
|
||||
const hideSidebar = isModuleMode || isPagesSidebarHidden || appType === 'module';
|
||||
|
||||
useEffect(() => {
|
||||
// Need to remove this if we shift setExposedVariable Logic outside of components
|
||||
// Currently present to run onLoadQueries after the component is mounted
|
||||
|
|
@ -90,7 +82,7 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
function handleResizeImmediate() {
|
||||
const _canvasWidth =
|
||||
moduleId === 'canvas'
|
||||
? document.getElementById('real-canvas')?.getBoundingClientRect()?.width
|
||||
|
|
@ -98,6 +90,8 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
if (_canvasWidth !== 0) setCanvasWidth(_canvasWidth);
|
||||
}
|
||||
|
||||
const handleResize = debounce(handleResizeImmediate, 300);
|
||||
|
||||
if (moduleId === 'canvas') {
|
||||
window.addEventListener('resize', handleResize);
|
||||
} else {
|
||||
|
|
@ -108,15 +102,17 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
return () => {
|
||||
if (elem) resizeObserver.unobserve(elem);
|
||||
resizeObserver.disconnect();
|
||||
handleResize.cancel();
|
||||
};
|
||||
}
|
||||
handleResize();
|
||||
handleResizeImmediate();
|
||||
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
handleResize.cancel();
|
||||
};
|
||||
}, [currentLayout, canvasMaxWidth, isViewerSidebarPinned, moduleId, isRightSidebarOpen]);
|
||||
|
||||
useEffect(() => {}, [isViewerSidebarPinned]);
|
||||
|
||||
const canvasContainerStyles = useMemo(() => {
|
||||
const canvasBgColor =
|
||||
currentMode === 'view'
|
||||
|
|
@ -211,7 +207,6 @@ export const AppCanvas = ({ appId, isViewer = false, switchDarkMode, darkMode })
|
|||
<PagesSidebarNavigation
|
||||
showHeader={showHeader}
|
||||
isMobileDevice={currentLayout === 'mobile'}
|
||||
pages={pages}
|
||||
currentPageId={currentPageId ?? homePageId}
|
||||
switchPage={switchPage}
|
||||
height={currentMode === 'edit' ? canvasContainerHeight : '100%'}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import { noop } from 'lodash';
|
|||
index - used to identify the subcontainer index
|
||||
onOptionChange - used to pass the onOptionChange function to the child components and pass the exposedValues to the parent component
|
||||
*/
|
||||
export const Container = React.memo(
|
||||
const Container = React.memo(
|
||||
({
|
||||
id,
|
||||
canvasWidth,
|
||||
|
|
@ -235,7 +235,7 @@ export const Container = React.memo(
|
|||
</div>
|
||||
);
|
||||
};
|
||||
const sortedComponents = useSortedComponents(components, currentLayout, id);
|
||||
const sortedComponents = useSortedComponents(components, currentLayout, id, moduleId);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -301,6 +301,7 @@ export const Container = React.memo(
|
|||
mode={currentMode}
|
||||
currentLayout={currentLayout}
|
||||
darkMode={darkMode}
|
||||
moduleId={moduleId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -309,3 +310,7 @@ export const Container = React.memo(
|
|||
);
|
||||
}
|
||||
);
|
||||
|
||||
Container.displayName = 'Container';
|
||||
|
||||
export { Container };
|
||||
|
|
|
|||
|
|
@ -871,7 +871,6 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
if (getHoveredComponentForGrid() !== e.target.id) {
|
||||
return false;
|
||||
}
|
||||
toggleRightSidebar();
|
||||
newDragParentId.current = boxList.find((box) => box.id === e.target.id)?.parent;
|
||||
e?.moveable?.controlBox?.removeAttribute('data-off-screen');
|
||||
|
||||
|
|
@ -983,6 +982,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
|||
useStore.getState().setDraggingComponentId(e.target.id);
|
||||
showGridLines();
|
||||
isDraggingRef.current = true;
|
||||
toggleRightSidebar();
|
||||
}
|
||||
const currentWidget = boxList.find((box) => box.id === e.target.id);
|
||||
const currentParentId =
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { renderTooltip } from '@/_helpers/appUtils';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import ErrorBoundary from '@/_ui/ErrorBoundary';
|
||||
import { BOX_PADDING } from './appCanvasConstants';
|
||||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
|
||||
const SHOULD_ADD_BOX_SHADOW_AND_VISIBILITY = [
|
||||
'Table',
|
||||
|
|
@ -48,13 +47,12 @@ const RenderWidget = ({
|
|||
widgetWidth,
|
||||
inCanvas = false,
|
||||
darkMode,
|
||||
moduleId,
|
||||
}) => {
|
||||
const { moduleId } = useModuleContext();
|
||||
const componentDefinition = useStore((state) => state.getComponentDefinition(id, moduleId), shallow);
|
||||
const component = useStore((state) => state.getComponentDefinition(id, moduleId)?.component, shallow);
|
||||
const getDefaultStyles = useStore((state) => state.debugger.getDefaultStyles, shallow);
|
||||
const adjustComponentPositions = useStore((state) => state.adjustComponentPositions, shallow);
|
||||
const componentCount = useStore((state) => state.getContainerChildrenMapping(id)?.length || 0, shallow);
|
||||
const component = componentDefinition?.component;
|
||||
const componentName = component?.name;
|
||||
const [key, setKey] = useState(Math.random());
|
||||
const resolvedProperties = useStore(
|
||||
|
|
@ -74,7 +72,7 @@ const RenderWidget = ({
|
|||
(state) => state.getResolvedComponent(id, subContainerIndex, moduleId)?.generalStyles,
|
||||
shallow
|
||||
);
|
||||
const unResolvedValidation = componentDefinition?.component?.definition?.validation || {};
|
||||
const unResolvedValidation = component?.definition?.validation || {};
|
||||
// const others = useStore((state) => state.getResolvedComponent(id, subContainerIndex)?.others, shallow);
|
||||
const updateDependencyValues = useStore((state) => state.updateDependencyValues, shallow);
|
||||
const validateWidget = useStore((state) => state.validateWidget, shallow);
|
||||
|
|
@ -153,7 +151,7 @@ const RenderWidget = ({
|
|||
useEffect(() => {
|
||||
setExposedVariable('id', id);
|
||||
}, []);
|
||||
if (!componentDefinition?.component) return null;
|
||||
if (!component) return null;
|
||||
|
||||
const disabledState = resolvedProperties?.disabledState;
|
||||
const loadingState = resolvedProperties?.loadingState;
|
||||
|
|
@ -219,4 +217,7 @@ const RenderWidget = ({
|
|||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
RenderWidget.displayName = 'RenderWidget';
|
||||
|
||||
export default memo(RenderWidget);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import { ConfigHandle } from './ConfigHandle/ConfigHandle';
|
|||
import { useGridStore } from '@/_stores/gridStore';
|
||||
import cx from 'classnames';
|
||||
import RenderWidget from './RenderWidget';
|
||||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import { NO_OF_GRIDS } from './appCanvasConstants';
|
||||
|
||||
const WidgetWrapper = memo(
|
||||
|
|
@ -21,8 +20,8 @@ const WidgetWrapper = memo(
|
|||
readOnly,
|
||||
mode,
|
||||
darkMode,
|
||||
moduleId,
|
||||
}) => {
|
||||
const { moduleId } = useModuleContext();
|
||||
const calculateMoveableBoxHeightWithId = useStore((state) => state.calculateMoveableBoxHeightWithId, shallow);
|
||||
const stylesDefinition = useStore(
|
||||
(state) => state.getComponentDefinition(id, moduleId)?.component?.definition?.styles,
|
||||
|
|
@ -127,6 +126,7 @@ const WidgetWrapper = memo(
|
|||
onOptionChange={onOptionChange}
|
||||
darkMode={darkMode}
|
||||
onOptionsChange={onOptionsChange}
|
||||
moduleId={moduleId}
|
||||
/>
|
||||
</div>
|
||||
<ResizeGhostWidget isResizing={isResizing} />
|
||||
|
|
@ -135,4 +135,6 @@ const WidgetWrapper = memo(
|
|||
}
|
||||
);
|
||||
|
||||
WidgetWrapper.displayName = 'WidgetWrapper';
|
||||
|
||||
export default WidgetWrapper;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ export const DragLayer = ({ index, component, isModuleTab = false, disabled = fa
|
|||
toggleRightSidebar(!isRightSidebarOpen);
|
||||
}
|
||||
setShowModuleBorder(true);
|
||||
} else {
|
||||
setShowModuleBorder(false);
|
||||
}
|
||||
}, [isDragging, setShowModuleBorder, isModuleEditor, toggleRightSidebar]);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import { Overlay, Popover } from 'react-bootstrap';
|
|||
|
||||
export const PagesSidebarNavigation = ({
|
||||
isMobileDevice,
|
||||
pages,
|
||||
currentPageId,
|
||||
switchPage,
|
||||
darkMode,
|
||||
|
|
@ -42,6 +41,7 @@ export const PagesSidebarNavigation = ({
|
|||
const appName = useStore((state) => state.appStore.modules[moduleId].app.appName);
|
||||
const isSidebarOpen = useStore((state) => state.isSidebarOpen);
|
||||
const isRightSidebarOpen = useStore((state) => state.isRightSidebarOpen, shallow);
|
||||
const pages = useStore((state) => state.modules.canvas.pages, shallow);
|
||||
|
||||
const navRef = useRef(null);
|
||||
const moreRef = useRef(null);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { ComponentConfigurationTab } from './ComponentConfigurationTab';
|
||||
import ComponentsManagerTab from './ComponentManagerTab';
|
||||
|
|
@ -13,13 +13,8 @@ export const RightSideBar = ({ darkMode }) => {
|
|||
|
||||
const activeTab = useStore((state) => state.activeRightSideBarTab);
|
||||
const isRightSidebarOpen = useStore((state) => state.isRightSidebarOpen);
|
||||
const setRightSidebarOpen = useStore((state) => state.setRightSidebarOpen);
|
||||
const isRightSidebarPinned = useStore((state) => state.isRightSidebarPinned);
|
||||
const setActiveRightSideBarTab = useStore((state) => state.setActiveRightSideBarTab);
|
||||
const [popoverContentHeight, setPopoverContentHeight] = useState(queryPanelHeight);
|
||||
|
||||
const sidebarRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDraggingQueryPane) {
|
||||
setPopoverContentHeight(
|
||||
|
|
@ -31,30 +26,10 @@ export const RightSideBar = ({ darkMode }) => {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [queryPanelHeight, isDraggingQueryPane]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const rigthSidebarMenu = document.querySelector('.right-sidebar-toggle');
|
||||
// function handleClickOutside(event) {
|
||||
// if (
|
||||
// sidebarRef.current &&
|
||||
// !sidebarRef.current.contains(event.target) &&
|
||||
// !rigthSidebarMenu.contains(event.target) &&
|
||||
// !isRightSidebarPinned
|
||||
// ) {
|
||||
// setRightSidebarOpen(false);
|
||||
// setActiveRightSideBarTab(null);
|
||||
// }
|
||||
// }
|
||||
|
||||
// document.addEventListener('mousedown', handleClickOutside);
|
||||
// return () => {
|
||||
// document.removeEventListener('mousedown', handleClickOutside);
|
||||
// };
|
||||
// }, [isRightSidebarPinned, setActiveRightSideBarTab, setRightSidebarOpen]);
|
||||
|
||||
if (!isRightSidebarOpen) return null;
|
||||
|
||||
return (
|
||||
<div ref={sidebarRef} className="sub-section">
|
||||
<div className="sub-section">
|
||||
<div
|
||||
style={{ height: `${popoverContentHeight}vh`, overflow: 'auto' }}
|
||||
className={cx('editor-sidebar', { 'dark-theme theme-dark': darkMode })}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ const MobileHeader = ({
|
|||
appName,
|
||||
changeToDarkMode,
|
||||
darkMode,
|
||||
pages,
|
||||
currentPageId,
|
||||
switchPage,
|
||||
setAppDefinitionFromVersion,
|
||||
|
|
@ -61,7 +60,6 @@ const MobileHeader = ({
|
|||
|
||||
const _renderMobileNavigationMenu = () => (
|
||||
<MobileNavigationMenu
|
||||
pages={pages}
|
||||
currentPageId={currentPageId}
|
||||
switchPage={switchPage}
|
||||
darkMode={darkMode}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@ import { Link } from 'react-router-dom';
|
|||
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
|
||||
import OverflowTooltip from '@/_components/OverflowTooltip';
|
||||
|
||||
const RenderGroup = ({ pages, pageGroup, currentPage, darkMode, handlepageSwitch, currentPageId, icon }) => {
|
||||
const RenderGroup = ({ pageGroup, currentPage, darkMode, handlepageSwitch, currentPageId, icon }) => {
|
||||
const { moduleId } = useModuleContext();
|
||||
const [isExpanded, setIsExpanded] = useState(true);
|
||||
const groupActive = currentPage.pageGroupId === pageGroup?.id;
|
||||
const homePageId = useStore((state) => state.appStore.modules[moduleId].app.homePageId);
|
||||
const pages = useStore((state) => state.modules[moduleId].pages);
|
||||
const handleToggle = () => {
|
||||
setIsExpanded(!isExpanded);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import { ModuleProvider } from '@/AppBuilder/_contexts/ModuleContext';
|
|||
import { getPatToken, setPatToken } from '@/AppBuilder/EmbedApp';
|
||||
import Spinner from '@/_ui/Spinner';
|
||||
import { checkIfLicenseNotValid } from '@/_helpers/appUtils';
|
||||
import toast from 'react-hot-toast';
|
||||
import TooljetBanner from '../../Editor/Viewer/TooljetBanner';
|
||||
|
||||
export const Viewer = ({
|
||||
|
|
@ -43,7 +42,6 @@ export const Viewer = ({
|
|||
currentCanvasWidth,
|
||||
currentPageId,
|
||||
globalSettings,
|
||||
pages,
|
||||
pageSettings,
|
||||
updateCanvasHeight,
|
||||
appName,
|
||||
|
|
@ -64,9 +62,6 @@ export const Viewer = ({
|
|||
homePageId: state.appStore.modules[moduleId].app.homepageId,
|
||||
currentPageId: state.modules[moduleId].currentPageId,
|
||||
globalSettings: state.globalSettings,
|
||||
pages: state.modules[moduleId].pages,
|
||||
modules: state.modules,
|
||||
globalSettingsChanged: state.globalSettingsChanged,
|
||||
pageSettings: state.pageSettings,
|
||||
updateCanvasHeight: state.updateCanvasBottomHeight,
|
||||
isMaintenanceOn: state.appStore.modules[moduleId].app.isMaintenanceOn,
|
||||
|
|
@ -79,7 +74,6 @@ export const Viewer = ({
|
|||
|
||||
const getCurrentPageComponents = useStore((state) => state.getCurrentPageComponents(moduleId), shallow);
|
||||
const currentPageComponents = useMemo(() => getCurrentPageComponents, [getCurrentPageComponents]);
|
||||
const changeDarkMode = useStore((state) => state.changeDarkMode);
|
||||
const isPagesSidebarHidden = useStore((state) => state.getPagesSidebarVisibility('canvas'), shallow);
|
||||
const canvasBgColor = useStore((state) => state.getCanvasBackgroundColor('canvas', darkMode), shallow);
|
||||
const deviceWindowWidth = window.screen.width - 5;
|
||||
|
|
@ -106,7 +100,7 @@ export const Viewer = ({
|
|||
}, [isSidebarPinned]);
|
||||
|
||||
const { definition: { properties = {} } = {} } = pageSettings ?? {};
|
||||
const { position, hideHeader } = properties ?? {};
|
||||
const { position } = properties ?? {};
|
||||
|
||||
const canvasRef = useRef(null);
|
||||
const isMobilePreviewMode = selectedVersion?.id && currentLayout === 'mobile';
|
||||
|
|
@ -160,7 +154,6 @@ export const Viewer = ({
|
|||
isAppLoaded={isAppLoaded}
|
||||
appName={appName}
|
||||
darkMode={darkMode}
|
||||
pages={pages}
|
||||
currentPageId={currentPageId ?? homePageId}
|
||||
showViewerNavigation={!hideSidebar}
|
||||
handleAppEnvironmentChanged={handleAppEnvironmentChanged}
|
||||
|
|
@ -176,7 +169,6 @@ export const Viewer = ({
|
|||
showHeader={showHeader}
|
||||
appName={appName}
|
||||
darkMode={darkMode}
|
||||
pages={pages}
|
||||
currentPageId={currentPageId ?? homePageId}
|
||||
showViewerNavigation={!hideSidebar}
|
||||
handleAppEnvironmentChanged={handleAppEnvironmentChanged}
|
||||
|
|
@ -260,7 +252,6 @@ export const Viewer = ({
|
|||
showHeader={showHeader && isAppLoaded}
|
||||
appName={appName}
|
||||
darkMode={darkMode}
|
||||
pages={pages}
|
||||
currentPageId={currentPageId ?? homePageId}
|
||||
showViewerNavigation={!hideSidebar}
|
||||
handleAppEnvironmentChanged={handleAppEnvironmentChanged}
|
||||
|
|
|
|||
|
|
@ -5,21 +5,17 @@ import {
|
|||
appsService,
|
||||
appVersionService,
|
||||
dataqueryService,
|
||||
datasourceService,
|
||||
orgEnvironmentConstantService,
|
||||
authenticationService,
|
||||
orgEnvironmentVariableService,
|
||||
customStylesService,
|
||||
} from '@/_services';
|
||||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { useEnvironmentsAndVersionsStore } from '@/_stores/environmentsAndVersionsStore';
|
||||
import { camelCase, cloneDeep, isEmpty, kebabCase, mapKeys, noop, rest } from 'lodash';
|
||||
import { camelCase, isEmpty, mapKeys, noop } from 'lodash';
|
||||
import { usePrevious } from '@dnd-kit/utilities';
|
||||
import { deepCamelCase } from '@/_helpers/appUtils';
|
||||
import { useEventActions } from '../_stores/slices/eventsSlice';
|
||||
import useRouter from '@/_hooks/use-router';
|
||||
import { extractEnvironmentConstantsFromConstantsList, navigate } from '../_utils/misc';
|
||||
import { getWorkspaceId } from '@/_helpers/utils';
|
||||
import { extractEnvironmentConstantsFromConstantsList } from '../_utils/misc';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
import { fetchAndSetWindowTitle, pageTitles, retrieveWhiteLabelText } from '@white-label/whiteLabelling';
|
||||
import { initEditorWalkThrough } from '@/AppBuilder/_helpers/createWalkThrough';
|
||||
|
|
@ -30,7 +26,6 @@ import { getPreviewQueryParams } from '@/_helpers/routes';
|
|||
import { useLocation, useMatch, useParams } from 'react-router-dom';
|
||||
import { useMounted } from '@/_hooks/use-mount';
|
||||
import useThemeAccess from './useThemeAccess';
|
||||
import { handleError } from '@/_helpers/handleAppAccess';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
/**
|
||||
|
|
@ -67,13 +62,13 @@ const useAppData = (
|
|||
moduleMode = false
|
||||
) => {
|
||||
const mounted = useMounted();
|
||||
const initModules = useStore((state) => state.initModules, shallow);
|
||||
const initModules = useStore((state) => state.initModules);
|
||||
moduleMode && !mounted && initModules(moduleId);
|
||||
const { state } = useLocation();
|
||||
const [currentSession, setCurrentSession] = useState();
|
||||
|
||||
const setEditorLoading = useStore((state) => state.setEditorLoading);
|
||||
const setApp = useStore((state) => state.setApp);
|
||||
const app = useStore((state) => state.appStore.modules[moduleId].app);
|
||||
const user = useStore((state) => state.user);
|
||||
const setCurrentVersionId = useStore((state) => state.setCurrentVersionId);
|
||||
const currentVersionId = useStore((state) => state.currentVersionId);
|
||||
|
|
@ -90,10 +85,6 @@ const useAppData = (
|
|||
const setPreviewData = useStore((state) => state.queryPanel.setPreviewData);
|
||||
// const fetchDataSources = useStore((state) => state.fetchDataSources);
|
||||
const fetchGlobalDataSources = useStore((state) => state.fetchGlobalDataSources);
|
||||
const previousVersion = usePrevious(currentVersionId);
|
||||
const events = useStore((state) => state.eventsSlice.module[moduleId]?.events || []);
|
||||
const pages = useStore((state) => state.modules[moduleId]?.pages || []);
|
||||
const currentPageId = useStore((state) => state.modules[moduleId].currentPageId);
|
||||
const setResolvedConstants = useStore((state) => state.setResolvedConstants);
|
||||
const setSecrets = useStore((state) => state.setSecrets);
|
||||
const setQueryMapping = useStore((state) => state.setQueryMapping);
|
||||
|
|
@ -115,23 +106,17 @@ const useAppData = (
|
|||
const cleanUpStore = useStore((state) => state.cleanUpStore);
|
||||
const selectedEnvironment = useStore((state) => state.selectedEnvironment);
|
||||
const setIsEditorFreezed = useStore((state) => state.setIsEditorFreezed);
|
||||
const appMode = useStore((state) => state.globalSettings.appMode);
|
||||
const selectedTheme = useStore((state) => state.globalSettings.theme);
|
||||
const previousEnvironmentId = usePrevious(selectedEnvironment?.id);
|
||||
const isComponentLayoutReady = useStore((state) => state.appStore.modules[moduleId].isComponentLayoutReady, shallow);
|
||||
const pageSwitchInProgress = useStore((state) => state.pageSwitchInProgress);
|
||||
const setPageSwitchInProgress = useStore((state) => state.setPageSwitchInProgress);
|
||||
const selectedVersion = useStore((state) => state.selectedVersion);
|
||||
const setIsPublicAccess = useStore((state) => state.setIsPublicAccess);
|
||||
|
||||
const setModulesIsLoading = useStore((state) => state?.setModulesIsLoading ?? noop, shallow);
|
||||
const setModulesList = useStore((state) => state?.setModulesList ?? noop, shallow);
|
||||
const setModulesIsLoading = useStore((state) => state?.setModulesIsLoading ?? noop);
|
||||
const setModulesList = useStore((state) => state?.setModulesList ?? noop);
|
||||
const setModuleDefinition = useStore((state) => state?.setModuleDefinition ?? noop);
|
||||
const getModuleDefinition = useStore((state) => state?.getModuleDefinition ?? noop);
|
||||
const deleteModuleDefinition = useStore((state) => state?.deleteModuleDefinition ?? noop);
|
||||
|
||||
const themeAccess = useThemeAccess();
|
||||
const themeChanged = useStore((state) => state.themeChanged);
|
||||
const detectThemeChange = useStore((state) => state.detectThemeChange);
|
||||
const setConversation = useStore((state) => state.ai?.setConversation);
|
||||
const setDocsConversation = useStore((state) => state.ai?.setDocsConversation);
|
||||
|
|
@ -142,10 +127,18 @@ const useAppData = (
|
|||
const toggleLeftSidebar = useStore((state) => state.toggleLeftSidebar);
|
||||
const pathParams = useParams();
|
||||
const slug = moduleMode ? '' : pathParams?.slug;
|
||||
|
||||
const previousVersion = usePrevious(currentVersionId);
|
||||
const events = useStore((state) => state.eventsSlice.module[moduleId]?.events || []);
|
||||
const currentPageId = useStore((state) => state.modules[moduleId].currentPageId);
|
||||
const appMode = useStore((state) => state.globalSettings.appMode);
|
||||
const selectedTheme = useStore((state) => state.globalSettings.theme);
|
||||
const previousEnvironmentId = usePrevious(selectedEnvironment?.id);
|
||||
const isComponentLayoutReady = useStore((state) => state.appStore.modules[moduleId].isComponentLayoutReady);
|
||||
const pageSwitchInProgress = useStore((state) => state.pageSwitchInProgress);
|
||||
const licenseStatus = useStore((state) => state.isLicenseValid());
|
||||
|
||||
|
||||
const match = useMatch('/applications/:slug/:pageHandle');
|
||||
const organizationId = useStore((state) => state.appStore.modules[moduleId].app.organizationId);
|
||||
const appName = useStore((state) => state.appStore.modules[moduleId].app.name);
|
||||
|
||||
const location = useRouter().location;
|
||||
|
||||
|
|
@ -542,10 +535,7 @@ const useAppData = (
|
|||
useEffect(() => {
|
||||
if (isComponentLayoutReady) {
|
||||
runOnLoadQueries(moduleId).then(() => {
|
||||
let startingPage = pages.find((page) => page.id === currentPageId);
|
||||
const currentPageEvents = events.filter(
|
||||
(event) => event.target === 'page' && event.sourceId === startingPage.id
|
||||
);
|
||||
const currentPageEvents = events.filter((event) => event.target === 'page' && event.sourceId === currentPageId);
|
||||
handleEvent('onPageLoad', currentPageEvents, {});
|
||||
});
|
||||
}
|
||||
|
|
@ -555,12 +545,12 @@ const useAppData = (
|
|||
if (moduleId) return;
|
||||
fetchAndSetWindowTitle({
|
||||
page: pageTitles.EDITOR,
|
||||
appName: app.appName,
|
||||
appName: appName,
|
||||
mode: mode,
|
||||
isReleased: isReleasedVersionId,
|
||||
licenseStatus: licenseStatus,
|
||||
});
|
||||
}, [app.appName, isReleasedVersionId, licenseStatus, mode, moduleId]);
|
||||
}, [appName, isReleasedVersionId, licenseStatus, mode, moduleId]);
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
|
|
@ -655,7 +645,7 @@ const useAppData = (
|
|||
}
|
||||
});
|
||||
// fetchDataSources(currentVersionId, selectedEnvironment.id);
|
||||
fetchGlobalDataSources(app.organizationId, currentVersionId, selectedEnvironment.id);
|
||||
fetchGlobalDataSources(organizationId, currentVersionId, selectedEnvironment.id);
|
||||
setResolvedConstants(orgConstants);
|
||||
setSecrets(orgSecrets);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,43 @@ import { useMemo, useRef } from 'react';
|
|||
import useStore from '@/AppBuilder/_stores/store';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
const useSortedComponents = (components, currentLayout, id) => {
|
||||
const useSortedComponents = (components, currentLayout, id, moduleId) => {
|
||||
const getCurrentPageComponents = useStore((state) => state.getCurrentPageComponents, shallow);
|
||||
const reorderContainerChildren = useStore((state) => state.reorderContainerChildren, shallow);
|
||||
// Only subscribe to reorderContainerChildren when it's relevant to this specific container
|
||||
const reorderContainerChildren = useStore((state) => {
|
||||
const { containerId, triggerUpdate } = state.reorderContainerChildren;
|
||||
// Only return an updated trigger when this specific container is being reordered
|
||||
// Return a stable value for other containers to prevent unnecessary re-renders
|
||||
if (containerId === id && moduleId === 'canvas') {
|
||||
return { triggerUpdate, containerId, shouldReorder: true };
|
||||
}
|
||||
return { triggerUpdate: 0, containerId: null, shouldReorder: false };
|
||||
}, shallow);
|
||||
|
||||
const prevForceUpdateRef = useRef(0);
|
||||
const prevComponentsOrder = useRef(components);
|
||||
|
||||
// Function to sort the components based on position in container for tab navigation
|
||||
const sortedComponents = useMemo(() => {
|
||||
const { triggerUpdate, containerId } = reorderContainerChildren;
|
||||
const { triggerUpdate, shouldReorder } = reorderContainerChildren;
|
||||
|
||||
// If a forced update occurred for a different container, return the previous order
|
||||
// Always recalculate if components array has changed (new component added/removed)
|
||||
const componentsChanged =
|
||||
prevComponentsOrder.current.length !== components.length ||
|
||||
!components.every((comp) => prevComponentsOrder.current.includes(comp));
|
||||
|
||||
// If a forced update occurred for this container, recalculate order
|
||||
const isForcedUpdate = prevForceUpdateRef.current !== triggerUpdate;
|
||||
if (isForcedUpdate) {
|
||||
prevForceUpdateRef.current = triggerUpdate;
|
||||
if (containerId !== id) {
|
||||
return prevComponentsOrder.current;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip recalculation only if:
|
||||
// 1. This container is not the target of reorder
|
||||
// 2. Components haven't changed
|
||||
// 3. No forced update occurred
|
||||
if (!shouldReorder && !componentsChanged && !isForcedUpdate) {
|
||||
return prevComponentsOrder.current;
|
||||
}
|
||||
|
||||
const currentPageComponents = getCurrentPageComponents();
|
||||
|
|
@ -41,7 +61,7 @@ const useSortedComponents = (components, currentLayout, id) => {
|
|||
prevComponentsOrder.current = newComponentsOrder;
|
||||
return newComponentsOrder;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [components, currentLayout, reorderContainerChildren.triggerUpdate, id]);
|
||||
}, [components, currentLayout, reorderContainerChildren.triggerUpdate, reorderContainerChildren.shouldReorder]);
|
||||
|
||||
return sortedComponents;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ const initialState = {
|
|||
isRightSidebarPinned: false,
|
||||
};
|
||||
|
||||
export const createRightSideBarSlice = (set) => ({
|
||||
export const createRightSideBarSlice = (set, get) => ({
|
||||
...initialState,
|
||||
setActiveRightSideBarTab: (tab) => set(() => ({ activeRightSideBarTab: tab }), false, 'setActiveRightSideBarTab'),
|
||||
toggleRightSidebar: () => set((state) => ({ isRightSidebarOpen: !state.isRightSidebarOpen })),
|
||||
setRightSidebarOpen: (open) => set(() => ({ isRightSidebarOpen: open })),
|
||||
toggleRightSidebarPin: () => set((state) => ({ isRightSidebarPinned: !state.isRightSidebarPinned })),
|
||||
toggleRightSidebar: () =>
|
||||
set((state) => ({ isRightSidebarOpen: !state.isRightSidebarOpen }), false, 'toggleRightSidebar'),
|
||||
setRightSidebarOpen: (open) => set(() => ({ isRightSidebarOpen: open }), false, 'setRightSidebarOpen'),
|
||||
toggleRightSidebarPin: () =>
|
||||
set((state) => ({ isRightSidebarPinned: !state.isRightSidebarPinned }), false, 'toggleRightSidebarPin'),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { useRef, useEffect } from 'react';
|
||||
|
||||
function useRenderCount(componentName) {
|
||||
function useRenderCount(componentName, options = {}) {
|
||||
const renderCountRef = useRef(0);
|
||||
|
||||
renderCountRef.current++;
|
||||
|
||||
useEffect(() => {
|
||||
console.log(`${componentName} rendered: ${renderCountRef.current} times`);
|
||||
console.log(`here--- ${componentName} rendered: ${renderCountRef.current} times `, options);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [renderCountRef.current, componentName]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue