forked from ddrilling/asb_cloud_front
Добавлена страница редактирования прав
This commit is contained in:
parent
78c7f78935
commit
b0d8126808
123
src/pages/AdminPanel/PermissionBits.jsx
Normal file
123
src/pages/AdminPanel/PermissionBits.jsx
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import { Button, Modal, Select } from 'antd'
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { EditableTable, makeColumn } from '../../components/Table'
|
||||||
|
|
||||||
|
export const toHexString = (num, size) => '0x' + ('0'.repeat(size) + num.toString(16).toUpperCase()).slice(-size)
|
||||||
|
|
||||||
|
const bitCount = 32
|
||||||
|
const bitOptions = [...Array(bitCount).keys()].map((n) => ({
|
||||||
|
label: toHexString(1 << n, bitCount / 4),
|
||||||
|
value: n,
|
||||||
|
}))
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
makeColumn('Бит', 'bit', {
|
||||||
|
// initialValue: bitOptions[0]?.value ?? '--',
|
||||||
|
input: <Select options={bitOptions} />,
|
||||||
|
render: (value) => bitOptions.find(option => option?.value === value)?.label ?? '--',
|
||||||
|
width: 200,
|
||||||
|
editable: true,
|
||||||
|
formItemRules: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Пожалуйста, выберите бит'
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
makeColumn('Описание', 'description', {
|
||||||
|
width: 400,
|
||||||
|
editable: true,
|
||||||
|
formItemRules: [{
|
||||||
|
required: true,
|
||||||
|
message: 'Пожалуйста, введите описание'
|
||||||
|
}],
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
|
||||||
|
export const PermissionBits = React.memo(({ value, onChange }) => {
|
||||||
|
const [isModalVisible, setIsModalVisible] = useState(false)
|
||||||
|
const [bits, setBits] = useState([])
|
||||||
|
// const [columns, setColumns] = useState([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setBits(Object.entries(value ?? {}).map(([bit, description]) => ({ bit, description })))
|
||||||
|
}, [value])
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const options = bitOptions.filter((option) => !(bits?.length && bits.find((row) => row.bit === option.value)))
|
||||||
|
// const defaultValue = options?.[0]?.label ?? '--'
|
||||||
|
|
||||||
|
// setColumns([
|
||||||
|
// makeColumn('Бит', 'bit', {
|
||||||
|
// initialValue: options?.[0]?.value ?? 0,
|
||||||
|
// input: <Select options={options} />,
|
||||||
|
// render: (value) => bitOptions.find(option => option?.value === value)?.label ?? defaultValue,
|
||||||
|
// width: 200,
|
||||||
|
// editable: true,
|
||||||
|
// formItemRules: [{ required: true, message: 'Пожалуйста, выберите бит' }],
|
||||||
|
// }),
|
||||||
|
// makeColumn('Описание', 'description', {
|
||||||
|
// width: 400,
|
||||||
|
// editable: true,
|
||||||
|
// formItemRules: [{ required: true, message: 'Пожалуйста, введите описание' }],
|
||||||
|
// }),
|
||||||
|
// ])
|
||||||
|
// }, [bits])
|
||||||
|
|
||||||
|
const saveBits = () => {
|
||||||
|
const newValue = {}
|
||||||
|
bits.forEach(({bit, description}) => (newValue[bit] = description))
|
||||||
|
if(!onChange(newValue))
|
||||||
|
setIsModalVisible(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addNewBit = (bit) => {
|
||||||
|
bit.key = Date.now()
|
||||||
|
setBits((prevBits) => [...(prevBits ?? []), bit])
|
||||||
|
}
|
||||||
|
|
||||||
|
const editBit = (bit) => {
|
||||||
|
if (!bit.key) return
|
||||||
|
const idx = bits.findIndex(v => v.key === bit.key)
|
||||||
|
if (idx < 0) return
|
||||||
|
setBits((prevBits) => {
|
||||||
|
prevBits[idx] = bit
|
||||||
|
return prevBits
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeBit = (bit) => {
|
||||||
|
if (!bit.key) return
|
||||||
|
const idx = bits.findIndex(v => v.bit === bit.bit)
|
||||||
|
if (idx < 0) return
|
||||||
|
setBits((prevBits) => {
|
||||||
|
prevBits.splice(idx, 1)
|
||||||
|
return prevBits
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button type={'link'} onClick={() => setIsModalVisible(true)}>Редактировать</Button>
|
||||||
|
<Modal
|
||||||
|
title={'Описание битов'}
|
||||||
|
centered
|
||||||
|
visible={isModalVisible}
|
||||||
|
width={750}
|
||||||
|
onCancel={() => setIsModalVisible(false)}
|
||||||
|
onOk={saveBits}
|
||||||
|
okText={'Сохранить'}
|
||||||
|
>
|
||||||
|
<EditableTable
|
||||||
|
size={'small'}
|
||||||
|
bordered
|
||||||
|
columns={columns}
|
||||||
|
dataSource={bits}
|
||||||
|
onRowAdd={addNewBit}
|
||||||
|
onRowEdit={editBit}
|
||||||
|
onRowDelete={removeBit}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default PermissionBits
|
60
src/pages/AdminPanel/PermissionController.jsx
Normal file
60
src/pages/AdminPanel/PermissionController.jsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { invokeWebApiWrapperAsync } from '../../components/factory'
|
||||||
|
import LoaderPortal from '../../components/LoaderPortal'
|
||||||
|
import { EditableTable, makeActionHandler, makeColumn } from '../../components/Table'
|
||||||
|
import { AdminPermissionInfoService } from '../../services/api'
|
||||||
|
import PermissionBits, { toHexString } from './PermissionBits'
|
||||||
|
|
||||||
|
export const PermissionController = () => {
|
||||||
|
const [permissions, setPermissions] = useState([])
|
||||||
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
makeColumn('Название', 'name', { width: 200, editable: true }),
|
||||||
|
makeColumn('Описание', 'description', { width: 200, editable: true }),
|
||||||
|
makeColumn('Значения битов', 'bitDescription', {
|
||||||
|
width: 200,
|
||||||
|
editable: true,
|
||||||
|
input: <PermissionBits />, // TODO: Дописать колонку для описания битов права
|
||||||
|
render: (bits) => {
|
||||||
|
if (!bits) return '--'
|
||||||
|
const sum = Object.keys(bits).reduce((sum, key) => sum + (1 << parseInt(key)), 0)
|
||||||
|
return sum && toHexString(sum, 16)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
const updateTable = () => invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const permissions = await AdminPermissionInfoService.getAll()
|
||||||
|
setPermissions(permissions)
|
||||||
|
},
|
||||||
|
setShowLoader,
|
||||||
|
`Не удалось загрузить список прав`
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(updateTable, [])
|
||||||
|
|
||||||
|
const handlerProps = {
|
||||||
|
service: AdminPermissionInfoService,
|
||||||
|
setLoader: setShowLoader,
|
||||||
|
errorMsg: `Не удалось выполнить операцию`,
|
||||||
|
onComplete: updateTable
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoaderPortal show={showLoader}>
|
||||||
|
<EditableTable
|
||||||
|
size={'small'}
|
||||||
|
bordered
|
||||||
|
columns={columns}
|
||||||
|
dataSource={permissions}
|
||||||
|
onRowAdd={makeActionHandler('insert', handlerProps)}
|
||||||
|
onRowEdit={makeActionHandler('update', handlerProps)}
|
||||||
|
onRowDelete={makeActionHandler('delete', handlerProps)}
|
||||||
|
/>
|
||||||
|
</LoaderPortal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PermissionController
|
@ -9,6 +9,7 @@ const CompanyController = React.lazy(() => import('./CompanyController'))
|
|||||||
const DepositController = React.lazy(() => import('./DepositController'))
|
const DepositController = React.lazy(() => import('./DepositController'))
|
||||||
const UserController = React.lazy(() => import('./UserController'))
|
const UserController = React.lazy(() => import('./UserController'))
|
||||||
const WellController = React.lazy(() => import('./WellController'))
|
const WellController = React.lazy(() => import('./WellController'))
|
||||||
|
const PermissionController = React.lazy(() => import('./PermissionController'))
|
||||||
|
|
||||||
export const AdminPanel = () => {
|
export const AdminPanel = () => {
|
||||||
const { tab } = useParams()
|
const { tab } = useParams()
|
||||||
@ -36,6 +37,9 @@ export const AdminPanel = () => {
|
|||||||
<PrivateMenuItem key={'company'} permissions={[[PermissionNames.admin.company, PermissionValue.Read]]}>
|
<PrivateMenuItem key={'company'} permissions={[[PermissionNames.admin.company, PermissionValue.Read]]}>
|
||||||
<Link to={`${rootPath}/company`}>Компании</Link>
|
<Link to={`${rootPath}/company`}>Компании</Link>
|
||||||
</PrivateMenuItem>
|
</PrivateMenuItem>
|
||||||
|
<PrivateMenuItem key={'permission'} permissions={[[PermissionNames.admin.permissions, PermissionValue.Read]]}>
|
||||||
|
<Link to={`${rootPath}/permission`}>Права</Link>
|
||||||
|
</PrivateMenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
@ -47,6 +51,7 @@ export const AdminPanel = () => {
|
|||||||
<PrivateRoute roles={[ 'well_admin']} path={`${rootPath}/well` } component={ WellController} />
|
<PrivateRoute roles={[ 'well_admin']} path={`${rootPath}/well` } component={ WellController} />
|
||||||
<PrivateRoute roles={[ 'user_admin']} path={`${rootPath}/user` } component={ UserController} />
|
<PrivateRoute roles={[ 'user_admin']} path={`${rootPath}/user` } component={ UserController} />
|
||||||
<PrivateRoute roles={['company_admin']} path={`${rootPath}/company`} component={CompanyController} />
|
<PrivateRoute roles={['company_admin']} path={`${rootPath}/company`} component={CompanyController} />
|
||||||
|
<PrivateRoute path={`${rootPath}/permission`} component={PermissionController} />
|
||||||
<Route path={'/'}>
|
<Route path={'/'}>
|
||||||
<Redirect to={`${rootPath}/deposit`}/>
|
<Redirect to={`${rootPath}/deposit`}/>
|
||||||
</Route>
|
</Route>
|
||||||
|
Loading…
Reference in New Issue
Block a user