Мне нужно предварительно обработать данные, поступающие из API. Необработанные данные имеют следующий формат:
I want to dynamically build a Table, in which the columns should be created using fields task_name
and saved_answers
. Please notice that saved_answers
may contain different sub-fields depending on the task_name
. In other words, saved_answers
does not always contain value21
, value22
, value23
and value24
.
Below I show an example of a table.
============================================================================================================
| user_id | task11-value21 | task11-value22 | task11-value23 | task11-value24 | task13-valueMu...
============================================================================================================
| 111 | 1 | 1 | 1 | 1 | 5
...
So far I only can retrieve the data from API and show specific columns in the table. I would highly appreciate any help. Thanks.
import React, { useEffect } from 'react'
import { makeStyles } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';
import axios from 'axios'
import config from '../../config/config.json';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
},
heading: {
fontSize: theme.typography.pxToRem(18),
fontWeight: theme.typography.fontWeightBold,
},
content: {
fontSize: theme.typography.pxToRem(14),
fontWeight: theme.typography.fontWeightRegular,
textAlign: "left",
marginTop: theme.spacing.unit*3,
marginLeft: theme.spacing.unit*3,
marginRight: theme.spacing.unit*3
},
table: {
minWidth: 650,
},
tableheader: {
fontWeight: theme.typography.fontWeightBold,
color: "#ffffff",
background: "#3f51b5"
}
}));
export function Main() {
const [groupKey,setGroupKey] = React.useState([]);
const classes = useStyles();
const options = {
'headers': {
'Authorization': `Bearer ${localStorage.getItem('accessToken')}`
}
}
useEffect(() => {
axios.get(config.api.url + '/api/test', options)
.then( (groups) => {
setGroupKey(groups);
console.log(groups);
})
.catch( (error) => {
console.log(error);
})
}, []);
return (
Group
Task name
{groupKey.map( (row, index) => (
{row.user_id} {row.task_name} ))} )}
ОБНОВЛЕНИЕ:
import '../../App.css';
import React, { useEffect } from 'react'
import PropTypes from 'prop-types';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import TablePagination from '@material-ui/core/TablePagination';
import TableFooter from '@material-ui/core/TableFooter';
import IconButton from '@material-ui/core/IconButton';
import FirstPageIcon from '@material-ui/icons/FirstPage';
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
import LastPageIcon from '@material-ui/icons/LastPage';
import Paper from '@material-ui/core/Paper';
import axios from 'axios'
import config from '../../config/config.json';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
},
heading: {
fontSize: theme.typography.pxToRem(18),
fontWeight: theme.typography.fontWeightBold,
},
content: {
fontSize: theme.typography.pxToRem(14),
fontWeight: theme.typography.fontWeightRegular,
textAlign: "left",
marginTop: theme.spacing.unit*3,
marginLeft: theme.spacing.unit*3,
marginRight: theme.spacing.unit*3
},
table: {
minWidth: 650,
},
tableheader: {
fontWeight: theme.typography.fontWeightBold,
color: "#ffffff",
background: "#3f51b5"
},
tableCell: {
color: "#000000",
background: "#ffffff"
},
button: {
fontSize: "12px",
minWidth: 100
},
}));
function TablePaginationActions(props) {
const classes = useStyles();
const theme = useTheme();
const { count, page, rowsPerPage, onChangePage } = props;
const handleFirstPageButtonClick = (event) => {
onChangePage(event, 0);
};
const handleBackButtonClick = (event) => {
onChangePage(event, page - 1);
};
const handleNextButtonClick = (event) => {
onChangePage(event, page + 1);
};
const handleLastPageButtonClick = (event) => {
onChangePage(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};
return (
<div className={classes.root}>
<IconButton
onClick={handleFirstPageButtonClick}
disabled={page === 0}
aria-label="first page"
>
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
</IconButton>
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
</IconButton>
<IconButton
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
</IconButton>
<IconButton
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
</IconButton>
</div>
);
}
function getGridHeader(config) {
const gridHeader = ["user_id"];
console.log(config);
const savedAnswers = Object.keys(JSON.parse(config.saved_answers));
savedAnswers.map(savedAnswer => {
gridHeader.push(`${config.task_name}-${savedAnswer}`)
});
return gridHeader;
}
function getGridData(config) {
const gridData = [config.user_id];
const savedAnswers = JSON.parse(config.saved_answers);
Object.keys(savedAnswers).map( savedAnswer => {
gridData.push(savedAnswers[savedAnswer]);
});
return gridData;
}
TablePaginationActions.propTypes = {
count: PropTypes.number.isRequired,
onChangePage: PropTypes.func.isRequired,
page: PropTypes.number.isRequired,
rowsPerPage: PropTypes.number.isRequired,
};
export function Main() {
const [groupKey,setGroupKey] = React.useState([]);
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
const emptyRows = rowsPerPage - Math.min(rowsPerPage, groupKey.length - page * rowsPerPage);
const gridHeader = getGridHeader(groupKey);
const gridData = getGridData(groupKey);
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const classes = useStyles();
const options = {
'headers': {
'Authorization': `Bearer ${localStorage.getItem('accessToken')}`
}
}
useEffect(() => {
axios.get(config.api.url + '/api/test', options)
.then( (groups) => {
setGroupKey(groups.data.subtask);
})
.catch( (error) => {
console.log(error);
})
}, []);
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12} className={classes.content}>
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow className={classes.tableheader}>
{gridHeader.map( (headerTitle, index) => (
<TableCell key={index}>{headerTitle}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{(rowsPerPage > 0
? gridData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: gridData
).map((cellValue, index) => (
<TableRow key={index} selected="false">
<TableCell className={classes.tableCell}component="th" scope="row">{cellValue}</TableCell>
</TableRow>
))}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
colSpan={3}
count={groupKey.length}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
inputProps: { 'aria-label': 'groups per page' },
native: true,
}}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
</Grid>
</Grid>
</div>
)
}