Reputation: 2105
I'm trying to create a tree component. I'm working with a mocked data and using react to create this component.
I would like when is loaded by first time, show collapse all children of their first parents. To show collapse or not I add a class called collapsed that have display: none
like this:
<div className={`hierarchy ${level} ${isCollapsed() ? "collapsed" : ""}`}>
And function is this:
const isCollapsed = () => {
const index: number = hiddenBranchs.findIndex( (hiddenId: string) => hiddenId === branch.value);
return (index >=0) ? true : false;
};
When load first time call this function:
export const showCollapsed = (branch: IHierarchyBranch) => {
// Get parent Ids
const parentIds: Array<string> = getFirstChildrenIds(branch);
// Get all ids
const ids: Array<string> = getIdOfChildrens(branch);
// remove parent ids from all ids to load first branch with their first children
const idsWithoutParents: Array<string> = removeAllIdsContainedInOtherArray(
ids,
parentIds
);
return idsWithoutParents;
};
My problem is that I dont know how show collapsed and behaviour that show on picture. ( I hope, that with picture undertand me better I'm what I would like to do). I store ids on redux when I call this function:
const onUpdatedHiddenBranchs = (ids: Array<string>, show: boolean) => {
let items: Array<string> = [];
if (!show) {
items = [...hiddenBranchs, ...ids];
} else {
const copyItems: Array<string> = [...hiddenBranchs];
const duplicatedItems: Array<string> = findDuplicatedItems(
copyItems
);
items = copyItems.filter((item: string) => {
return !ids.includes(item);
});
items = [...items, ...duplicatedItems];
}
onUpdateHiddenBranchs(items);
};
Here is the data with I'm working:
export const smallData: any = {
value: "22-hierarchy",
label: "HIERARCHY",
type: "hierarchy",
id: 22,
children: [
{
label: "EXAMPLE LIST",
value: "4720-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4720,
parentId: null,
tag: null,
alarms: {
dmaId: 4720,
numAlarms: 0,
numSectorsWithAlarms: 2,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: false,
},
children: [
{
label: "Enric1",
value: "4838-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4838,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4838,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "Gran Abonado",
value: "12-tag",
icon: "tag",
favourite: false,
sensorizable: false,
id: 1,
parentId: 4838,
tag: null,
alarms: null,
children: [
{
label: "TAG_ING",
value: "4845-dma",
icon: "sensor",
favourite: false,
sensorizable: false,
id: 4845,
parentId: 4838,
tag: {
id: 1,
name: "Gran Abonado",
autogenerated: null,
},
alarms: {
dmaId: 4845,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
],
},
],
},
{
label: "Enric2",
value: "4839-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4839,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4839,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
{
label: "Enric3",
value: "4840-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4840,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4840,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
{
label: "Enric4",
value: "4841-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4841,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4841,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
{
label: "N1",
value: "4825-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4825,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4825,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
{
label: "N2",
value: "4826-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4826,
parentId: 4720,
tag: null,
alarms: {
dmaId: 4826,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "HIJO-1",
value: "4827-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4827,
parentId: 4826,
tag: null,
alarms: {
dmaId: 4827,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "NUEVO-NIVEL",
value: "4829-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4829,
parentId: 4827,
tag: null,
alarms: {
dmaId: 4829,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "Enric5",
value: "4842-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4842,
parentId: 4829,
tag: null,
alarms: {
dmaId: 4842,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "Otros",
value: "1-tag",
icon: "tag",
favourite: false,
sensorizable: false,
id: 5,
parentId: 4842,
tag: null,
alarms: null,
children: [
{
label: "TESTED",
value: "4843-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4843,
parentId: 4842,
tag: {
id: 5,
name: "Otros",
autogenerated: null,
},
alarms: {
dmaId: 4843,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
],
},
],
},
],
},
],
},
{
label: "HIJO-2",
value: "4828-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4828,
parentId: 4826,
tag: null,
alarms: {
dmaId: 4828,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [
{
label: "NUEVO-NIVEL",
value: "4830-dma",
icon: "dma",
favourite: false,
sensorizable: true,
id: 4830,
parentId: 4828,
tag: null,
alarms: {
dmaId: 4830,
numAlarms: 0,
numSectorsWithAlarms: 0,
codeAlarmList: null,
nameAlarmList: null,
showAlarm: null,
},
children: [],
},
],
},
],
},
],
},
],
};
And here is my component:
import React, { useState } from "react";
import { IHierarchyBranchProps, IHierarchyBranch } from "../main/interfaces";
import { getIdOfChildrens } from "../../utils/hierarhcy";
const HierarchyBranch = ({
id,
level,
label,
favourite,
icon,
children,
branch,
selectedId,
hiddenBranchs,
onUpdateSelectedBranch,
onUpdatedHiddenBranchs,
onUpdateFavourites,
renderHierarchyBranch,
}: IHierarchyBranchProps): JSX.Element => {
const [opened, setOpen] = useState<boolean>(true);
const onSelectDma = () => {
onUpdateSelectedBranch(id, branch);
};
const onOpenCloseTags = () => {
const show: boolean = !opened;
setOpen(show);
const ids: Array<string> = getIdOfChildrens(branch);
onUpdatedHiddenBranchs(ids, show);
};
const onUpdateFavorite = () => {
onUpdateFavourites(branch);
};
const isCollapsed = () => {
const index: number = hiddenBranchs.findIndex( (hiddenId: string) => hiddenId === branch.value);
return (index >=0) ? true : false;
};
return (
<>
<div
className={`go-hierarchy ${level} ${
isCollapsed() ? "collapsed" : ""
}`}
style={{ marginLeft: `${level * 15}px` }}
>
{branch.children && branch.children.length > 0 ? (
<div className="hirarchy-show" onClick={onOpenCloseTags}>
{opened ? (
<i className="icon-down-open" />
) : (
<i className="icon-right-open" />
)}
</div>
) : <div className="hierarchy-hidden"></div>}
<div
className={`go-hierarchy-branch ${
selectedId === id ? "active" : ""
} `}
onClick={onSelectDma}
>
{!icon ? (
<div className="hierarchy-branch-favourite">
{opened ? (
<i className="icon-folder-open-empty" />
) : (
<i className="icon-folder-empty" />
)}
</div>
) : (
<>
{icon === "tag" ? (
<div className="hierarchy-branch-favourite">
<i className="icon-tag" />
</div>
) : (
<div
className="hierarchy-branch-favourite"
onClick={onUpdateFavorite}
>
{!favourite ? (
<i className="icon-bookmark-empty" />
) : (
<i className="icon-bookmark" />
)}
</div>
)}
</>
)}
<div className="hierarchy-branch-title">
<label>{label}</label>
</div>
</div>
</div>
{children &&
children.length > 0 &&
children.map((child: IHierarchyBranch, index: number) => {
return renderHierarchyBranch(index, child);
})}
</>
);
};
export default HierarchyBranch;
Upvotes: 1
Views: 260
Reputation: 98
Please the below, it will help you understanding clear. In this way you can get collapsed view.
class App extends React.Component {
state = { data: tree };
render() {
return (
<div>
<div className='example-config'>
<button onClick={this.expandAll} className='k-button'>Expand all</button>
<button onClick={this.collapseAll} className='k-button'>Collapse all</button>
</div>
<TreeView data={this.state.data} expandIcons={true} onExpandChange={this.onExpandChange} />
</div>
);
}
expandAll = () => {
this.setState({
data: this.state.data.map(item => Object.assign({}, item, { expanded: true }))
});
}
collapseAll = () => {
this.setState({
data: this.state.data.map(item => Object.assign({}, item, { expanded: false }))
});
}
onExpandChange = (event) => {
const data = this.state.data.slice();
const itemIndex = data.indexOf(event.item);
data[itemIndex] = { ...event.item };
data[itemIndex].expanded = !data[itemIndex].expanded;
this.setState({ data });
}
}
const tree = [
{ text: 'Item1', items: [{ text: 'Item1.1' }, { text: 'Item1.2' }] },
{ text: 'Item2', items: [{ text: 'Item2.1' }, { text: 'Item2.2' }] },
{ text: 'Item3', items: [{ text: 'Item3.1' }, { text: 'Item3.2' }] },
{ text: 'Item4', items: [{ text: 'Item4.1' }, { text: 'Item4.2' }] },
{ text: 'Item5', items: [{ text: 'Item5.1' }, { text: 'Item5.2' }] },
{ text: 'Item6', items: [{ text: 'Item6.1' }, { text: 'Item6.2' }] }
];
ReactDOM.render(
<App />,
document.querySelector('my-app')
);
Upvotes: 1