mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
replace useConfig with useGraph
This commit is contained in:
parent
a26b94f584
commit
20bcdfef10
@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
// import { useInViewport } from "react-in-viewport";
|
// import { useInViewport } from "react-in-viewport";
|
||||||
import { CustomNodeProps } from "src/components/CustomNode";
|
import { CustomNodeProps } from "src/components/CustomNode";
|
||||||
import useConfig from "src/store/useConfig";
|
import useGraph from "src/store/useGraph";
|
||||||
import * as Styled from "./styles";
|
import * as Styled from "./styles";
|
||||||
|
|
||||||
const inViewport = true;
|
const inViewport = true;
|
||||||
@ -9,7 +9,7 @@ const inViewport = true;
|
|||||||
const ObjectNode: React.FC<CustomNodeProps> = ({ node, x, y }) => {
|
const ObjectNode: React.FC<CustomNodeProps> = ({ node, x, y }) => {
|
||||||
const { text, width, height, data } = node;
|
const { text, width, height, data } = node;
|
||||||
const ref = React.useRef(null);
|
const ref = React.useRef(null);
|
||||||
const performanceMode = useConfig(state => state.performanceMode);
|
const performanceMode = useGraph(state => state.performanceMode);
|
||||||
// const { inViewport } = useInViewport(ref);
|
// const { inViewport } = useInViewport(ref);
|
||||||
|
|
||||||
if (data.isEmpty) return null;
|
if (data.isEmpty) return null;
|
||||||
|
@ -2,7 +2,6 @@ import React from "react";
|
|||||||
import { MdLink, MdLinkOff } from "react-icons/md";
|
import { MdLink, MdLinkOff } from "react-icons/md";
|
||||||
// import { useInViewport } from "react-in-viewport";
|
// import { useInViewport } from "react-in-viewport";
|
||||||
import { CustomNodeProps } from "src/components/CustomNode";
|
import { CustomNodeProps } from "src/components/CustomNode";
|
||||||
import useConfig from "src/store/useConfig";
|
|
||||||
import useGraph from "src/store/useGraph";
|
import useGraph from "src/store/useGraph";
|
||||||
import useStored from "src/store/useStored";
|
import useStored from "src/store/useStored";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
@ -48,7 +47,7 @@ const TextNode: React.FC<CustomNodeProps> = ({
|
|||||||
const expandNodes = useGraph(state => state.expandNodes);
|
const expandNodes = useGraph(state => state.expandNodes);
|
||||||
const collapseNodes = useGraph(state => state.collapseNodes);
|
const collapseNodes = useGraph(state => state.collapseNodes);
|
||||||
const isExpanded = useGraph(state => state.collapsedParents.includes(id));
|
const isExpanded = useGraph(state => state.collapsedParents.includes(id));
|
||||||
const performanceMode = useConfig(state => state.performanceMode);
|
const performanceMode = useGraph(state => state.performanceMode);
|
||||||
// const { inViewport } = useInViewport(ref);
|
// const { inViewport } = useInViewport(ref);
|
||||||
|
|
||||||
const handleExpand = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const handleExpand = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
} from "react-zoom-pan-pinch";
|
} from "react-zoom-pan-pinch";
|
||||||
import { Canvas, Edge, ElkRoot } from "reaflow";
|
import { Canvas, Edge, ElkRoot } from "reaflow";
|
||||||
import { CustomNode } from "src/components/CustomNode";
|
import { CustomNode } from "src/components/CustomNode";
|
||||||
import useConfig from "src/store/useConfig";
|
|
||||||
import useGraph from "src/store/useGraph";
|
import useGraph from "src/store/useGraph";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Loading } from "../Loading";
|
import { Loading } from "../Loading";
|
||||||
@ -47,8 +46,8 @@ const GraphComponent = ({
|
|||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
}: GraphProps) => {
|
}: GraphProps) => {
|
||||||
const setLoading = useGraph(state => state.setLoading);
|
const setLoading = useGraph(state => state.setLoading);
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const setZoomPanPinch = useGraph(state => state.setZoomPanPinch);
|
||||||
const centerView = useConfig(state => state.centerView);
|
const centerView = useGraph(state => state.centerView);
|
||||||
|
|
||||||
const loading = useGraph(state => state.loading);
|
const loading = useGraph(state => state.loading);
|
||||||
const direction = useGraph(state => state.direction);
|
const direction = useGraph(state => state.direction);
|
||||||
@ -70,9 +69,9 @@ const GraphComponent = ({
|
|||||||
|
|
||||||
const onInit = React.useCallback(
|
const onInit = React.useCallback(
|
||||||
(ref: ReactZoomPanPinchRef) => {
|
(ref: ReactZoomPanPinchRef) => {
|
||||||
setConfig("zoomPanPinch", ref);
|
setZoomPanPinch(ref);
|
||||||
},
|
},
|
||||||
[setConfig]
|
[setZoomPanPinch]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onLayoutChange = React.useCallback(
|
const onLayoutChange = React.useCallback(
|
||||||
|
@ -19,11 +19,11 @@ import {
|
|||||||
VscSettingsGear,
|
VscSettingsGear,
|
||||||
} from "react-icons/vsc";
|
} from "react-icons/vsc";
|
||||||
import { Tooltip } from "src/components/Tooltip";
|
import { Tooltip } from "src/components/Tooltip";
|
||||||
import useConfig from "src/store/useConfig";
|
|
||||||
import useGraph from "src/store/useGraph";
|
import useGraph from "src/store/useGraph";
|
||||||
import useModal from "src/store/useModal";
|
import useModal from "src/store/useModal";
|
||||||
import { getNextDirection } from "src/utils/getNextDirection";
|
import { getNextDirection } from "src/utils/getNextDirection";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
import useJson from "src/store/useJson";
|
||||||
|
|
||||||
const StyledSidebar = styled.div`
|
const StyledSidebar = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -140,17 +140,19 @@ function rotateLayout(direction: "LEFT" | "RIGHT" | "DOWN" | "UP") {
|
|||||||
|
|
||||||
export const Sidebar: React.FC = () => {
|
export const Sidebar: React.FC = () => {
|
||||||
const setVisible = useModal(state => state.setVisible);
|
const setVisible = useModal(state => state.setVisible);
|
||||||
const getJson = useGraph(state => state.getJson);
|
|
||||||
const setDirection = useGraph(state => state.setDirection);
|
const setDirection = useGraph(state => state.setDirection);
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const getJson = useJson(state => state.getJson);
|
||||||
const centerView = useConfig(state => state.centerView);
|
|
||||||
const collapseGraph = useGraph(state => state.collapseGraph);
|
const collapseGraph = useGraph(state => state.collapseGraph);
|
||||||
const expandGraph = useGraph(state => state.expandGraph);
|
const expandGraph = useGraph(state => state.expandGraph);
|
||||||
|
const centerView = useGraph(state => state.centerView);
|
||||||
|
const toggleFold = useGraph(state => state.toggleFold);
|
||||||
|
const toggleFullscreen = useGraph(state => state.toggleFullscreen);
|
||||||
|
|
||||||
const graphCollapsed = useGraph(state => state.graphCollapsed);
|
|
||||||
const direction = useGraph(state => state.direction);
|
const direction = useGraph(state => state.direction);
|
||||||
const foldNodes = useConfig(state => state.foldNodes);
|
const foldNodes = useGraph(state => state.foldNodes);
|
||||||
const fullscreen = useConfig(state => state.fullscreen);
|
const fullscreen = useGraph(state => state.fullscreen);
|
||||||
|
const graphCollapsed = useGraph(state => state.graphCollapsed);
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
@ -162,7 +164,7 @@ export const Sidebar: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toggleFoldNodes = () => {
|
const toggleFoldNodes = () => {
|
||||||
setConfig("foldNodes", !foldNodes);
|
toggleFold(!foldNodes);
|
||||||
toast(`${foldNodes ? "Unfolded" : "Folded"} nodes`);
|
toast(`${foldNodes ? "Unfolded" : "Folded"} nodes`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -189,7 +191,7 @@ export const Sidebar: React.FC = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Tooltip className="mobile" title="Edit JSON">
|
<Tooltip className="mobile" title="Edit JSON">
|
||||||
<StyledElement onClick={() => setConfig("fullscreen", !fullscreen)}>
|
<StyledElement onClick={() => toggleFullscreen(!fullscreen)}>
|
||||||
<AiOutlineEdit />
|
<AiOutlineEdit />
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -3,8 +3,8 @@ import dynamic from "next/dynamic";
|
|||||||
import { Allotment } from "allotment";
|
import { Allotment } from "allotment";
|
||||||
import "allotment/dist/style.css";
|
import "allotment/dist/style.css";
|
||||||
import { JsonEditor } from "src/containers/Editor/JsonEditor";
|
import { JsonEditor } from "src/containers/Editor/JsonEditor";
|
||||||
import useConfig from "src/store/useConfig";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
import useGraph from "src/store/useGraph";
|
||||||
|
|
||||||
export const StyledEditor = styled(Allotment)`
|
export const StyledEditor = styled(Allotment)`
|
||||||
position: relative !important;
|
position: relative !important;
|
||||||
@ -17,13 +17,13 @@ const LiveEditor = dynamic(() => import("src/containers/Editor/LiveEditor"), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const Panes: React.FC = () => {
|
const Panes: React.FC = () => {
|
||||||
const fullscreen = useConfig(state => state.fullscreen);
|
const fullscreen = useGraph(state => state.fullscreen);
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const toggleFullscreen = useGraph(state => state.toggleFullscreen);
|
||||||
const isMobile = React.useMemo(() => window.innerWidth <= 768, []);
|
const isMobile = React.useMemo(() => window.innerWidth <= 768, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (isMobile) setConfig("fullscreen", true);
|
if (isMobile) toggleFullscreen(true);
|
||||||
}, [isMobile, setConfig]);
|
}, [isMobile, toggleFullscreen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledEditor proportionalLayout={false} vertical={isMobile}>
|
<StyledEditor proportionalLayout={false} vertical={isMobile}>
|
||||||
|
@ -3,7 +3,7 @@ import { AiOutlineFullscreen, AiOutlineMinus, AiOutlinePlus } from "react-icons/
|
|||||||
import { FiDownload } from "react-icons/fi";
|
import { FiDownload } from "react-icons/fi";
|
||||||
import { MdCenterFocusWeak } from "react-icons/md";
|
import { MdCenterFocusWeak } from "react-icons/md";
|
||||||
import { SearchInput } from "src/components/SearchInput";
|
import { SearchInput } from "src/components/SearchInput";
|
||||||
import useConfig from "src/store/useConfig";
|
import useGraph from "src/store/useGraph";
|
||||||
import useModal from "src/store/useModal";
|
import useModal from "src/store/useModal";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
@ -48,13 +48,13 @@ const StyledToolElement = styled.button`
|
|||||||
export const Tools: React.FC = () => {
|
export const Tools: React.FC = () => {
|
||||||
const setVisible = useModal(state => state.setVisible);
|
const setVisible = useModal(state => state.setVisible);
|
||||||
|
|
||||||
const fullscreen = useConfig(state => state.fullscreen);
|
const fullscreen = useGraph(state => state.fullscreen);
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const toggleFullscreen = useGraph(state => state.toggleFullscreen);
|
||||||
|
|
||||||
const zoomIn = useConfig(state => state.zoomIn);
|
const zoomIn = useGraph(state => state.zoomIn);
|
||||||
const zoomOut = useConfig(state => state.zoomOut);
|
const zoomOut = useGraph(state => state.zoomOut);
|
||||||
const centerView = useConfig(state => state.centerView);
|
const centerView = useGraph(state => state.centerView);
|
||||||
const toggleEditor = () => setConfig("fullscreen", !fullscreen);
|
const toggleEditor = () => toggleFullscreen(!fullscreen);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -7,8 +7,8 @@ import { FiCopy, FiDownload } from "react-icons/fi";
|
|||||||
import { Button } from "src/components/Button";
|
import { Button } from "src/components/Button";
|
||||||
import { Input } from "src/components/Input";
|
import { Input } from "src/components/Input";
|
||||||
import { Modal, ModalProps } from "src/components/Modal";
|
import { Modal, ModalProps } from "src/components/Modal";
|
||||||
import useConfig from "src/store/useConfig";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
import useGraph from "src/store/useGraph";
|
||||||
|
|
||||||
const ColorPickerStyles: Partial<TwitterPickerStylesProps> = {
|
const ColorPickerStyles: Partial<TwitterPickerStylesProps> = {
|
||||||
card: {
|
card: {
|
||||||
@ -93,7 +93,7 @@ const StyledColorIndicator = styled.div<{ color: string }>`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const DownloadModal: React.FC<ModalProps> = ({ visible, setVisible }) => {
|
export const DownloadModal: React.FC<ModalProps> = ({ visible, setVisible }) => {
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const togglePerfMode = useGraph(state => state.togglePerfMode);
|
||||||
const [fileDetails, setFileDetails] = React.useState({
|
const [fileDetails, setFileDetails] = React.useState({
|
||||||
filename: "jsoncrack.com",
|
filename: "jsoncrack.com",
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
@ -103,7 +103,7 @@ export const DownloadModal: React.FC<ModalProps> = ({ visible, setVisible }) =>
|
|||||||
const clipboardImage = async () => {
|
const clipboardImage = async () => {
|
||||||
try {
|
try {
|
||||||
toast.loading("Copying to clipboard...", { id: "toastClipboard" });
|
toast.loading("Copying to clipboard...", { id: "toastClipboard" });
|
||||||
setConfig("performanceMode", false);
|
togglePerfMode(false);
|
||||||
|
|
||||||
const imageElement = document.querySelector("svg[id*='ref']") as HTMLElement;
|
const imageElement = document.querySelector("svg[id*='ref']") as HTMLElement;
|
||||||
|
|
||||||
@ -126,14 +126,14 @@ export const DownloadModal: React.FC<ModalProps> = ({ visible, setVisible }) =>
|
|||||||
} finally {
|
} finally {
|
||||||
toast.dismiss("toastClipboard");
|
toast.dismiss("toastClipboard");
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setConfig("performanceMode", true);
|
togglePerfMode(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportAsImage = async () => {
|
const exportAsImage = async () => {
|
||||||
try {
|
try {
|
||||||
toast.loading("Downloading...", { id: "toastDownload" });
|
toast.loading("Downloading...", { id: "toastDownload" });
|
||||||
setConfig("performanceMode", false);
|
togglePerfMode(false);
|
||||||
|
|
||||||
const imageElement = document.querySelector("svg[id*='ref']") as HTMLElement;
|
const imageElement = document.querySelector("svg[id*='ref']") as HTMLElement;
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ export const DownloadModal: React.FC<ModalProps> = ({ visible, setVisible }) =>
|
|||||||
} finally {
|
} finally {
|
||||||
toast.dismiss("toastDownload");
|
toast.dismiss("toastDownload");
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setConfig("performanceMode", true);
|
togglePerfMode(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import useGraph from "src/store/useGraph";
|
||||||
import {
|
import {
|
||||||
searchQuery,
|
searchQuery,
|
||||||
cleanupHighlight,
|
cleanupHighlight,
|
||||||
highlightMatchedNodes,
|
highlightMatchedNodes,
|
||||||
} from "src/utils/search";
|
} from "src/utils/search";
|
||||||
import useConfig from "../store/useConfig";
|
|
||||||
|
|
||||||
export const useFocusNode = () => {
|
export const useFocusNode = () => {
|
||||||
const setConfig = useConfig(state => state.setConfig);
|
const togglePerfMode = useGraph(state => state.togglePerfMode);
|
||||||
const zoomPanPinch = useConfig(state => state.zoomPanPinch);
|
const zoomPanPinch = useGraph(state => state.zoomPanPinch);
|
||||||
const [selectedNode, setSelectedNode] = React.useState(0);
|
const [selectedNode, setSelectedNode] = React.useState(0);
|
||||||
const [content, setContent] = React.useState({
|
const [content, setContent] = React.useState({
|
||||||
value: "",
|
value: "",
|
||||||
@ -18,14 +18,14 @@ export const useFocusNode = () => {
|
|||||||
const skip = () => setSelectedNode(current => current + 1);
|
const skip = () => setSelectedNode(current => current + 1);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setConfig("performanceMode", !content.value.length);
|
togglePerfMode(!content.value.length);
|
||||||
|
|
||||||
const debouncer = setTimeout(() => {
|
const debouncer = setTimeout(() => {
|
||||||
setContent(val => ({ ...val, debounced: content.value }));
|
setContent(val => ({ ...val, debounced: content.value }));
|
||||||
}, 800);
|
}, 800);
|
||||||
|
|
||||||
return () => clearTimeout(debouncer);
|
return () => clearTimeout(debouncer);
|
||||||
}, [content.value, setConfig]);
|
}, [content.value, togglePerfMode]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!zoomPanPinch) return;
|
if (!zoomPanPinch) return;
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import { ReactZoomPanPinchRef } from "react-zoom-pan-pinch";
|
|
||||||
import create from "zustand";
|
|
||||||
|
|
||||||
type StateType = keyof typeof initialStates;
|
|
||||||
type StateKey<T extends StateType> = typeof initialStates[T];
|
|
||||||
|
|
||||||
interface ConfigActions {
|
|
||||||
setConfig: <T extends StateType, K extends StateKey<T>>(key: T, value: K) => void;
|
|
||||||
zoomIn: () => void;
|
|
||||||
zoomOut: () => void;
|
|
||||||
centerView: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialStates = {
|
|
||||||
foldNodes: false,
|
|
||||||
fullscreen: false,
|
|
||||||
performanceMode: true,
|
|
||||||
zoomPanPinch: undefined as ReactZoomPanPinchRef | undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Config = typeof initialStates;
|
|
||||||
|
|
||||||
const useConfig = create<Config & ConfigActions>()((set, get) => ({
|
|
||||||
...initialStates,
|
|
||||||
zoomIn: () => {
|
|
||||||
const zoomPanPinch = get().zoomPanPinch;
|
|
||||||
if (zoomPanPinch) {
|
|
||||||
zoomPanPinch.setTransform(
|
|
||||||
zoomPanPinch?.state.positionX,
|
|
||||||
zoomPanPinch?.state.positionY,
|
|
||||||
zoomPanPinch?.state.scale + 0.4
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
zoomOut: () => {
|
|
||||||
const zoomPanPinch = get().zoomPanPinch;
|
|
||||||
if (zoomPanPinch) {
|
|
||||||
zoomPanPinch.setTransform(
|
|
||||||
zoomPanPinch?.state.positionX,
|
|
||||||
zoomPanPinch?.state.positionY,
|
|
||||||
zoomPanPinch?.state.scale - 0.4
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
centerView: () => {
|
|
||||||
const zoomPanPinch = get().zoomPanPinch;
|
|
||||||
const canvas = document.querySelector(".jsoncrack-canvas") as HTMLElement;
|
|
||||||
if (zoomPanPinch && canvas) zoomPanPinch.zoomToElement(canvas);
|
|
||||||
},
|
|
||||||
setConfig: (setting, value) => {
|
|
||||||
if (setting === "fullscreen" && value) {
|
|
||||||
set({ fullscreen: true });
|
|
||||||
return get().centerView();
|
|
||||||
}
|
|
||||||
|
|
||||||
set({ [setting]: value });
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default useConfig;
|
|
@ -1,17 +1,19 @@
|
|||||||
import { parse } from "jsonc-parser";
|
import { ReactZoomPanPinchRef } from "react-zoom-pan-pinch";
|
||||||
import { CanvasDirection } from "reaflow";
|
import { CanvasDirection } from "reaflow";
|
||||||
import { Graph } from "src/components/Graph";
|
import { Graph } from "src/components/Graph";
|
||||||
import { getChildrenEdges } from "src/utils/getChildrenEdges";
|
import { getChildrenEdges } from "src/utils/getChildrenEdges";
|
||||||
import { getOutgoers } from "src/utils/getOutgoers";
|
import { getOutgoers } from "src/utils/getOutgoers";
|
||||||
import { parser } from "src/utils/jsonParser";
|
import { parser } from "src/utils/jsonParser";
|
||||||
import create from "zustand";
|
import create from "zustand";
|
||||||
import useConfig from "./useConfig";
|
|
||||||
|
|
||||||
const initialStates = {
|
const initialStates = {
|
||||||
json: null as unknown as string,
|
zoomPanPinch: undefined as ReactZoomPanPinchRef | undefined,
|
||||||
loading: true,
|
|
||||||
direction: "RIGHT" as CanvasDirection,
|
direction: "RIGHT" as CanvasDirection,
|
||||||
|
loading: true,
|
||||||
graphCollapsed: false,
|
graphCollapsed: false,
|
||||||
|
foldNodes: false,
|
||||||
|
fullscreen: false,
|
||||||
|
performanceMode: true,
|
||||||
nodes: [] as NodeData[],
|
nodes: [] as NodeData[],
|
||||||
edges: [] as EdgeData[],
|
edges: [] as EdgeData[],
|
||||||
collapsedNodes: [] as string[],
|
collapsedNodes: [] as string[],
|
||||||
@ -23,25 +25,36 @@ export type Graph = typeof initialStates;
|
|||||||
|
|
||||||
interface GraphActions {
|
interface GraphActions {
|
||||||
setGraph: (json: string) => void;
|
setGraph: (json: string) => void;
|
||||||
getJson: () => string;
|
|
||||||
setNodeEdges: (nodes: NodeData[], edges: EdgeData[]) => void;
|
setNodeEdges: (nodes: NodeData[], edges: EdgeData[]) => void;
|
||||||
setLoading: (loading: boolean) => void;
|
setLoading: (loading: boolean) => void;
|
||||||
setDirection: (direction: CanvasDirection) => void;
|
setDirection: (direction: CanvasDirection) => void;
|
||||||
|
setZoomPanPinch: (ref: ReactZoomPanPinchRef) => void;
|
||||||
expandNodes: (nodeId: string) => void;
|
expandNodes: (nodeId: string) => void;
|
||||||
collapseNodes: (nodeId: string) => void;
|
collapseNodes: (nodeId: string) => void;
|
||||||
collapseGraph: () => void;
|
collapseGraph: () => void;
|
||||||
expandGraph: () => void;
|
expandGraph: () => void;
|
||||||
|
toggleFold: (value: boolean) => void;
|
||||||
|
toggleFullscreen: (value: boolean) => void;
|
||||||
|
togglePerfMode: (value: boolean) => void;
|
||||||
|
zoomIn: () => void;
|
||||||
|
zoomOut: () => void;
|
||||||
|
centerView: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useGraph = create<Graph & GraphActions>((set, get) => ({
|
const useGraph = create<Graph & GraphActions>((set, get) => ({
|
||||||
...initialStates,
|
...initialStates,
|
||||||
getJson: () => get().json,
|
|
||||||
setGraph: (data: string) => {
|
setGraph: (data: string) => {
|
||||||
const { nodes, edges } = parser(data, useConfig.getState().foldNodes);
|
const { nodes, edges } = parser(data, get().foldNodes);
|
||||||
const json = JSON.stringify(parse(data), null, 2);
|
|
||||||
|
|
||||||
set({ json, loading: true });
|
set({
|
||||||
get().setNodeEdges(nodes, edges);
|
nodes,
|
||||||
|
edges,
|
||||||
|
collapsedParents: [],
|
||||||
|
collapsedNodes: [],
|
||||||
|
collapsedEdges: [],
|
||||||
|
graphCollapsed: false,
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
setDirection: direction => set({ direction }),
|
setDirection: direction => set({ direction }),
|
||||||
setNodeEdges: (nodes, edges) =>
|
setNodeEdges: (nodes, edges) =>
|
||||||
@ -52,6 +65,7 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
|||||||
collapsedNodes: [],
|
collapsedNodes: [],
|
||||||
collapsedEdges: [],
|
collapsedEdges: [],
|
||||||
graphCollapsed: false,
|
graphCollapsed: false,
|
||||||
|
loading: true
|
||||||
}),
|
}),
|
||||||
setLoading: loading => set({ loading }),
|
setLoading: loading => set({ loading }),
|
||||||
expandNodes: nodeId => {
|
expandNodes: nodeId => {
|
||||||
@ -141,6 +155,36 @@ const useGraph = create<Graph & GraphActions>((set, get) => ({
|
|||||||
graphCollapsed: false,
|
graphCollapsed: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
zoomIn: () => {
|
||||||
|
const zoomPanPinch = get().zoomPanPinch;
|
||||||
|
if (zoomPanPinch) {
|
||||||
|
zoomPanPinch.setTransform(
|
||||||
|
zoomPanPinch?.state.positionX,
|
||||||
|
zoomPanPinch?.state.positionY,
|
||||||
|
zoomPanPinch?.state.scale + 0.4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
zoomOut: () => {
|
||||||
|
const zoomPanPinch = get().zoomPanPinch;
|
||||||
|
if (zoomPanPinch) {
|
||||||
|
zoomPanPinch.setTransform(
|
||||||
|
zoomPanPinch?.state.positionX,
|
||||||
|
zoomPanPinch?.state.positionY,
|
||||||
|
zoomPanPinch?.state.scale - 0.4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
centerView: () => {
|
||||||
|
const zoomPanPinch = get().zoomPanPinch;
|
||||||
|
const canvas = document.querySelector(".jsoncrack-canvas") as HTMLElement;
|
||||||
|
if (zoomPanPinch && canvas) zoomPanPinch.zoomToElement(canvas);
|
||||||
|
},
|
||||||
|
toggleFold: foldNodes => set({ foldNodes }),
|
||||||
|
togglePerfMode: performanceMode => set({ performanceMode }),
|
||||||
|
toggleFullscreen: fullscreen => set({ fullscreen }),
|
||||||
|
setZoomPanPinch: zoomPanPinch => set({ zoomPanPinch }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useGraph;
|
export default useGraph;
|
||||||
|
@ -15,6 +15,7 @@ interface Json {
|
|||||||
|
|
||||||
interface JsonActions {
|
interface JsonActions {
|
||||||
setJson: (json: string) => void;
|
setJson: (json: string) => void;
|
||||||
|
getJson: () => string;
|
||||||
fetchJson: (jsonId: string | string[] | undefined) => void;
|
fetchJson: (jsonId: string | string[] | undefined) => void;
|
||||||
setError: (hasError: boolean) => void;
|
setError: (hasError: boolean) => void;
|
||||||
setHasChanges: (hasChanges: boolean) => void;
|
setHasChanges: (hasChanges: boolean) => void;
|
||||||
@ -30,8 +31,9 @@ const initialStates = {
|
|||||||
|
|
||||||
export type JsonStates = typeof initialStates;
|
export type JsonStates = typeof initialStates;
|
||||||
|
|
||||||
const useJson = create<JsonStates & JsonActions>()(set => ({
|
const useJson = create<JsonStates & JsonActions>()((set, get) => ({
|
||||||
...initialStates,
|
...initialStates,
|
||||||
|
getJson: () => get().json,
|
||||||
fetchJson: async jsonId => {
|
fetchJson: async jsonId => {
|
||||||
if (jsonId) {
|
if (jsonId) {
|
||||||
const { data } = await altogic.endpoint.get(`json/${jsonId}`);
|
const { data } = await altogic.endpoint.get(`json/${jsonId}`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user