import React, { useState, useRef, useCallback, useEffect } from 'react'; import { useEventListener } from '@/_hooks/use-event-listener'; import { Tooltip } from 'react-tooltip'; import { QueryDataPane } from './QueryDataPane'; import QueryManager from '../QueryManager/QueryManager'; import useWindowResize from '@/_hooks/useWindowResize'; import { useQueryPanelActions, useQueryPanelStore } from '@/_stores/queryPanelStore'; import { useDataQueriesStore, useDataQueries } from '@/_stores/dataQueriesStore'; import Maximize from '@/_ui/Icon/solidIcons/Maximize'; import { isEmpty, isEqual } from 'lodash'; import { ButtonSolid } from '@/_ui/AppButton/AppButton'; import cx from 'classnames'; import { deepClone } from '@/_helpers/utilities/utils.helpers'; const QueryPanel = ({ dataQueriesChanged, fetchDataQueries, darkMode, allComponents, appId, appDefinition, editorRef, onQueryPaneDragging, handleQueryPaneExpanding, }) => { const { updateQueryPanelHeight } = useQueryPanelActions(); const dataQueries = useDataQueries(); const queryManagerPreferences = useRef( JSON.parse(localStorage.getItem('queryManagerPreferences')) ?? { current: { isExpanded: true, queryPanelHeight: 100, }, } ); const queryPaneRef = useRef(null); const [isExpanded, setExpanded] = useState(queryManagerPreferences.current?.isExpanded ?? true); const [isDragging, setDragging] = useState(false); const [height, setHeight] = useState( queryManagerPreferences.current?.queryPanelHeight > 95 ? 50 : queryManagerPreferences.current?.queryPanelHeight ?? 70 ); const [isTopOfQueryPanel, setTopOfQueryPanel] = useState(false); const [windowSize, isWindowResizing] = useWindowResize(); useEffect(() => { const queryPanelStoreListner = useQueryPanelStore.subscribe(({ selectedQuery }, prevState) => { if (isEmpty(prevState?.selectedQuery) || isEmpty(selectedQuery)) { return; } if (prevState?.selectedQuery?.id !== selectedQuery.id) { return; } //removing updated_at since this value changes whenever the data is updated in the BE const formattedQuery = deepClone(selectedQuery); delete formattedQuery.updated_at; const formattedPrevQuery = deepClone(prevState?.selectedQuery || {}); delete formattedPrevQuery.updated_at; if (!isEqual(formattedQuery, formattedPrevQuery)) { useDataQueriesStore.getState().actions.saveData(selectedQuery); } }); return queryPanelStoreListner; }, []); useEffect(() => { handleQueryPaneExpanding(isExpanded); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isExpanded]); useEffect(() => { onQueryPaneDragging(isDragging); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isDragging]); useEffect(() => { updateQueryPanelHeight(queryPaneRef?.current?.offsetHeight); if (isWindowResizing) { onQueryPaneDragging(true); } else { onQueryPaneDragging(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [windowSize.height, isExpanded, isWindowResizing]); const onMouseUp = () => { setDragging(false); /* Updated queryPanelHeight here instead of using a useEffect on height to avoid continuous rerendering during window dragging which causes screen to act sluggish */ updateQueryPanelHeight(queryPaneRef?.current?.offsetHeight); }; const onMouseDown = () => { isTopOfQueryPanel && setDragging(true); }; const onMouseMove = (e) => { if (queryPaneRef.current) { const componentTop = Math.round(queryPaneRef.current.getBoundingClientRect().top); const clientY = e.clientY; if ((clientY >= componentTop) & (clientY <= componentTop + 5)) { setTopOfQueryPanel(true); } else if (isTopOfQueryPanel) { setTopOfQueryPanel(false); } if (isDragging) { let height = (clientY / window.innerHeight) * 100, maxLimitReached = false; if (height > 94) { height = 30; maxLimitReached = true; } if (height < 4.5) height = 4.5; queryManagerPreferences.current = { ...queryManagerPreferences.current, queryPanelHeight: height, isExpanded: !maxLimitReached, }; localStorage.setItem('queryManagerPreferences', JSON.stringify(queryManagerPreferences.current)); setExpanded(!maxLimitReached); setHeight(height); } } }; useEventListener('mousemove', onMouseMove); useEventListener('mouseup', onMouseUp); const toggleQueryEditor = useCallback(() => { queryManagerPreferences.current = { ...queryManagerPreferences.current, isExpanded: !isExpanded }; localStorage.setItem('queryManagerPreferences', JSON.stringify(queryManagerPreferences.current)); if (isExpanded) { updateQueryPanelHeight(95); } else { updateQueryPanelHeight(queryPaneRef?.current?.offsetHeight); } setExpanded(!isExpanded); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isExpanded]); const updateDataQueries = useCallback(() => { dataQueriesChanged(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return (