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:
committed by
GitHub
parent
ff9ea9c71c
commit
4c2df3fd2c
@@ -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'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
54
src/redux/RolesRedux.js
Normal 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
|
||||||
|
});
|
||||||
@@ -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
30
src/sagas/Roles.js
Normal 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)];
|
||||||
@@ -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]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user