mirror of
				https://github.com/chartdb/chartdb.git
				synced 2025-11-03 05:23:26 +00:00 
			
		
		
		
	* feat: add zoom navigation buttons to canvas filter for tables and areas * fix * fix --------- Co-authored-by: Guy Ben-Aharon <baguy3@gmail.com>
		
			
				
	
	
		
			143 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { useCallback } from 'react';
 | 
						|
import { useReactFlow } from '@xyflow/react';
 | 
						|
import { useLayout } from '@/hooks/use-layout';
 | 
						|
import { useBreakpoint } from '@/hooks/use-breakpoint';
 | 
						|
 | 
						|
interface FocusOptions {
 | 
						|
    select?: boolean;
 | 
						|
}
 | 
						|
 | 
						|
export const useFocusOn = () => {
 | 
						|
    const { fitView, setNodes, setEdges } = useReactFlow();
 | 
						|
    const { hideSidePanel } = useLayout();
 | 
						|
    const { isMd: isDesktop } = useBreakpoint('md');
 | 
						|
 | 
						|
    const focusOnArea = useCallback(
 | 
						|
        (areaId: string, options: FocusOptions = {}) => {
 | 
						|
            const { select = true } = options;
 | 
						|
 | 
						|
            if (select) {
 | 
						|
                setNodes((nodes) =>
 | 
						|
                    nodes.map((node) =>
 | 
						|
                        node.id === areaId
 | 
						|
                            ? {
 | 
						|
                                  ...node,
 | 
						|
                                  selected: true,
 | 
						|
                              }
 | 
						|
                            : {
 | 
						|
                                  ...node,
 | 
						|
                                  selected: false,
 | 
						|
                              }
 | 
						|
                    )
 | 
						|
                );
 | 
						|
            }
 | 
						|
 | 
						|
            fitView({
 | 
						|
                duration: 500,
 | 
						|
                maxZoom: 1,
 | 
						|
                minZoom: 1,
 | 
						|
                nodes: [
 | 
						|
                    {
 | 
						|
                        id: areaId,
 | 
						|
                    },
 | 
						|
                ],
 | 
						|
            });
 | 
						|
 | 
						|
            if (!isDesktop) {
 | 
						|
                hideSidePanel();
 | 
						|
            }
 | 
						|
        },
 | 
						|
        [fitView, setNodes, hideSidePanel, isDesktop]
 | 
						|
    );
 | 
						|
 | 
						|
    const focusOnTable = useCallback(
 | 
						|
        (tableId: string, options: FocusOptions = {}) => {
 | 
						|
            const { select = true } = options;
 | 
						|
 | 
						|
            if (select) {
 | 
						|
                setNodes((nodes) =>
 | 
						|
                    nodes.map((node) =>
 | 
						|
                        node.id === tableId
 | 
						|
                            ? {
 | 
						|
                                  ...node,
 | 
						|
                                  selected: true,
 | 
						|
                              }
 | 
						|
                            : {
 | 
						|
                                  ...node,
 | 
						|
                                  selected: false,
 | 
						|
                              }
 | 
						|
                    )
 | 
						|
                );
 | 
						|
            }
 | 
						|
 | 
						|
            fitView({
 | 
						|
                duration: 500,
 | 
						|
                maxZoom: 1,
 | 
						|
                minZoom: 1,
 | 
						|
                nodes: [
 | 
						|
                    {
 | 
						|
                        id: tableId,
 | 
						|
                    },
 | 
						|
                ],
 | 
						|
            });
 | 
						|
 | 
						|
            if (!isDesktop) {
 | 
						|
                hideSidePanel();
 | 
						|
            }
 | 
						|
        },
 | 
						|
        [fitView, setNodes, hideSidePanel, isDesktop]
 | 
						|
    );
 | 
						|
 | 
						|
    const focusOnRelationship = useCallback(
 | 
						|
        (
 | 
						|
            relationshipId: string,
 | 
						|
            sourceTableId: string,
 | 
						|
            targetTableId: string,
 | 
						|
            options: FocusOptions = {}
 | 
						|
        ) => {
 | 
						|
            const { select = true } = options;
 | 
						|
 | 
						|
            if (select) {
 | 
						|
                setEdges((edges) =>
 | 
						|
                    edges.map((edge) =>
 | 
						|
                        edge.id === relationshipId
 | 
						|
                            ? {
 | 
						|
                                  ...edge,
 | 
						|
                                  selected: true,
 | 
						|
                              }
 | 
						|
                            : {
 | 
						|
                                  ...edge,
 | 
						|
                                  selected: false,
 | 
						|
                              }
 | 
						|
                    )
 | 
						|
                );
 | 
						|
            }
 | 
						|
 | 
						|
            fitView({
 | 
						|
                duration: 500,
 | 
						|
                maxZoom: 1,
 | 
						|
                minZoom: 1,
 | 
						|
                nodes: [
 | 
						|
                    {
 | 
						|
                        id: sourceTableId,
 | 
						|
                    },
 | 
						|
                    {
 | 
						|
                        id: targetTableId,
 | 
						|
                    },
 | 
						|
                ],
 | 
						|
            });
 | 
						|
 | 
						|
            if (!isDesktop) {
 | 
						|
                hideSidePanel();
 | 
						|
            }
 | 
						|
        },
 | 
						|
        [fitView, setEdges, hideSidePanel, isDesktop]
 | 
						|
    );
 | 
						|
 | 
						|
    return {
 | 
						|
        focusOnArea,
 | 
						|
        focusOnTable,
 | 
						|
        focusOnRelationship,
 | 
						|
    };
 | 
						|
};
 |