Created
May 25, 2023 09:48
-
-
Save zourdyzou/af59918fb9afb408272bcdf0a6193dcb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useState } from 'react'; | |
| export type WBSProjectCRUD = { | |
| id?: string | null; | |
| name: string; | |
| reference: string; | |
| parentReference?: string | null; | |
| parentWbsId?: string | null; | |
| projectId?: string | null; | |
| wbsLevel: number; | |
| wbsOrder: number; | |
| expand: boolean; | |
| editMode: boolean; | |
| tempId: string; | |
| allChildren: WBSProjectCRUD[]; | |
| }; | |
| export type UseWBSProject = { | |
| projects: WBSProjectCRUD[]; | |
| addProject: (level: number) => void; | |
| updateProject: ( | |
| id: string | null, | |
| tempId: string | null, | |
| name: string, | |
| reference: string, | |
| ) => void; | |
| deleteProject: (id: string, tempId: string) => void; | |
| toggleExpand: (id: string, tempId: string) => void; | |
| }; | |
| export function findNodeById< | |
| A extends { id: string; tempId: string | any; allChildren: A[] }, | |
| >(node: A, id: string | null, tempId: string | null): A | null { | |
| if ((node.id && node.id === id) || (node.tempId && node.tempId === tempId)) { | |
| return node; | |
| } | |
| const foundNode = node.allChildren?.find((child) => | |
| findNodeById(child, id, tempId), | |
| ); | |
| return foundNode || null; | |
| } | |
| export const useWBSProject = ( | |
| initialProjects: WBSProjectCRUD[] = [], | |
| ): UseWBSProject => { | |
| const [projects, setProjects] = useState<WBSProjectCRUD[]>(initialProjects); | |
| const addProject = (level: number) => { | |
| const newProject: WBSProjectCRUD = { | |
| wbsOrder: 0, | |
| id: null, | |
| tempId: Date.now().toString(), // temporary ID | |
| name: ``, | |
| reference: ``, | |
| wbsLevel: level, | |
| expand: false, | |
| editMode: true, | |
| allChildren: [], | |
| }; | |
| if (level === 0) { | |
| setProjects([...projects, newProject]); | |
| } else { | |
| const addNode = (node: WBSProjectCRUD, level: number): WBSProjectCRUD => { | |
| if (node.wbsLevel === level - 1) { | |
| return { ...node, allChildren: [...node.allChildren, newProject] }; | |
| } else { | |
| node.allChildren = node.allChildren.map((child) => | |
| addNode(child, level), | |
| ); | |
| return node; | |
| } | |
| }; | |
| setProjects(projects.map((project) => addNode(project, level))); | |
| } | |
| }; | |
| const updateProject = ( | |
| id: string | null, | |
| tempId: string | null, | |
| name: string, | |
| reference: string, | |
| ) => { | |
| const updateNode = (node: WBSProjectCRUD): WBSProjectCRUD => { | |
| if (node.id === id || node.tempId === tempId) { | |
| return { ...node, name, reference, editMode: false }; | |
| } else { | |
| node.allChildren = node.allChildren.map((child) => updateNode(child)); | |
| return node; | |
| } | |
| }; | |
| setProjects(projects.map((project) => updateNode(project))); | |
| }; | |
| const deleteProject = (id: string, tempId: string) => { | |
| const deleteNode = (node: WBSProjectCRUD): WBSProjectCRUD | null => { | |
| if ( | |
| (node.id && node.id === id) || | |
| (node.tempId && node.tempId === tempId) | |
| ) { | |
| return null; | |
| } else { | |
| node.allChildren = node.allChildren | |
| .map((child) => deleteNode(child)) | |
| .filter(Boolean) as WBSProjectCRUD[]; | |
| return node; | |
| } | |
| }; | |
| setProjects( | |
| projects | |
| .map((project) => deleteNode(project)) | |
| .filter(Boolean) as WBSProjectCRUD[], | |
| ); | |
| }; | |
| const toggleExpand = (id: string, tempId: string) => { | |
| const toggleNode = (node: WBSProjectCRUD): WBSProjectCRUD => { | |
| if ( | |
| (node.id && node.id === id) || | |
| (node.tempId && node.tempId === tempId) | |
| ) { | |
| return { ...node, expand: !node.expand }; | |
| } else { | |
| node.allChildren = node.allChildren.map((child) => toggleNode(child)); | |
| return node; | |
| } | |
| }; | |
| setProjects(projects.map((project) => toggleNode(project))); | |
| }; | |
| return { | |
| projects, | |
| addProject, | |
| updateProject, | |
| deleteProject, | |
| toggleExpand, | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment