Добавлена страница редактирования прав

This commit is contained in:
Александр Сироткин 2021-12-13 10:31:47 +05:00
parent 78c7f78935
commit b0d8126808
3 changed files with 188 additions and 0 deletions

View 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

View 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

View File

@ -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>