Это должно работать. Это было немного сложнее, чем я думал изначально, ха-ха. ?
Вам нужно преобразовать во вложенную структуру данных, а затем рекурсивно отобразить ее, чтобы получить желаемый результат:
Полная демонстрация ниже и здесь: https://codepen.io/Alexander9111/pen/pojXBWX
function MyTable(props) {
const initState = [
{
Level: 1,
"Type of activity": "Consolidated task",
ID: 118027222233,
Name: "Name 1"
},
{
Level: 2,
"Type of activity": "Consolidated task",
ID: 118636886633,
Name: "Name 2"
},
{
Level: 3,
"Type of activity": "Consolidated task",
ID: 118637048333,
Name: "Name 3"
},
{
Level: 4,
"Type of activity": "task",
ID: 118637035433,
Name: "Name 4"
},
{
Level: 4,
"Type of activity": "task",
ID: 118841127933,
Name: "Name 5"
},
{
Level: 4,
"Type of activity": "task",
ID: 118841156833,
Name: "Name 6"
},
{
Level: 3,
"Type of activity": "Consolidated task",
ID: 118637046733,
Name: "Name 9"
},
{
Level: 4,
"Type of activity": "Consolidated task",
ID: 118744514633,
Name: "Name 10"
},
{
Level: 5,
"Type of activity": "task",
ID: 118637033033,
Name: "Name 11"
},
{
Level: 5,
"Type of activity": "task",
ID: 118637031033,
Name: "Name 13"
},
{
Level: 2,
"Type of activity": "Consolidated task",
ID: 118636886633,
Name: "Name 19"
},
{
Level: 3,
"Type of activity": "task",
ID: 118637048333,
Name: "Name 20"
},
{
Level: 3,
"Type of activity": "task",
ID: 118637048333,
Name: "Name 21"
},
{
Level: 2,
"Type of activity": "Consolidated task",
ID: 128637048333,
Name: "Name 22"
},
{
Level: 3,
"Type of activity": "task",
ID: 138637048333,
Name: "Name 23"
},
{
Level: 1,
"Type of activity": "Consolidated task",
ID: 148637048333,
Name: "Name 24"
},
{
Level: 2,
"Type of activity": "task",
ID: 158637048333,
Name: "Name 25"
}
];
const [state, setState] = React.useState(initState);
const table = (
<table>
<tr key={"header"}>
{Object.keys(state[0]).map((key) => (
<th>{key}</th>
))}
</tr>
{state.map((item) => (
<tr key={item.id}>
{Object.values(item).map((val) => (
<td>{val}</td>
))}
</tr>
))}
</table>
);
let currPointer = null;
const listOfPointers = [];
const nestedArrs = state.reduce((aggArr, item) => {
//console.log(listOfPointers)
if (item.Level == 1) {
aggArr.push(item);
}
else if (item.Level > currPointer.Level) {
currPointer.children.push(item);
}
else if (item.Level <= currPointer.Level) {
while (item.Level <= currPointer.Level) {
listOfPointers.pop();
currPointer = listOfPointers[listOfPointers.length - 1];
}
currPointer.children.push(item);
}
item.children = [];
currPointer = item;
listOfPointers.push(currPointer);
return aggArr;
}, []);
//console.log(nestedArrs);
const nestedDivs = (
<div>
{(function mapChildren(data) {
return data.map((d, i) => {
if (d["Type of activity"] != "task") {
return (
<div className={"level_" + d.Level}>
<span>{d.Level + " : " + d.Name}</span>
{mapChildren(d.children)}
</div>
);
} else {
return (
<div className={"level_" + d.Level + " task"}>
<span>{d.Level + " : " + d.Name}</span>
</div>
);
}
});
})(nestedArrs)}
</div>
);
//console.log(nestedDivs);
return (
<div>
{table}
{nestedDivs}
</div>
);
}
ReactDOM.render(<MyTable />, document.getElementById("target"));
th,
td {
border: 1px solid black;
margin: 0px 0px;
padding: 5px 5px;
}
div {
padding: 10px;
margin: 10px;
}
.level_1 {
background-color: blue;
}
.level_2 {
background-color: orange;
}
.level_3 {
background-color: green;
}
.level_4 {
background-color: yellow;
}
.task {
background-color: white !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="target"></div>
Ввод:
Выход: