diff --git a/services/frontend/src/components/Project/index.tsx b/services/frontend/src/components/Project/index.tsx index 47d57bc..711cf6b 100644 --- a/services/frontend/src/components/Project/index.tsx +++ b/services/frontend/src/components/Project/index.tsx @@ -1,45 +1,45 @@ -import { useEffect, useState } from "react"; -import { useParams, useNavigate } from "react-router-dom"; -import { IProjectPayload } from "../../types"; -import { nodes, connections, position, updateProjectName } from "../../reducers"; -import Spinner from "../Spinner"; -import { Canvas } from "../Canvas"; -import useWindowDimensions from "../../hooks/useWindowDimensions"; -import { getClientNodesAndConnections } from "../../utils"; -import { projectHttpGet, projectHttpUpdate, projectHttpCreate } from "../../services/project"; -import { checkHttpStatus } from "../../services/helpers"; -import { nodeLibraries } from "../../utils/data/libraries"; +import { useEffect, useState } from "react" +import { useParams, useNavigate } from "react-router-dom" +import { IProjectPayload } from "../../types" +import { nodes, connections, position, updateProjectName } from "../../reducers" +import Spinner from "../Spinner" +import { Canvas } from "../Canvas" +import useWindowDimensions from "../../hooks/useWindowDimensions" +import { getClientNodesAndConnections } from "../../utils" +import { + projectHttpGet, + projectHttpUpdate, + projectHttpCreate +} from "../../services/project" +import { checkHttpStatus } from "../../services/helpers" +import { nodeLibraries } from "../../utils/data/libraries" interface IProjectProps { - dispatch: any; - state: any; + dispatch: any + state: any } export default function Project(props: IProjectProps) { - const { uuid } = useParams<{ uuid?: string }>(); - const { dispatch, state } = props; - const [saving, setSaving] = useState(false); - const [projectName, setProjectName] = useState(""); - const { height, width } = useWindowDimensions(); - const navigate = useNavigate(); + const { uuid } = useParams<{ uuid?: string }>() + const { dispatch, state } = props + const [saving, setSaving] = useState(false) + const [projectName, setProjectName] = useState("") + const { height, width } = useWindowDimensions() + const navigate = useNavigate() const handleNameChange = (e: any) => { - setProjectName(e.target.value); - dispatch(updateProjectName(e.target.value)); + setProjectName(e.target.value) + dispatch(updateProjectName(e.target.value)) } const updateProject = (uuid: string, payload: IProjectPayload) => { projectHttpUpdate(uuid, JSON.stringify(payload)) .then(checkHttpStatus) - .then(data => { - - }) - .catch(err => { - - }) + .then(data => {}) + .catch(err => {}) .finally(() => { - setSaving(false); - }); + setSaving(false) + }) } const createProject = (payload: IProjectPayload) => { @@ -48,16 +48,14 @@ export default function Project(props: IProjectProps) { .then(data => { navigate(`/projects/${data.uuid}`) }) - .catch(err => { - - }) + .catch(err => {}) .finally(() => { - setSaving(false); - }); + setSaving(false) + }) } const onSave = () => { - setSaving(true); + setSaving(true) const payload: IProjectPayload = { name: state.projectName, data: { @@ -71,66 +69,75 @@ export default function Project(props: IProjectProps) { secrets: [], services: state.nodes, version: 3, - volumes: [], + volumes: [] } - }; + } if (uuid) { - updateProject(uuid, payload); + updateProject(uuid, payload) } else { - createProject(payload); + createProject(payload) } - }; + } const setViewHeight = () => { - let vh = window.innerHeight * 0.01; - document.documentElement.style.setProperty('--vh', `${vh}px`); - }; + let vh = window.innerHeight * 0.01 + document.documentElement.style.setProperty("--vh", `${vh}px`) + } - useEffect(() => { - if (uuid) { - projectHttpGet(uuid) - .then(checkHttpStatus) - .then(data => { - const projectData = JSON.parse(data.data); - const nodesAsList = Object.keys(projectData.canvas.nodes).map((k) => { - return projectData.canvas.nodes[k]; - }); - - const clientNodeItems = getClientNodesAndConnections(nodesAsList, nodeLibraries); - setProjectName(data.name); - dispatch(updateProjectName(data.name)); - dispatch(nodes(clientNodeItems)); - dispatch(connections(projectData.canvas.connections)); - dispatch(position(projectData.canvas.position)); - }) - .catch(err => { - if (err.status === 404) { - window.location.replace("/"); - } - }) - .finally(() => { - //setFetching(false); - }) + const { data, error, isFetching } = useProject(uuid) + + const { nodesAsList, clientNodeItems } = useMemo(() => { + if (!data) { + return } - }, [uuid, dispatch]); + + const nodesAsList = Object.keys(projectData.canvas.nodes).map(k => { + return projectData.canvas.nodes[k] + }) + + const clientNodeItems = getClientNodesAndConnections( + nodesAsList, + nodeLibraries + ) + + /* TODO: Remove these dispatch calls as we migrate other components + * to React Query. + */ + dispatch(updateProjectName(data.name)); + dispatch(nodes(clientNodeItems)); + dispatch(connections(projectData.canvas.connections)); + dispatch(position(projectData.canvas.position)); + + return { nodesAsList, clientNodeItems } + }, [dispatch]) useEffect(() => { - //setProjectName(state.projectName); - }, [state.projectName]); + if (uuid && !isFetching && data) { + setProjectName(data.name) + } + }, [uuid, isFetching, data?.name]) useEffect(() => { - window.addEventListener("resize", () => { - setViewHeight(); - }); + const handler = () => { + setViewHeight() + } - setViewHeight(); - }, []); + window.addEventListener("resize", handler) + setViewHeight() + + () => { + window.removeEventListener("resize", handler) + } + }, []) return ( <>