Feat: List roles page (WMS-40) (#55)

* feat: list roles page with api integration
* Update: added dispatch on first load
This commit is contained in:
Sathishkumar Krishnan
2022-02-11 22:55:54 +05:30
committed by GitHub
parent ff9ea9c71c
commit 4c2df3fd2c
6 changed files with 186 additions and 30 deletions

View File

@@ -2,5 +2,6 @@ export default {
LOGIN_USER: '/user/login', LOGIN_USER: '/user/login',
GET_WAREHOUSE_DATA: '/warehouse/all?page=0&perPage=50', GET_WAREHOUSE_DATA: '/warehouse/all?page=0&perPage=50',
CREATE_WAREHOUSE: '/warehouse/', CREATE_WAREHOUSE: '/warehouse/',
GET_USERS_DATA: '/user/all?page=0&perPage=10' GET_USERS_DATA: '/user/all?page=0&perPage=10',
GET_ROLES_DATA: '/user-role/all?page=0&perPage=10'
}; };

View File

@@ -1,4 +1,4 @@
import React, { useEffect } from 'react'; import React, { useEffect, useMemo } from 'react';
import MDBox from 'components/MDBox'; import MDBox from 'components/MDBox';
import DashboardNavbar from 'components/DashboardNavbar'; import DashboardNavbar from 'components/DashboardNavbar';
import Footer from 'components/Footer'; import Footer from 'components/Footer';
@@ -13,10 +13,10 @@ import MDButton from 'components/Button';
import { useState } from 'react'; import { useState } from 'react';
import { Tabs, Tab } from '@mui/material'; import { Tabs, Tab } from '@mui/material';
import TabPanel from 'components/Tabs'; import TabPanel from 'components/Tabs';
import UsersActions from 'redux/UsersRedux'; import UsersActions, { UsersSelectors } from 'redux/UsersRedux';
import RolesActions, { RolesSelectors } from 'redux/RolesRedux';
import { API } from 'constant'; import { API } from 'constant';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { UsersSelectors } from 'redux/UsersRedux';
import moment from 'moment'; import moment from 'moment';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
@@ -51,34 +51,36 @@ const useStyles = makeStyles((theme) => ({
} }
} }
})); }));
const headCells = [ const userHeadCells = [
{ id: 'fullName', label: 'Name' }, { id: 'fullName', label: 'Name' },
{ id: 'role_name', label: 'Roles' }, { id: 'role_name', label: 'Roles' },
{ id: 'updated_at', label: 'Updated at' }, { id: 'updated_at', label: 'Updated at' },
{ id: 'created_at', label: 'Created by and at' } { id: 'created_at', label: 'Created by and at' }
]; ];
const rolesHeadCells = [
{ id: 'role', label: 'Role' },
{ id: 'permissions', label: 'Permissions' },
{ id: 'status', label: 'Status' }
];
// const permissionsHeadCells = [
// { id: 'permission', label: 'Permission' },
// { id: 'warehouse', label: 'Warehouse' },
// { id: 'inventories', label: 'Inventories' },
// { id: 'actions', label: 'Actions' },
// { id: 'app_modules', label: 'App Modules' },
// { id: 'status', label: 'Status' }
// ];
function UserAccessScreen() { function UserAccessScreen() {
const classes = useStyles(); const classes = useStyles();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [value, setValue] = useState(0); const [value, setValue] = useState(0);
const usersData = useSelector(UsersSelectors.getUsersDetail); const usersData = useSelector(UsersSelectors.getUsersDetail);
const [records, setRecords] = useState([]); const rolesData = useSelector(RolesSelectors.getRolesDetail);
const [userRecords, setUserRecords] = useState([]);
useEffect(() => { const [rolesRecords, setRoleRecords] = useState([]);
if (usersData.length) {
let users = JSON.parse(JSON.stringify(usersData));
users = users.map((item) => {
item.role_name = item.roles.map((role) => role.name).join(',');
return item;
});
setRecords(users);
}
}, [usersData]);
const handleTabs = (e, val) => {
setValue(val);
};
const usersHandler = () => { const usersHandler = () => {
dispatch( dispatch(
@@ -90,6 +92,50 @@ function UserAccessScreen() {
); );
}; };
const rolesHandler = () => {
dispatch(
RolesActions.getRolesAction({
loader: 'loading-request',
slug: API.GET_ROLES_DATA,
method: 'get'
})
);
};
useMemo(() => rolesHandler(), []);
useEffect(() => {
if (usersData.length) {
let users = JSON.parse(JSON.stringify(usersData));
users = users.map((item) => {
item.role_name = item.roles.map((role) => role.name).join(',');
return item;
});
setUserRecords(users);
}
if (rolesData.length) {
let roles = JSON.parse(JSON.stringify(rolesData));
roles = roles.map((item) => {
item.name = item.name.split('-').join(' ').toUpperCase();
item.permissions = item.permissions.map((permission) => permission.name).join(',');
if (!item.permissions) {
item.permissions = 'NA';
}
item.status = 'INACTIVE';
if (item.status) {
item.status = 'ACTIVE';
}
return item;
});
setRoleRecords(roles);
}
}, [rolesData, usersData]);
const handleTabs = (e, val) => {
setValue(val);
};
const StyledTableRow = styled(TableRow)(({ theme }) => ({ const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(even)': { '&:nth-of-type(even)': {
backgroundColor: theme.palette.action.hover backgroundColor: theme.palette.action.hover
@@ -103,7 +149,7 @@ function UserAccessScreen() {
<Grid container spacing={2} className={classes.margin}> <Grid container spacing={2} className={classes.margin}>
<Grid item xs={12} sm={4} md={4}> <Grid item xs={12} sm={4} md={4}>
<Tabs value={value} className={classes.tabs} onChange={handleTabs}> <Tabs value={value} className={classes.tabs} onChange={handleTabs}>
<Tab label="Roles" /> <Tab label="Roles" onClick={() => rolesHandler()} />
<Tab label="Users" onClick={() => usersHandler()} /> <Tab label="Users" onClick={() => usersHandler()} />
</Tabs> </Tabs>
</Grid> </Grid>
@@ -117,18 +163,39 @@ function UserAccessScreen() {
</Grid> </Grid>
</Grid> </Grid>
<TabPanel value={value} index={0}> <TabPanel value={value} index={0}>
<div className={classes.marginTable}>Item2 Detail</div>
</TabPanel>
<TabPanel value={value} index={1}>
<BasicTable <BasicTable
headCells={headCells} headCells={rolesHeadCells}
records={records} records={rolesRecords}
backgroundColor="#007AFF" backgroundColor="#007AFF"
color="#fff" color="#fff"
> >
<TableBody> <TableBody>
{records && {rolesRecords &&
records.map((item) => ( rolesRecords.map((item) => (
<StyledTableRow key={item.id}>
<TableCell>
<div className={classes.iconwrap}>
<EditIcon className={classes.iconSize} />
{item.name}
</div>
</TableCell>
<TableCell>{item.permissions}</TableCell>
<TableCell>{item.status}</TableCell>
</StyledTableRow>
))}
</TableBody>
</BasicTable>
</TabPanel>
<TabPanel value={value} index={1}>
<BasicTable
headCells={userHeadCells}
records={userRecords}
backgroundColor="#007AFF"
color="#fff"
>
<TableBody>
{userRecords &&
userRecords.map((item) => (
<StyledTableRow key={item.id}> <StyledTableRow key={item.id}>
<TableCell> <TableCell>
<div className={classes.iconwrap}> <div className={classes.iconwrap}>

54
src/redux/RolesRedux.js Normal file
View File

@@ -0,0 +1,54 @@
import { createActions, createReducer } from 'reduxsauce';
import Immutable from 'seamless-immutable';
import _ from 'underscore';
import { getFetchingValue, getErrorValue } from '../services/Utils';
/* ------------- Types and Action Creators ------------- */
const { Types, Creators } = createActions({
getRolesAction: ['payload'],
getRolesSuccess: ['data'],
getRolesFailure: ['error']
});
export const RolesTypes = Types;
const RolesActions = Creators;
export default RolesActions;
/* ------------- Initial State ------------- */
export const INITIAL_STATE = Immutable({
rolesDetail: [],
rolesLoading: false,
roleserror: {}
});
/* ------------- Selectors ------------- */
export const RolesSelectors = {
getRolesDetail: (state) => state.roles.rolesDetail
};
/* ------------- Reducers ------------- */
export const onGetRolesAction = (state, { payload }) =>
state.merge({
fetching: _.uniq([state.fetching, payload?.loader]),
error: getErrorValue(state?.error, payload?.loader)
});
export const onGetRolesSuccess = (state, { data }) =>
state.merge({
fetching: getFetchingValue(state.fetching, data?.loader),
error: getErrorValue(state?.error, data?.loader),
rolesDetail: data.rolesDetail
});
export const onGetRolesFailure = (state, { error }) =>
state.merge({
fetching: _.without(state.fetching, error?.loader),
error: { ...state.error, [error?.loader]: error?.error }
});
/* ------------- Hookup Reducers To Types ------------- */
export const rolesReducer = createReducer(INITIAL_STATE, {
[Types.GET_ROLES_ACTION]: onGetRolesAction,
[Types.GET_ROLES_SUCCESS]: onGetRolesSuccess,
[Types.GET_ROLES_FAILURE]: onGetRolesFailure
});

View File

@@ -2,12 +2,14 @@ import { combineReducers } from 'redux';
import { authReducer } from './AuthRedux'; import { authReducer } from './AuthRedux';
import { warehouseReducer } from './WarehouseRedux'; import { warehouseReducer } from './WarehouseRedux';
import { usersReducer } from './UsersRedux'; import { usersReducer } from './UsersRedux';
import { rolesReducer } from './RolesRedux';
// Combine all reducers. // Combine all reducers.
const appReducer = combineReducers({ const appReducer = combineReducers({
auth: authReducer, auth: authReducer,
warehouse: warehouseReducer, warehouse: warehouseReducer,
users: usersReducer users: usersReducer,
roles: rolesReducer
}); });
const rootReducer = (state, action) => { const rootReducer = (state, action) => {

30
src/sagas/Roles.js Normal file
View File

@@ -0,0 +1,30 @@
import { AuthorizedAPI } from 'config';
import { takeLatest, call, put } from 'redux-saga/effects';
import RolesActions, { RolesTypes } from '../redux/RolesRedux';
import ApiServices from 'services/API/ApiServices';
export function* onRequestRolesData({ payload }) {
const response = yield call(
ApiServices[payload?.method],
AuthorizedAPI,
payload?.slug,
payload?.data
);
if (response?.status === 200) {
yield put(
RolesActions.getRolesSuccess({
loader: payload?.loader,
rolesDetail: response?.data?.data
})
);
} else {
payload.onFailedRolesData(response.data.error);
yield put(
RolesActions.getRolesFailure({
loader: payload?.loader,
error: response?.data
})
);
}
}
export default [takeLatest(RolesTypes.GET_ROLES_ACTION, onRequestRolesData)];

View File

@@ -2,9 +2,11 @@ import { all } from 'redux-saga/effects';
import AuthSaga from './Auth'; import AuthSaga from './Auth';
import WarehouseSaga from './Warehouse'; import WarehouseSaga from './Warehouse';
import UsersSaga from './Users'; import UsersSaga from './Users';
import RolesSaga from './Roles';
export default function* rootSaga() { export default function* rootSaga() {
yield all([...AuthSaga]); yield all([...AuthSaga]);
yield all([...WarehouseSaga]); yield all([...WarehouseSaga]);
yield all([...UsersSaga]); yield all([...UsersSaga]);
yield all([...RolesSaga]);
} }