Skip to content

Commit

Permalink
#72: Home page beside tasks gets user data
Browse files Browse the repository at this point in the history
User data in Home grid is not hard coded anymore.
Enabled One to Many relationshipin Task / User Models
User can now change a status of task by clicking status chip
  • Loading branch information
Blagoja95 authored and ogi1998 committed Feb 13, 2024
1 parent 7363215 commit 4dc60bc
Show file tree
Hide file tree
Showing 21 changed files with 406 additions and 288 deletions.
1 change: 1 addition & 0 deletions app/web/src/components/layout/header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const Header = ({ titleTxt, subtitleTxt }) =>
const dispatch = useDispatch();
const refUser = useRef(null);
const open = useSelector(state => state.ui.userMenuOpen);

return <Box
sx={ {
p: '1rem',
Expand Down
2 changes: 1 addition & 1 deletion app/web/src/components/layout/navigation/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Navigation = () => {
'& .MuiPaper-root':
{
bgcolor: 'gray.dark',
position: 'relative',
position: 'sticky',
overflowX: 'hidden',
height: '100vh',
'&::-webkit-scrollbar': {
Expand Down
23 changes: 4 additions & 19 deletions app/web/src/components/pages/home/HomeController.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const HomeController = () =>
const btoken = useSelector(state => state.user.btoken);
const nav = useNavigate();

const createTaskRedirect = () => nav('create/task?id=' + selectedTeam.id);
const createTaskRedirect = () => nav('tasks/create/' + selectedTeam.id);

const handeValChange = (e, val, reason) =>
{
Expand All @@ -20,7 +20,7 @@ const HomeController = () =>
dispatch(teamActions.setTeamStats(null));
dispatch(teamActions.setTeamTasks([]));
}
}
};

const getCount = async (teamId) =>
{
Expand All @@ -34,27 +34,12 @@ const HomeController = () =>
}
})
.catch(e => dispatch(teamActions.setTeamStats(null)));
}

const getTasks = async (teamId) =>
{
axios.get('http://localhost:8080/tasks/team/' + (teamId ?? -1),
{ headers: {"Authorization" : `Bearer ${btoken}`} })
.then(res =>
{
if (res.status === 200 && res.data.status)
{
dispatch(teamActions.setTeamTasks(res.data.data))
}
})
.catch(e => dispatch(teamActions.setTeamTasks([])));
}
};

return {
createTaskRedirect,
handeValChange,
getCount,
getTasks
getCount
}
}

Expand Down
260 changes: 58 additions & 202 deletions app/web/src/components/ui/grid/Grid.js
Original file line number Diff line number Diff line change
@@ -1,209 +1,65 @@
import { useEffect, useState } from 'react';
import { Box, Chip, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination } from '@mui/material';
import { Paper, Table, TableBody, TableContainer, TableHead, TablePagination } from '@mui/material';
import { useSelector } from 'react-redux';
import GridController from "./GridController";

import UserAvatar from '../avatar/UserAvatar';
import { useSelector } from "react-redux";

const dummyData = [ // TODO: remove later
{ user: { name: 'Marko Markovic', id: 221, src: 'https://randomuser.me/api/portraits/men/73.jpg' }, statusT: 1 },
{ user: { name: 'Janko Jankovic', id: 222 }, statusT: 2 },
{ user: { name: 'Jovana Jovanovic', id: 223, src: 'https://randomuser.me/api/portraits/women/31.jpg' }, statusT: 3 },
{ user: { name: 'Ljubo Kobas', id: 224 }, statusT: 0 },
{ user: { name: 'Jovan Jovanovic', id: 225 }, statusT: 3 },
{ user: { name: 'Petar Petrovic', id: 225 }, statusT: 3},
{ user: { name: 'Pero Peric', id: 225 }, statusT: 3 },
{ user: { name: 'Marko Markovic', id: 225 }, statusT: 1 },
{ user: { name: 'Nikola Nikola', id: 225 }, statusT: 2 },
{ user: { name: 'Test name', id: 225 }, statusT: 0 },
{ user: { name: 'Name shit', id: 225 }, statusT: 0 },
{ user: { name: 'Johan all', id: 225 }, statusT: 1 },
{ user: { name: 'Jovo Bar', id: 225 }, statusT: 3 },
{ user: { name: 'Marsal Peter', id: 225 }, statusT: 2 },
{ user: { name: 'Johna Hill', id: 225 }, statusT: 2 },
{ user: { name: 'Margaret Roby', id: 225 }, statusT: 3 }
];

const status = {
0: {
name: 'Not started',
color: 'secondary'
},
1: {
name: 'In progress',
color: 'primary',
},
2: {
name: 'Review',
color: 'warning'
},
3: {
name: 'Done',
color: 'success'
}
};

const rowsPerPageOptions = [5, 10, 25];

export const checkGridType = (input) =>
{
if (!input || typeof input !== 'string')
const Grid = ({ gridType = 'tasks', teamId }) =>
{
return false
}

const gridTypes = new Set([
'tasks',
'teams',
'users'
]);

return gridTypes.has(input);
};

export const getTableHeader = (type) =>
{
if (!checkGridType(type))
{
return <TableRow/>
}

switch (type)
{
case 'tasks':
return <TableRow>
<TableCell align='left'>
Task
</TableCell>

<TableCell align='left'>
Deadline
</TableCell>

<TableCell align='left'>
Status
</TableCell>

<TableCell>
Assigned to
</TableCell>
</TableRow>

default:
break;
}
};

export const getTableRows = (type, rows) =>
{
if (!checkGridType(type))
{
return <TableRow/>
}

return rows.map((row, i) =>

<TableRow
key={ row.id + '-task-' + row.title }
sx={ { '&:last-child td, &:last-child th': { border: 0 } } }
>
<TableCell align='left' sx={ {
fontWeight: 'bold'
const rowsPerPageOptions = [ 5, 10, 25 ];
const [ page, setPage ] = useState(0);
const [ rowsPerPage, setRowsPerPage ] = useState(rowsPerPageOptions[0]);

const controller = GridController();

useEffect(() =>
{
controller.getData(teamId);
}, [ teamId ]);

const handleChangePage = (event, newPage) =>
{
setPage(newPage);
};

const handleChangeRowsPerPage = event =>
{
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

const data = useSelector(state => state.team.teamTasks);

const slicedData = data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);

return <TableContainer
component={ Paper }
sx={ {
minHeight: 500,
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between'
} }>
{ row.title }
</TableCell>


<TableCell
align='left'>
{ row.deadline }
</TableCell>

<TableCell align='left'>
<Chip color={ status[row.status].color }
label={ status[row.status].name }
sx={ {
width: 100
} }/>
</TableCell>

<TableCell> {/* TODO: when users URI is available change this*/}
<Box
sx={ {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
gap: 3
} }>
<UserAvatar data={ {
name: dummyData[i].user.name,
src: dummyData[i].user.src
} }
sx={ {
width: 44,
height: 44
} }/>

<Box
container={ 'span' }>
{ dummyData[i].user.name }
</Box>
</Box>
</TableCell>
</TableRow>
);
}

const Grid = ({ gridType = 'tasks' , teamId, controller}) =>
{
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageOptions[0]);

useEffect(() =>
{
controller.getTasks(teamId);
}, [teamId]);

const handleChangePage = (event, newPage) => {
setPage(newPage);
};

const handleChangeRowsPerPage = event => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
<Table>
<TableHead>
{ controller.getTableHeader(gridType) }
</TableHead>

<TableBody>
{ controller.getTableRows(gridType, slicedData) }
</TableBody>
</Table>

<TablePagination
rowsPerPageOptions={ rowsPerPageOptions }
component='div'
count={ data.length }
rowsPerPage={ rowsPerPage }
page={ page }
onPageChange={ handleChangePage }
onRowsPerPageChange={ handleChangeRowsPerPage }
/>
</TableContainer>
};

const data = useSelector(state => state.team.teamTasks);
const slicedData = data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);

return <TableContainer
component={ Paper }
sx={{
minHeight: 500,
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between'
}}>

<Table>
<TableHead>
{ getTableHeader(gridType) }
</TableHead>

<TableBody>
{ getTableRows(gridType, slicedData) }
</TableBody>
</Table>

<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component='div'
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</TableContainer>
};

export default Grid;
export default Grid;
Loading

0 comments on commit 4dc60bc

Please sign in to comment.