diff --git a/src/pages/AdminPanel/PermissionBits.jsx b/src/pages/AdminPanel/PermissionBits.jsx
new file mode 100644
index 0000000..cabf448
--- /dev/null
+++ b/src/pages/AdminPanel/PermissionBits.jsx
@@ -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: ,
+ 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: ,
+ // 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 (
+ <>
+
+ setIsModalVisible(false)}
+ onOk={saveBits}
+ okText={'Сохранить'}
+ >
+
+
+ >
+ )
+})
+
+export default PermissionBits
diff --git a/src/pages/AdminPanel/PermissionController.jsx b/src/pages/AdminPanel/PermissionController.jsx
new file mode 100644
index 0000000..628c95a
--- /dev/null
+++ b/src/pages/AdminPanel/PermissionController.jsx
@@ -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: , // 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 (
+
+
+
+ )
+}
+
+export default PermissionController
diff --git a/src/pages/AdminPanel/index.jsx b/src/pages/AdminPanel/index.jsx
index dbb490a..2ec84b4 100644
--- a/src/pages/AdminPanel/index.jsx
+++ b/src/pages/AdminPanel/index.jsx
@@ -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 = () => {
Компании
+
+ Права
+
@@ -47,6 +51,7 @@ export const AdminPanel = () => {
+