diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index fddaf69..e010866 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -12,6 +12,11 @@ export { SelectFromDictionary } from './SelectFromDictionary' export const RegExpIsFloat = /^[-+]?\d+\.?\d*$/ +export const defaultPagination = { + defaultPageSize: 14, + showSizeChanger: true, +} + export const makeNumericRender = (fixed?: number) => (value: any, row: object): ReactNode => { let val = '-' if ((value ?? null) !== null && Number.isFinite(+value)) { diff --git a/src/pages/AdminPanel/ClusterController.jsx b/src/pages/AdminPanel/ClusterController.jsx index 4b9f46e..6acfc8b 100644 --- a/src/pages/AdminPanel/ClusterController.jsx +++ b/src/pages/AdminPanel/ClusterController.jsx @@ -7,7 +7,8 @@ import { makeColumn, makeSelectColumn, makeActionHandler, - makeStringSorter + makeStringSorter, + defaultPagination } from '../../components/Table' import { AdminClusterService, AdminDepositService } from '../../services/api' import { arrayOrDefault } from '../../utils' @@ -69,8 +70,9 @@ export const ClusterController = () => { { + const [columns, setColumns] = useState([]) const [companies, setCompanies] = useState([]) const [showLoader, setShowLoader] = useState(false) - const updateTable = () => invokeWebApiWrapperAsync( - async() => { - const companies = await AdminCompanyService.getAll() - setCompanies(arrayOrDefault(companies)) - }, - setShowLoader, - `Не удалось загрузить список кустов` - ) + const updateTable = async () => { + const companies = await AdminCompanyService.getAll() + setCompanies(arrayOrDefault(companies)) + } - useEffect(updateTable, []) + useEffect(() => invokeWebApiWrapperAsync( + async() => { + const companyTypes = arrayOrDefault(await AdminCompanyTypeService.getAll()).map((companyType) => ({ + value: companyType.id, + label: companyType.caption, + })) + + setColumns([ + makeColumn('Название', 'caption', { + width: 200, + editable: true, + sorter: makeStringSorter('caption'), + formItemRules: min1, + }), + makeSelectColumn('Тип компании', 'idCompanyType', companyTypes, null, { + width: 200, + editable: true + }), + ]) + + await updateTable() + } + ), []) const handlerProps = { service: AdminCompanyService, @@ -48,8 +61,9 @@ export default function CompanyController() { ) } + +export default CompanyController diff --git a/src/pages/AdminPanel/CompanyTypeController.jsx b/src/pages/AdminPanel/CompanyTypeController.jsx index b067614..3cd0415 100644 --- a/src/pages/AdminPanel/CompanyTypeController.jsx +++ b/src/pages/AdminPanel/CompanyTypeController.jsx @@ -2,7 +2,13 @@ import { useEffect, useState } from 'react' import { invokeWebApiWrapperAsync } from '../../components/factory' import LoaderPortal from '../../components/LoaderPortal' -import { EditableTable, makeColumn, makeActionHandler, makeStringSorter } from '../../components/Table' +import { + EditableTable, + makeColumn, + makeActionHandler, + makeStringSorter, + defaultPagination +} from '../../components/Table' import { AdminCompanyTypeService } from '../../services/api' import { arrayOrDefault } from '../../utils' import { min1 } from '../../utils/validationRules' @@ -16,11 +22,6 @@ const columns = [ }), ] -const pagination = { - defaultPageSize: 16, - showSizeChanger: true, -} - export const CompanyTypeController = () => { const [companyTypes, setCompanyTypes] = useState([]) const [showLoader, setShowLoader] = useState(false) @@ -50,7 +51,7 @@ export const CompanyTypeController = () => { size={'small'} columns={columns} dataSource={companyTypes} - pagination={pagination} + pagination={defaultPagination} onRowAdd={makeActionHandler('insert', handlerProps)} onRowEdit={makeActionHandler('put', handlerProps)} onRowDelete={makeActionHandler('delete', handlerProps)} diff --git a/src/pages/AdminPanel/DepositController.jsx b/src/pages/AdminPanel/DepositController.jsx index c37fd04..0006785 100644 --- a/src/pages/AdminPanel/DepositController.jsx +++ b/src/pages/AdminPanel/DepositController.jsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react' -import { invokeWebApiWrapperAsync } from '../../components/factory' + import LoaderPortal from '../../components/LoaderPortal' -import { EditableTable, makeColumn, makeActionHandler } from '../../components/Table' +import { invokeWebApiWrapperAsync } from '../../components/factory' +import { EditableTable, makeColumn, makeActionHandler, defaultPagination } from '../../components/Table' import { AdminDepositService } from '../../services/api' import { arrayOrDefault } from '../../utils' import { min1 } from '../../utils/validationRules' @@ -14,7 +15,7 @@ const depositColumns = [ makeColumn('Долгота', 'longitude', { width: 150, editable: true, render: coordsFixed }) ] -export default function DepositController() { +export const DepositController = () => { const [deposits, setDeposits] = useState([]) const [showLoader, setShowLoader] = useState(false) @@ -41,8 +42,9 @@ export default function DepositController() { ) } + +export default DepositController diff --git a/src/pages/AdminPanel/RoleController.jsx b/src/pages/AdminPanel/RoleController.jsx index 00da065..5dd2e33 100644 --- a/src/pages/AdminPanel/RoleController.jsx +++ b/src/pages/AdminPanel/RoleController.jsx @@ -16,7 +16,7 @@ export const RoleController = memo(() => { const loadRoles = async () => { const roles = await AdminUserRoleService.getAll() - setRoles(Array.isArray(roles) ? roles : []) + setRoles(arrayOrDefault(roles)) } useEffect(() => { @@ -28,7 +28,6 @@ export const RoleController = memo(() => { editable: true }, { allowClear: true }), makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', { - width: 200, editable: true, render: (permission) => , }), diff --git a/src/pages/AdminPanel/UserController/RoleTag.jsx b/src/pages/AdminPanel/UserController/RoleTag.jsx new file mode 100644 index 0000000..c67aa26 --- /dev/null +++ b/src/pages/AdminPanel/UserController/RoleTag.jsx @@ -0,0 +1,27 @@ +import { Select } from 'antd' +import { memo, useEffect, useState } from 'react' + +export const RoleTag = memo(({ roles, value, onChange }) => { + const [options, setOptions] = useState([]) + + useEffect(() => { + setOptions(roles.map((elm) => ({ + key: Date.now(), + value: `${elm.caption}`, + label: elm.caption + }))) + }, [roles]) + + return ( + - ) -}) - -const makeOnFilter = (key) => (value, record) => record?.[key]?.startsWith(value) -const makeDataFilters = (array, keys) => { - const filters = Array(keys.length) - - for (let i = 0; i < keys.length; i++) - filters[i] = [] - - array.forEach((row) => { - if (!row) return - keys.forEach((key, idx) => { - if (row[key] && filters[idx].indexOf(row[key]) < 0) - filters[idx].push(row[key]) - }) - }) - - const out = {} - - keys.forEach((key, idx) => { - filters[idx].sort() - out[key] = filters[idx].map((filter) => ({ - value: filter, - text: filter, - })) - }) - - return out -} - -export default function UserController() { +export const UserController = () => { const [users, setUsers] = useState([]) const [showLoader, setShowLoader] = useState(false) const [columns, setColumns] = useState([]) @@ -104,7 +58,7 @@ export default function UserController() { const users = arrayOrDefault(await AdminUserService.getAll()) setUsers(users) - const filters = makeDataFilters(users, ['surname', 'name', 'patronymic', 'email']) + const filters = makeTextFilters(users, ['surname', 'name', 'patronymic', 'email']) setColumns([ @@ -130,7 +84,7 @@ export default function UserController() { sorter: makeStringSorter('surname'), filters: filters.surname, filterSearch: true, - onFilter: makeOnFilter('surname'), + onFilter: makeTextOnFilter('surname'), }), makeColumn('Имя', 'name', { editable: true, @@ -138,7 +92,7 @@ export default function UserController() { sorter: makeStringSorter('name'), filters: filters.name, filterSearch: true, - onFilter: makeOnFilter('name'), + onFilter: makeTextOnFilter('name'), }), makeColumn('Отчество', 'patronymic', { editable: true, @@ -146,7 +100,7 @@ export default function UserController() { sorter: makeStringSorter('patronymic'), filters: filters.patronymic, filterSearch: true, - onFilter: makeOnFilter('patronymic'), + onFilter: makeTextOnFilter('patronymic'), }), makeColumn('E-mail', 'email', { editable: true, @@ -154,7 +108,7 @@ export default function UserController() { sorter: makeStringSorter('email'), filters: filters.email, filterSearch: true, - onFilter: makeOnFilter('email'), + onFilter: makeTextOnFilter('email'), }), makeColumn('Номер телефона', 'phone', { editable: true, @@ -204,7 +158,7 @@ export default function UserController() { onRowDelete={makeActionHandler('delete', handlerProps)} additionalButtons={additionalButtons} buttonsWidth={120} - pagination={{ defaultPageSize: 14 }} + pagination={defaultPagination} /> ) } + +export default UserController diff --git a/src/pages/AdminPanel/VisitLog.jsx b/src/pages/AdminPanel/VisitLog.jsx index e74962f..89b6f21 100644 --- a/src/pages/AdminPanel/VisitLog.jsx +++ b/src/pages/AdminPanel/VisitLog.jsx @@ -2,7 +2,7 @@ import { memo, useEffect, useState } from 'react' import { invokeWebApiWrapperAsync } from '../../components/factory' import LoaderPortal from '../../components/LoaderPortal' -import { makeColumn, makeDateSorter, makeStringSorter, Table } from '../../components/Table' +import { defaultPagination, makeColumn, makeDateSorter, makeStringSorter, Table } from '../../components/Table' import { RequerstTrackerService } from '../../services/api' import { arrayOrDefault, formatDate } from '../../utils' @@ -17,11 +17,6 @@ const columns = [ }), ] -const pagination = { - defaultPageSize: 16, - showSizeChanger: true, -} - export const VisitLog = memo(() => { const [logData, setLogData] = useState([]) const [isLoading, setIsLoading] = useState(false) @@ -44,7 +39,7 @@ export const VisitLog = memo(() => { bordered columns={columns} dataSource={logData} - pagination={pagination} + pagination={defaultPagination} /> ) diff --git a/src/pages/AdminPanel/WellController/TelemetrySelect.jsx b/src/pages/AdminPanel/WellController/TelemetrySelect.jsx new file mode 100644 index 0000000..6b16cb5 --- /dev/null +++ b/src/pages/AdminPanel/WellController/TelemetrySelect.jsx @@ -0,0 +1,28 @@ +import { memo } from 'react' +import { Select } from 'antd' + +import { getTelemetryLabel } from '../../../components/Views' + +export const TelemetrySelect = memo(({ telemetry, value, onChange }) => { + const onSelectChange = (id) => { + onChange?.(telemetry.find((row) => row.id === id)) + } + + return ( + + ) +}) + +export default TelemetrySelect diff --git a/src/pages/AdminPanel/WellController.jsx b/src/pages/AdminPanel/WellController/index.jsx similarity index 77% rename from src/pages/AdminPanel/WellController.jsx rename to src/pages/AdminPanel/WellController/index.jsx index 6547e82..194ec1c 100644 --- a/src/pages/AdminPanel/WellController.jsx +++ b/src/pages/AdminPanel/WellController/index.jsx @@ -1,10 +1,10 @@ -import { Button, Select } from 'antd' +import { useEffect, useState } from 'react' +import { Button } from 'antd' import { CopyOutlined } from '@ant-design/icons' -import { memo, useEffect, useState } from 'react' -import LoaderPortal from '../../components/LoaderPortal' -import { invokeWebApiWrapperAsync } from '../../components/factory' -import { TelemetryView, getTelemetryLabel, CompanyView } from '../../components/Views' +import LoaderPortal from '../../../components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '../../../components/factory' +import { TelemetryView, CompanyView } from '../../../components/Views' import { EditableTable, makeColumn, @@ -13,46 +13,27 @@ import { makeStringSorter, makeNumericSorter, makeTagColumn, -} from '../../components/Table' + defaultPagination, +} from '../../../components/Table' import { AdminClusterService, AdminCompanyService, AdminTelemetryService, AdminWellService, -} from '../../services/api' -import { arrayOrDefault } from '../../utils' -import { coordsFixed } from './DepositController' +} from '../../../services/api' +import { arrayOrDefault } from '../../../utils' -import '../../styles/admin.css' +import { coordsFixed } from '../DepositController' +import TelemetrySelect from './TelemetrySelect' + +import '../../../styles/admin.css' const wellTypes = [ { value: 1, label: 'Наклонно-направленная' }, { value: 2, label: 'Горизонтальная' }, ] -const TelemetrySelect = memo(({ telemetry, value, onChange }) => { - const onSelectChange = (id) => { - onChange?.(telemetry.find((row) => row.id === id)) - } - - return ( - - ) -}) - -export default function WellController() { +export const WellController = () => { const [columns, setColumns] = useState([]) const [wells, setWells] = useState([]) const [showLoader, setShowLoader] = useState(false) @@ -142,6 +123,7 @@ export default function WellController() { bordered columns={columns} dataSource={wells} + pagination={defaultPagination} onRowAdd={makeActionHandler('insert', handlerProps, recordParser)} onRowEdit={makeActionHandler('put', handlerProps, recordParser)} onRowDelete={makeActionHandler('delete', handlerProps)} @@ -151,3 +133,5 @@ export default function WellController() { ) } + +export default WellController diff --git a/src/utils/table.ts b/src/utils/table.ts new file mode 100644 index 0000000..55af786 --- /dev/null +++ b/src/utils/table.ts @@ -0,0 +1,30 @@ +export const makeTextOnFilter = (key: string) => + (value: string, record?: Record) => record?.[key]?.startsWith(value) + +export const makeTextFilters = (array: Record[], keys: string[]) => { + const filters: string[][] = Array(keys.length) + + filters.forEach((_, idx) => filters[idx] = []) + + array.forEach((row) => { + if (!row) return + keys.forEach((key, idx) => { + if (!row[key]) return + const value = String(row[key]) + if (filters[idx].indexOf(value) < 0) + filters[idx].push(value) + }) + }) + + const out: Record = {} + + keys.forEach((key, idx) => { + filters[idx].sort() + out[key] = filters[idx].map((filter) => ({ + value: filter, + text: filter, + })) + }) + + return out +}