그룹웨어 만드는 과정중에 조직도 페이지를 위해 트리구조 화면단이 필요했다
라이브러리를 사용한다면 쉽게 만들순 있겠지만 라이브러리 없이도 만들수 있을 거 같아 그냥 만들어봤다
일단 트리구조를 위해선 당연하게도 트리구조 data가 필요하다
const initialTreeData = [
{
id: '1',
label: '(주)코스모스오피스',
depth: 0,
type: 'root',
expand: true,
children: [
{
id: '2',
label: '대표',
depth: 1,
type: 'department',
expand: false,
children: [
{
id: '3',
label: '김철수 대표',
depth: 2,
type: 'employee',
expand: false,
children: []
}
]
},
{
id: '4',
label: 'A 유닛',
depth: 1,
type: 'department',
expand: false,
children: []
},
{
id: '5',
label: 'B 유닛',
depth: 1,
type: 'department',
expand: false,
children: [
{
id: '6',
label: 'B1 팀',
depth: 2,
type: 'department',
expand: false,
children: [
{
id: '7',
label: '홍길동 팀장',
depth: 3,
type: 'employee',
expand: false,
children: []
},
{
id: '8',
label: '이순신 팀원',
depth: 3,
type: 'employee',
expand: false,
children: []
},
]
}
]
},
]
}
];
label에는 화면에 보여지게 될 이름,
depth는 계층형으로 css를 만들어 주기 위한 속성이 될것
type은 타입별로 label 옆에 보여지게 될 이미지를 조절하기 위해
expand는 초기 랜더링 시 펼쳐져있을지, 접혀있을지 결정하는 속성
Organization.jsx
import React, { useState } from 'react';
import style from '../SCSS/components/Organization.module.scss';
const TreeItem = ({ label, id, depth, type, expand, children }) => {
const [isExpanded, setIsExpanded] = useState(expand);
const toggleExpand = () => {
setIsExpanded(!isExpanded);
};
const getImagePath = () => {
if (type === 'department') {
return '/org/folder.svg';
} else if (type === 'employee') {
return '/org/human.svg';
} else {
return ''; // 다른 유형에 대한 이미지가 필요한 경우 여기에 추가
}
};
// root일때만 label 값만 출력하도록 수정
if (type === 'root') {
return (
<div style={{ marginLeft: `${depth * 20}px` }}>
{label}
{isExpanded && children && children.map(child => (
<TreeItem key={child.id} {...child} />
))}
</div>
);
}
// employee인 경우 클릭 이벤트 처리하지 않음
const handleClick = type === 'employee' ? null : toggleExpand;
return (
<div className={style.tree_item_wrapper} style={{ marginLeft: `${depth * 20}px` }}>
<div className={style.tree_item_box} onClick={handleClick}>
{type !== 'employee' && (isExpanded ? <img src='/org/minus.svg' /> : <img src='/org/plus.svg' />)} <img src={getImagePath()} alt={type} /> {label}
</div>
{isExpanded && children && children.map(child => (
<TreeItem key={child.id} {...child} />
))}
</div>
);
};
const Organization = ({ initialTreeData }) => {
return (
<div className={style.org_main}>
{initialTreeData.map(data => (
<TreeItem key={data.id} {...data} />
))}
</div>
);
};
export default Organization;
Organization이라는 컴포넌트를 구성하고
{departmentTree && <Organization initialTreeData={departmentTree} />}
미리 정의해둔 data 혹은 back단에서 받아온 데이터를 넘겨주는 식으로 구현
*db에는 계층형 데이터로 상위id 컬럼을 추가
결과물