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 UserController = React.lazy(() => import('./UserController'))
|
||||
const WellController = React.lazy(() => import('./WellController'))
|
||||
const PermissionController = React.lazy(() => import('./PermissionController'))
|
||||
|
||||
export const AdminPanel = () => {
|
||||
const { tab } = useParams()
|
||||
@ -36,6 +37,9 @@ export const AdminPanel = () => {
|
||||
<PrivateMenuItem key={'company'} permissions={[[PermissionNames.admin.company, PermissionValue.Read]]}>
|
||||
<Link to={`${rootPath}/company`}>Компании</Link>
|
||||
</PrivateMenuItem>
|
||||
<PrivateMenuItem key={'permission'} permissions={[[PermissionNames.admin.permissions, PermissionValue.Read]]}>
|
||||
<Link to={`${rootPath}/permission`}>Права</Link>
|
||||
</PrivateMenuItem>
|
||||
</Menu>
|
||||
|
||||
<Layout>
|
||||
@ -47,6 +51,7 @@ export const AdminPanel = () => {
|
||||
<PrivateRoute roles={[ 'well_admin']} path={`${rootPath}/well` } component={ WellController} />
|
||||
<PrivateRoute roles={[ 'user_admin']} path={`${rootPath}/user` } component={ UserController} />
|
||||
<PrivateRoute roles={['company_admin']} path={`${rootPath}/company`} component={CompanyController} />
|
||||
<PrivateRoute path={`${rootPath}/permission`} component={PermissionController} />
|
||||
<Route path={'/'}>
|
||||
<Redirect to={`${rootPath}/deposit`}/>
|
||||
</Route>
|
||||
|
Loading…
Reference in New Issue
Block a user