diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx index b1d7f3fc9e5594e7f7897a8b48383fec0d990bfb..3e93ec3dab142e37f48ba3fe3bdf9999893ad42f 100644 --- a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx @@ -25,9 +25,7 @@ import ReactFlow, { isNode, useReactFlow, } from 'reactflow'; -import { Dialog, DialogClose, DialogContent } from '../../components/layout/Dialog'; -import { Button } from '../../components/buttons'; -import { ControlContainer } from '../../components/controls'; +import { Dialog, DialogContent } from '../../components/layout/Dialog'; import { addError } from '../../data-access/store/configSlice'; import { toSchemaGraphology } from '../../data-access/store/schemaSlice'; import { LayoutFactory } from '../../graph-layout'; @@ -38,25 +36,20 @@ import { dragPillStarted, movePillTo } from '../pills/dragging/dragPill'; import styles from './querybuilder.module.scss'; import { QueryBuilderLogicPillsPanel } from './querysidepanel/QueryBuilderLogicPillsPanel'; import { QueryBuilderRelatedNodesPanel } from './querysidepanel/QueryBuilderRelatedNodesPanel'; -import { QueryMLDialog } from './querysidepanel/QueryMLDialog'; import { ConnectingNodeDataI } from './utils/connectorDrop'; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../components/tooltip'; import { resultSetFocus } from '../../data-access/store/interactionSlice'; import { QueryBuilderDispatcherContext } from './QueryBuilderDispatcher'; -import { Popover, PopoverContent, PopoverTrigger } from '../../components/layout/Popover'; -import { QuerySettings } from './querysidepanel/QuerySettings'; +import { QueryBuilderNav, QueryBuilderToggleSettings } from './QueryBuilderNav'; export type QueryBuilderProps = { onRunQuery?: () => void; }; -type SettingsPanel = 'settings' | 'ml' | 'logic' | 'relatedNodes' | undefined; - /** * This is the main querybuilder component. It is responsible for holding all pills and fire off the visual part of the querybuilder panel logic */ export const QueryBuilderInner = (props: QueryBuilderProps) => { - const [toggleSettings, setToggleSettings] = useState<SettingsPanel>(); + const [toggleSettings, setToggleSettings] = useState<QueryBuilderToggleSettings>(); const reactFlowWrapper = useRef<HTMLDivElement>(null); const queryBuilderSettings = useQuerybuilderSettings(); @@ -109,13 +102,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { setTimeout(() => reactFlow.fitView(), 0); }; - /** - * Clears all nodes in the graph. - */ - function clearAllNodes() { - dispatch(clearQB()); - } - /** * Clears all nodes in the graph. * TODO: only works if the node is clicked and not moved (maybe use onSelectionChange) @@ -537,163 +523,19 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { }} > <div ref={reactFlowWrapper} className="h-full w-full flex flex-col"> - <div className="sticky shrink-0 top-0 flex items-stretch justify-between h-7 bg-secondary-100 border-b border-secondary-200 max-w-full"> - <div className="flex items-center"> - <h1 className="text-xs font-semibold text-secondary-600 px-2 truncate">Query builder</h1> - </div> - <div className="sticky right-0 px-0.5 ml-auto items-center flex truncate"> - <ControlContainer> - <TooltipProvider delayDuration={0}> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-fullscreen]" - onClick={fitView} - /> - </TooltipTrigger> - <TooltipContent> - <p>Fit to screen</p> - </TooltipContent> - </Tooltip> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-delete]" - onClick={() => clearAllNodes()} - /> - </TooltipTrigger> - <TooltipContent> - <p>Clear query panel</p> - </TooltipContent> - </Tooltip> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-camera-alt]" - onClick={(event) => { - event.stopPropagation(); - }} - /> - </TooltipTrigger> - <TooltipContent> - <p>Capture screen</p> - </TooltipContent> - </Tooltip> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-import-export]" - onClick={(event) => { - event.stopPropagation(); - applyLayout(); - }} - /> - </TooltipTrigger> - <TooltipContent> - <p>Layouts</p> - </TooltipContent> - </Tooltip> - <Popover> - <PopoverTrigger> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-settings]" - className="query-settings" - /> - </TooltipTrigger> - <TooltipContent> - <p>Query builder settings</p> - </TooltipContent> - </Tooltip> - </PopoverTrigger> - <PopoverContent> - <QuerySettings /> - </PopoverContent> - </Popover> - <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-cached]" - onClick={(event) => { - event.stopPropagation(); - if (props.onRunQuery) props.onRunQuery(); - }} - /> - </TooltipTrigger> - <TooltipContent> - <p>Rerun query</p> - </TooltipContent> - </Tooltip> - <Tooltip> - <TooltipTrigger asChild> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-difference]" - onClick={(event) => { - event.stopPropagation(); - if (toggleSettings === 'logic') setToggleSettings(undefined); - else setToggleSettings('logic'); - }} - /> - </TooltipTrigger> - <TooltipContent disabled={toggleSettings === 'logic'}> - <p>Logic settings</p> - </TooltipContent> - </Tooltip> - <Popover> - <PopoverTrigger> - <Tooltip> - <TooltipTrigger> - <Button variantType="secondary" variant="ghost" size="xs" iconComponent="icon-[ic--baseline-lightbulb]" /> - </TooltipTrigger> - <TooltipContent disabled={toggleSettings === 'ml'}> - <p>Machine learning</p> - </TooltipContent> - </Tooltip> - </PopoverTrigger> - <PopoverContent> - <QueryMLDialog /> - </PopoverContent> - </Popover> - {/* <Tooltip> - <TooltipTrigger> - <Button - variantType="secondary" - variant="ghost" - size="xs" - iconComponent="icon-[ic--baseline-drive-file-move]" - onClick={() => onAddSchemaToQueryBuilder()} - /> - </TooltipTrigger> - <TooltipContent> - <p>Query All Data</p> - </TooltipContent> - </Tooltip> */} - </TooltipProvider> - </ControlContainer> - </div> - </div> + <QueryBuilderNav + toggleSettings={toggleSettings} + onFitView={fitView} + onApplyLayout={() => applyLayout()} + onRunQuery={() => { + if (props.onRunQuery) props.onRunQuery(); + }} + onScreenshot={() => {}} + onLogic={() => { + if (toggleSettings === 'logic') setToggleSettings(undefined); + else setToggleSettings('logic'); + }} + /> <Dialog open={toggleSettings === 'logic'} diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d0b39b72d17196b8d5d3856db19e3dea4feeb473 --- /dev/null +++ b/libs/shared/lib/querybuilder/panel/QueryBuilderNav.tsx @@ -0,0 +1,177 @@ +import React from 'react'; +import { ControlContainer, TooltipProvider, Tooltip, TooltipTrigger, Button, TooltipContent } from '../../components'; +import { Popover, PopoverTrigger, PopoverContent } from '../../components/layout/Popover'; +import { useAppDispatch } from '../../data-access'; +import { clearQB } from '../../data-access/store/querybuilderSlice'; +import { QueryMLDialog } from './querysidepanel/QueryMLDialog'; +import { QuerySettings } from './querysidepanel/QuerySettings'; + +export type QueryBuilderToggleSettings = 'settings' | 'ml' | 'logic' | 'relatedNodes' | undefined; + +export type QueryBuilderNavProps = { + toggleSettings: QueryBuilderToggleSettings; + onFitView: () => void; + onApplyLayout: () => void; + onRunQuery: () => void; + onScreenshot: () => void; + onLogic: () => void; +}; + +export const QueryBuilderNav = (props: QueryBuilderNavProps) => { + const dispatch = useAppDispatch(); + + /** + * Clears all nodes in the graph. + */ + function clearAllNodes() { + dispatch(clearQB()); + } + + return ( + <div className="sticky shrink-0 top-0 flex items-stretch justify-between h-7 bg-secondary-100 border-b border-secondary-200 max-w-full"> + <div className="flex items-center"> + <h1 className="text-xs font-semibold text-secondary-600 px-2 truncate">Query builder</h1> + </div> + <div className="sticky right-0 px-0.5 ml-auto items-center flex truncate"> + <ControlContainer> + <TooltipProvider delayDuration={0}> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-fullscreen]" + onClick={props.onFitView} + /> + </TooltipTrigger> + <TooltipContent> + <p>Fit to screen</p> + </TooltipContent> + </Tooltip> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-delete]" + onClick={() => clearAllNodes()} + /> + </TooltipTrigger> + <TooltipContent> + <p>Clear query panel</p> + </TooltipContent> + </Tooltip> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-camera-alt]" + onClick={props.onScreenshot} + /> + </TooltipTrigger> + <TooltipContent> + <p>Capture screen</p> + </TooltipContent> + </Tooltip> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-import-export]" + onClick={props.onApplyLayout} + /> + </TooltipTrigger> + <TooltipContent> + <p>Layouts</p> + </TooltipContent> + </Tooltip> + <Popover> + <PopoverTrigger> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-settings]" + className="query-settings" + /> + </TooltipTrigger> + <TooltipContent> + <p>Query builder settings</p> + </TooltipContent> + </Tooltip> + </PopoverTrigger> + <PopoverContent> + <QuerySettings /> + </PopoverContent> + </Popover> + <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-cached]" + onClick={props.onRunQuery} + /> + </TooltipTrigger> + <TooltipContent> + <p>Rerun query</p> + </TooltipContent> + </Tooltip> + <Tooltip> + <TooltipTrigger asChild> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-difference]" + onClick={props.onLogic} + /> + </TooltipTrigger> + <TooltipContent disabled={props.toggleSettings === 'logic'}> + <p>Logic settings</p> + </TooltipContent> + </Tooltip> + <Popover> + <PopoverTrigger> + <Tooltip> + <TooltipTrigger> + <Button variantType="secondary" variant="ghost" size="xs" iconComponent="icon-[ic--baseline-lightbulb]" /> + </TooltipTrigger> + <TooltipContent disabled={props.toggleSettings === 'ml'}> + <p>Machine learning</p> + </TooltipContent> + </Tooltip> + </PopoverTrigger> + <PopoverContent> + <QueryMLDialog /> + </PopoverContent> + </Popover> + {/* <Tooltip> + <TooltipTrigger> + <Button + variantType="secondary" + variant="ghost" + size="xs" + iconComponent="icon-[ic--baseline-drive-file-move]" + onClick={() => onAddSchemaToQueryBuilder()} + /> + </TooltipTrigger> + <TooltipContent> + <p>Query All Data</p> + </TooltipContent> + </Tooltip> */} + </TooltipProvider> + </ControlContainer> + </div> + </div> + ); +};