feat: updated to use `useProject` hook

pull/68/head
Samuel Rowe 3 years ago
parent 99f935f81b
commit 8c145387bf

@ -1,45 +1,45 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react"
import { useParams, useNavigate } from "react-router-dom"; import { useParams, useNavigate } from "react-router-dom"
import { IProjectPayload } from "../../types"; import { IProjectPayload } from "../../types"
import { nodes, connections, position, updateProjectName } from "../../reducers"; import { nodes, connections, position, updateProjectName } from "../../reducers"
import Spinner from "../Spinner"; import Spinner from "../Spinner"
import { Canvas } from "../Canvas"; import { Canvas } from "../Canvas"
import useWindowDimensions from "../../hooks/useWindowDimensions"; import useWindowDimensions from "../../hooks/useWindowDimensions"
import { getClientNodesAndConnections } from "../../utils"; import { getClientNodesAndConnections } from "../../utils"
import { projectHttpGet, projectHttpUpdate, projectHttpCreate } from "../../services/project"; import {
import { checkHttpStatus } from "../../services/helpers"; projectHttpGet,
import { nodeLibraries } from "../../utils/data/libraries"; projectHttpUpdate,
projectHttpCreate
} from "../../services/project"
import { checkHttpStatus } from "../../services/helpers"
import { nodeLibraries } from "../../utils/data/libraries"
interface IProjectProps { interface IProjectProps {
dispatch: any; dispatch: any
state: any; state: any
} }
export default function Project(props: IProjectProps) { export default function Project(props: IProjectProps) {
const { uuid } = useParams<{ uuid?: string }>(); const { uuid } = useParams<{ uuid?: string }>()
const { dispatch, state } = props; const { dispatch, state } = props
const [saving, setSaving] = useState(false); const [saving, setSaving] = useState(false)
const [projectName, setProjectName] = useState(""); const [projectName, setProjectName] = useState("")
const { height, width } = useWindowDimensions(); const { height, width } = useWindowDimensions()
const navigate = useNavigate(); const navigate = useNavigate()
const handleNameChange = (e: any) => { const handleNameChange = (e: any) => {
setProjectName(e.target.value); setProjectName(e.target.value)
dispatch(updateProjectName(e.target.value)); dispatch(updateProjectName(e.target.value))
} }
const updateProject = (uuid: string, payload: IProjectPayload) => { const updateProject = (uuid: string, payload: IProjectPayload) => {
projectHttpUpdate(uuid, JSON.stringify(payload)) projectHttpUpdate(uuid, JSON.stringify(payload))
.then(checkHttpStatus) .then(checkHttpStatus)
.then(data => { .then(data => {})
.catch(err => {})
})
.catch(err => {
})
.finally(() => { .finally(() => {
setSaving(false); setSaving(false)
}); })
} }
const createProject = (payload: IProjectPayload) => { const createProject = (payload: IProjectPayload) => {
@ -48,16 +48,14 @@ export default function Project(props: IProjectProps) {
.then(data => { .then(data => {
navigate(`/projects/${data.uuid}`) navigate(`/projects/${data.uuid}`)
}) })
.catch(err => { .catch(err => {})
})
.finally(() => { .finally(() => {
setSaving(false); setSaving(false)
}); })
} }
const onSave = () => { const onSave = () => {
setSaving(true); setSaving(true)
const payload: IProjectPayload = { const payload: IProjectPayload = {
name: state.projectName, name: state.projectName,
data: { data: {
@ -71,66 +69,75 @@ export default function Project(props: IProjectProps) {
secrets: [], secrets: [],
services: state.nodes, services: state.nodes,
version: 3, version: 3,
volumes: [], volumes: []
}
} }
};
if (uuid) { if (uuid) {
updateProject(uuid, payload); updateProject(uuid, payload)
} else { } else {
createProject(payload); createProject(payload)
}
} }
};
const setViewHeight = () => { const setViewHeight = () => {
let vh = window.innerHeight * 0.01; let vh = window.innerHeight * 0.01
document.documentElement.style.setProperty('--vh', `${vh}px`); document.documentElement.style.setProperty("--vh", `${vh}px`)
}; }
useEffect(() => { const { data, error, isFetching } = useProject(uuid)
if (uuid) {
projectHttpGet(uuid) const { nodesAsList, clientNodeItems } = useMemo(() => {
.then(checkHttpStatus) if (!data) {
.then(data => { return
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); const nodesAsList = Object.keys(projectData.canvas.nodes).map(k => {
setProjectName(data.name); 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(updateProjectName(data.name));
dispatch(nodes(clientNodeItems)); dispatch(nodes(clientNodeItems));
dispatch(connections(projectData.canvas.connections)); dispatch(connections(projectData.canvas.connections));
dispatch(position(projectData.canvas.position)); dispatch(position(projectData.canvas.position));
})
.catch(err => { return { nodesAsList, clientNodeItems }
if (err.status === 404) { }, [dispatch])
window.location.replace("/");
}
})
.finally(() => {
//setFetching(false);
})
}
}, [uuid, dispatch]);
useEffect(() => { useEffect(() => {
//setProjectName(state.projectName); if (uuid && !isFetching && data) {
}, [state.projectName]); setProjectName(data.name)
}
}, [uuid, isFetching, data?.name])
useEffect(() => { useEffect(() => {
window.addEventListener("resize", () => { const handler = () => {
setViewHeight(); setViewHeight()
}); }
setViewHeight(); window.addEventListener("resize", handler)
}, []); setViewHeight()
() => {
window.removeEventListener("resize", handler)
}
}, [])
return ( return (
<> <>
<div className="px-4 py-3 border-b border-gray-200"> <div className="px-4 py-3 border-b border-gray-200">
<form className="flex flex-col space-y-2 md:flex-row md:justify-between items-center" autoComplete="off"> <form
className="flex flex-col space-y-2 md:flex-row md:justify-between items-center"
autoComplete="off"
>
<input <input
className={` className={`
bg-gray-100 bg-gray-100
@ -165,7 +172,7 @@ export default function Project(props: IProjectProps) {
<div className="flex flex-col space-y-2 w-full justify-end mb-4 md:flex-row md:space-y-0 md:space-x-2 md:mb-0"> <div className="flex flex-col space-y-2 w-full justify-end mb-4 md:flex-row md:space-y-0 md:space-x-2 md:mb-0">
<button <button
onClick={() => { onClick={() => {
window.location.replace("/"); window.location.replace("/")
}} }}
type="button" type="button"
className="btn-util text-black bg-gray-200 hover:bg-gray-300 sm:w-auto" className="btn-util text-black bg-gray-200 hover:bg-gray-300 sm:w-auto"
@ -181,9 +188,7 @@ export default function Project(props: IProjectProps) {
className="btn-util text-white bg-green-600 hover:bg-green-700 sm:w-auto" className="btn-util text-white bg-green-600 hover:bg-green-700 sm:w-auto"
> >
<div className="flex justify-center items-center space-x-2 mx-auto"> <div className="flex justify-center items-center space-x-2 mx-auto">
{saving && {saving && <Spinner className="w-4 h-4 text-green-300" />}
<Spinner className="w-4 h-4 text-green-300" />
}
<span>Save</span> <span>Save</span>
</div> </div>
</button> </button>
@ -192,12 +197,8 @@ export default function Project(props: IProjectProps) {
</div> </div>
<div className="flex flex-grow relative flex-col md:flex-row"> <div className="flex flex-grow relative flex-col md:flex-row">
<Canvas <Canvas state={state} dispatch={dispatch} height={height - 64} />
state={state}
dispatch={dispatch}
height={(height - 64)}
/>
</div> </div>
</> </>
); )
} }

Loading…
Cancel
Save