diff --git a/src/client/index.ts b/src/client/index.ts index 7fe5743..6bca2a8 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -7,6 +7,8 @@ export { CancelablePromise, CancelError } from './core/CancelablePromise'; export { OpenAPI } from './core/OpenAPI'; export type { OpenAPIConfig } from './core/OpenAPI'; +export type { AddUserRequest } from './models/AddUserRequest'; +export type { AddUserResponse } from './models/AddUserResponse'; export type { AuthLoginRequest } from './models/AuthLoginRequest'; export type { AuthLoginResponse } from './models/AuthLoginResponse'; export type { BarcodeAttributeSchema } from './models/BarcodeAttributeSchema'; @@ -50,6 +52,10 @@ export type { CreateBoxInDealSchema } from './models/CreateBoxInDealSchema'; export type { CreateBoxInPalletSchema } from './models/CreateBoxInPalletSchema'; export type { CreateDealBillRequest } from './models/CreateDealBillRequest'; export type { CreateDealBillResponse } from './models/CreateDealBillResponse'; +export type { CreateDepartmentRequest } from './models/CreateDepartmentRequest'; +export type { CreateDepartmentResponse } from './models/CreateDepartmentResponse'; +export type { CreateDepartmentSectionRequest } from './models/CreateDepartmentSectionRequest'; +export type { CreateDepartmentSectionResponse } from './models/CreateDepartmentSectionResponse'; export type { CreateMarketplaceRequest } from './models/CreateMarketplaceRequest'; export type { CreateMarketplaceResponse } from './models/CreateMarketplaceResponse'; export type { CreatePalletResponse } from './models/CreatePalletResponse'; @@ -139,6 +145,8 @@ export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServi export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest'; export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse'; export type { DeleteBoxResponse } from './models/DeleteBoxResponse'; +export type { DeleteDepartmentResponse } from './models/DeleteDepartmentResponse'; +export type { DeleteDepartmentSectionResponse } from './models/DeleteDepartmentSectionResponse'; export type { DeleteMarketplaceRequest } from './models/DeleteMarketplaceRequest'; export type { DeleteMarketplaceResponse } from './models/DeleteMarketplaceResponse'; export type { DeletePalletResponse } from './models/DeletePalletResponse'; @@ -156,6 +164,12 @@ export type { DeleteShippingWarehouseRequest } from './models/DeleteShippingWare export type { DeleteShippingWarehouseResponse } from './models/DeleteShippingWarehouseResponse'; export type { DeleteTransactionResponse } from './models/DeleteTransactionResponse'; export type { DeleteTransactionTagResponse } from './models/DeleteTransactionTagResponse'; +export type { DeleteUserRequest } from './models/DeleteUserRequest'; +export type { DeleteUserResponse } from './models/DeleteUserResponse'; +export type { DepartmentBaseSchema } from './models/DepartmentBaseSchema'; +export type { DepartmentSchema } from './models/DepartmentSchema'; +export type { DepartmentSectionBaseSchema } from './models/DepartmentSectionBaseSchema'; +export type { DepartmentSectionSchema } from './models/DepartmentSectionSchema'; export type { FinishPauseByShiftIdResponse } from './models/FinishPauseByShiftIdResponse'; export type { FinishPauseByUserIdResponse } from './models/FinishPauseByUserIdResponse'; export type { FinishShiftByIdResponse } from './models/FinishShiftByIdResponse'; @@ -175,6 +189,7 @@ export type { GetAllTransactionsRequest } from './models/GetAllTransactionsReque export type { GetAllTransactionsResponse } from './models/GetAllTransactionsResponse'; export type { GetAllTransactionTagsResponse } from './models/GetAllTransactionTagsResponse'; export type { GetAllUsersResponse } from './models/GetAllUsersResponse'; +export type { GetAvailableUsersForDepartmentSectionResponse } from './models/GetAvailableUsersForDepartmentSectionResponse'; export type { GetBarcodeTemplateByIdRequest } from './models/GetBarcodeTemplateByIdRequest'; export type { GetBarcodeTemplateByIdResponse } from './models/GetBarcodeTemplateByIdResponse'; export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest'; @@ -182,6 +197,7 @@ export type { GetClientMarketplacesResponse } from './models/GetClientMarketplac export type { GetDealBillById } from './models/GetDealBillById'; export type { GetDealProductsBarcodesPdfRequest } from './models/GetDealProductsBarcodesPdfRequest'; export type { GetDealProductsBarcodesPdfResponse } from './models/GetDealProductsBarcodesPdfResponse'; +export type { GetDepartmentsResponse } from './models/GetDepartmentsResponse'; export type { GetManagersResponse } from './models/GetManagersResponse'; export type { GetPaymentRecordsResponse } from './models/GetPaymentRecordsResponse'; export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest'; @@ -271,6 +287,10 @@ export type { TransactionTagSchema } from './models/TransactionTagSchema'; export type { UpdateBoxRequest } from './models/UpdateBoxRequest'; export type { UpdateBoxResponse } from './models/UpdateBoxResponse'; export type { UpdateBoxSchema } from './models/UpdateBoxSchema'; +export type { UpdateDepartmentRequest } from './models/UpdateDepartmentRequest'; +export type { UpdateDepartmentResponse } from './models/UpdateDepartmentResponse'; +export type { UpdateDepartmentSectionRequest } from './models/UpdateDepartmentSectionRequest'; +export type { UpdateDepartmentSectionResponse } from './models/UpdateDepartmentSectionResponse'; export type { UpdateMarketplaceRequest } from './models/UpdateMarketplaceRequest'; export type { UpdateMarketplaceResponse } from './models/UpdateMarketplaceResponse'; export type { UpdatePayRateRequest } from './models/UpdatePayRateRequest'; @@ -307,6 +327,7 @@ export { BarcodeService } from './services/BarcodeService'; export { BillingService } from './services/BillingService'; export { ClientService } from './services/ClientService'; export { DealService } from './services/DealService'; +export { DepartmentService } from './services/DepartmentService'; export { MarketplaceService } from './services/MarketplaceService'; export { PayrollService } from './services/PayrollService'; export { PositionService } from './services/PositionService'; diff --git a/src/client/models/AddUserRequest.ts b/src/client/models/AddUserRequest.ts new file mode 100644 index 0000000..8d2e953 --- /dev/null +++ b/src/client/models/AddUserRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type AddUserRequest = { + userId: number; + sectionId: number; +}; + diff --git a/src/client/models/AddUserResponse.ts b/src/client/models/AddUserResponse.ts new file mode 100644 index 0000000..5e94df7 --- /dev/null +++ b/src/client/models/AddUserResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type AddUserResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/CreateDepartmentRequest.ts b/src/client/models/CreateDepartmentRequest.ts new file mode 100644 index 0000000..467221a --- /dev/null +++ b/src/client/models/CreateDepartmentRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentBaseSchema } from './DepartmentBaseSchema'; +export type CreateDepartmentRequest = { + department: DepartmentBaseSchema; +}; + diff --git a/src/client/models/CreateDepartmentResponse.ts b/src/client/models/CreateDepartmentResponse.ts new file mode 100644 index 0000000..648f109 --- /dev/null +++ b/src/client/models/CreateDepartmentResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type CreateDepartmentResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/CreateDepartmentSectionRequest.ts b/src/client/models/CreateDepartmentSectionRequest.ts new file mode 100644 index 0000000..ceeadc0 --- /dev/null +++ b/src/client/models/CreateDepartmentSectionRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentSectionBaseSchema } from './DepartmentSectionBaseSchema'; +export type CreateDepartmentSectionRequest = { + section: DepartmentSectionBaseSchema; +}; + diff --git a/src/client/models/CreateDepartmentSectionResponse.ts b/src/client/models/CreateDepartmentSectionResponse.ts new file mode 100644 index 0000000..0fc6bbc --- /dev/null +++ b/src/client/models/CreateDepartmentSectionResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type CreateDepartmentSectionResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/DeleteDepartmentResponse.ts b/src/client/models/DeleteDepartmentResponse.ts new file mode 100644 index 0000000..30d8172 --- /dev/null +++ b/src/client/models/DeleteDepartmentResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DeleteDepartmentResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/DeleteDepartmentSectionResponse.ts b/src/client/models/DeleteDepartmentSectionResponse.ts new file mode 100644 index 0000000..94d2427 --- /dev/null +++ b/src/client/models/DeleteDepartmentSectionResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DeleteDepartmentSectionResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/DeleteUserRequest.ts b/src/client/models/DeleteUserRequest.ts new file mode 100644 index 0000000..0fce376 --- /dev/null +++ b/src/client/models/DeleteUserRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DeleteUserRequest = { + userId: number; + sectionId: number; +}; + diff --git a/src/client/models/DeleteUserResponse.ts b/src/client/models/DeleteUserResponse.ts new file mode 100644 index 0000000..8f25592 --- /dev/null +++ b/src/client/models/DeleteUserResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DeleteUserResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/DepartmentBaseSchema.ts b/src/client/models/DepartmentBaseSchema.ts new file mode 100644 index 0000000..9946b18 --- /dev/null +++ b/src/client/models/DepartmentBaseSchema.ts @@ -0,0 +1,8 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DepartmentBaseSchema = { + name: string; +}; + diff --git a/src/client/models/DepartmentSchema.ts b/src/client/models/DepartmentSchema.ts new file mode 100644 index 0000000..37ac76b --- /dev/null +++ b/src/client/models/DepartmentSchema.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentSectionSchema } from './DepartmentSectionSchema'; +export type DepartmentSchema = { + name: string; + id: number; + sections?: Array; +}; + diff --git a/src/client/models/DepartmentSectionBaseSchema.ts b/src/client/models/DepartmentSectionBaseSchema.ts new file mode 100644 index 0000000..13f7ec2 --- /dev/null +++ b/src/client/models/DepartmentSectionBaseSchema.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type DepartmentSectionBaseSchema = { + name: string; + departmentId: number; +}; + diff --git a/src/client/models/DepartmentSectionSchema.ts b/src/client/models/DepartmentSectionSchema.ts new file mode 100644 index 0000000..877cc75 --- /dev/null +++ b/src/client/models/DepartmentSectionSchema.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { UserSchema } from './UserSchema'; +export type DepartmentSectionSchema = { + name: string; + departmentId: number; + id: number; + users?: Array; +}; + diff --git a/src/client/models/GetAvailableUsersForDepartmentSectionResponse.ts b/src/client/models/GetAvailableUsersForDepartmentSectionResponse.ts new file mode 100644 index 0000000..c39c86a --- /dev/null +++ b/src/client/models/GetAvailableUsersForDepartmentSectionResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { UserSchema } from './UserSchema'; +export type GetAvailableUsersForDepartmentSectionResponse = { + users: Array; +}; + diff --git a/src/client/models/GetDepartmentsResponse.ts b/src/client/models/GetDepartmentsResponse.ts new file mode 100644 index 0000000..aaac739 --- /dev/null +++ b/src/client/models/GetDepartmentsResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentSchema } from './DepartmentSchema'; +export type GetDepartmentsResponse = { + departments: Array; +}; + diff --git a/src/client/models/UpdateDepartmentRequest.ts b/src/client/models/UpdateDepartmentRequest.ts new file mode 100644 index 0000000..e9a1a96 --- /dev/null +++ b/src/client/models/UpdateDepartmentRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentSchema } from './DepartmentSchema'; +export type UpdateDepartmentRequest = { + department: DepartmentSchema; +}; + diff --git a/src/client/models/UpdateDepartmentResponse.ts b/src/client/models/UpdateDepartmentResponse.ts new file mode 100644 index 0000000..e251c72 --- /dev/null +++ b/src/client/models/UpdateDepartmentResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type UpdateDepartmentResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/models/UpdateDepartmentSectionRequest.ts b/src/client/models/UpdateDepartmentSectionRequest.ts new file mode 100644 index 0000000..8963e6a --- /dev/null +++ b/src/client/models/UpdateDepartmentSectionRequest.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { DepartmentSectionSchema } from './DepartmentSectionSchema'; +export type UpdateDepartmentSectionRequest = { + section: DepartmentSectionSchema; +}; + diff --git a/src/client/models/UpdateDepartmentSectionResponse.ts b/src/client/models/UpdateDepartmentSectionResponse.ts new file mode 100644 index 0000000..25f0c73 --- /dev/null +++ b/src/client/models/UpdateDepartmentSectionResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type UpdateDepartmentSectionResponse = { + ok: boolean; + message: string; +}; + diff --git a/src/client/services/DepartmentService.ts b/src/client/services/DepartmentService.ts new file mode 100644 index 0000000..952813f --- /dev/null +++ b/src/client/services/DepartmentService.ts @@ -0,0 +1,219 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { AddUserRequest } from '../models/AddUserRequest'; +import type { AddUserResponse } from '../models/AddUserResponse'; +import type { CreateDepartmentRequest } from '../models/CreateDepartmentRequest'; +import type { CreateDepartmentResponse } from '../models/CreateDepartmentResponse'; +import type { CreateDepartmentSectionRequest } from '../models/CreateDepartmentSectionRequest'; +import type { CreateDepartmentSectionResponse } from '../models/CreateDepartmentSectionResponse'; +import type { DeleteDepartmentResponse } from '../models/DeleteDepartmentResponse'; +import type { DeleteDepartmentSectionResponse } from '../models/DeleteDepartmentSectionResponse'; +import type { DeleteUserRequest } from '../models/DeleteUserRequest'; +import type { DeleteUserResponse } from '../models/DeleteUserResponse'; +import type { GetAvailableUsersForDepartmentSectionResponse } from '../models/GetAvailableUsersForDepartmentSectionResponse'; +import type { GetDepartmentsResponse } from '../models/GetDepartmentsResponse'; +import type { UpdateDepartmentRequest } from '../models/UpdateDepartmentRequest'; +import type { UpdateDepartmentResponse } from '../models/UpdateDepartmentResponse'; +import type { UpdateDepartmentSectionRequest } from '../models/UpdateDepartmentSectionRequest'; +import type { UpdateDepartmentSectionResponse } from '../models/UpdateDepartmentSectionResponse'; +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; +export class DepartmentService { + /** + * Get Departments + * @returns GetDepartmentsResponse Successful Response + * @throws ApiError + */ + public static getDepartments(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/department/', + }); + } + /** + * Create Department + * @returns CreateDepartmentResponse Successful Response + * @throws ApiError + */ + public static createDepartment({ + requestBody, + }: { + requestBody: CreateDepartmentRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/department/', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Update Department + * @returns UpdateDepartmentResponse Successful Response + * @throws ApiError + */ + public static updateDepartment({ + requestBody, + }: { + requestBody: UpdateDepartmentRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/department/', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Delete Department + * @returns DeleteDepartmentResponse Successful Response + * @throws ApiError + */ + public static deleteDepartment({ + departmentId, + }: { + departmentId: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/department/{department_id}', + path: { + 'department_id': departmentId, + }, + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Create Section + * @returns CreateDepartmentSectionResponse Successful Response + * @throws ApiError + */ + public static createSection({ + requestBody, + }: { + requestBody: CreateDepartmentSectionRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/department/section', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Update Section + * @returns UpdateDepartmentSectionResponse Successful Response + * @throws ApiError + */ + public static updateSection({ + requestBody, + }: { + requestBody: UpdateDepartmentSectionRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PATCH', + url: '/department/section', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Delete Section + * @returns DeleteDepartmentSectionResponse Successful Response + * @throws ApiError + */ + public static deleteSection({ + sectionId, + }: { + sectionId: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/department/section/{section_id}', + path: { + 'section_id': sectionId, + }, + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Get Available Users For Department Section + * @returns GetAvailableUsersForDepartmentSectionResponse Successful Response + * @throws ApiError + */ + public static getAvailableUsersForSection({ + sectionId, + }: { + sectionId: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/department/users/{section_id}', + path: { + 'section_id': sectionId, + }, + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Add User + * @returns AddUserResponse Successful Response + * @throws ApiError + */ + public static addUser({ + requestBody, + }: { + requestBody: AddUserRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/department/users', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } + /** + * Delete User + * @returns DeleteUserResponse Successful Response + * @throws ApiError + */ + public static deleteUser({ + requestBody, + }: { + requestBody: DeleteUserRequest, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/department/users/delete', + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Validation Error`, + }, + }); + } +} diff --git a/src/modals/modals.ts b/src/modals/modals.ts index 01910ad..7995414 100644 --- a/src/modals/modals.ts +++ b/src/modals/modals.ts @@ -25,6 +25,9 @@ import ScanningModal from "./ScanningModal/ScanningModal.tsx"; import TransactionFormModal from "../pages/AdminPage/tabs/Transactions/modals/TransactionFormModal.tsx"; import TransactionTagsModal from "../pages/AdminPage/tabs/Transactions/modals/TransactionTagsModal.tsx"; import ShippingProductModal from "../pages/LeadsPage/tabs/ShippingTab/modals/ShippingProductModal.tsx"; +import DepartmentModal from "../pages/AdminPage/tabs/OrganizationalStructureTab/modals/DepartmentModal.tsx"; +import AddUserToDepartmentModal + from "../pages/AdminPage/tabs/OrganizationalStructureTab/modals/AddUserToDepartmentModal.tsx"; export const modals = { enterDeadline: EnterDeadlineModal, @@ -54,4 +57,6 @@ export const modals = { transactionFormModal: TransactionFormModal, transactionTagsModal: TransactionTagsModal, shippingProductModal: ShippingProductModal, + departmentModal: DepartmentModal, + addUserToDepartmentModal: AddUserToDepartmentModal, }; diff --git a/src/pages/AdminPage/AdminPage.tsx b/src/pages/AdminPage/AdminPage.tsx index e0351fb..3a13bfd 100644 --- a/src/pages/AdminPage/AdminPage.tsx +++ b/src/pages/AdminPage/AdminPage.tsx @@ -2,14 +2,13 @@ import styles from "./AdminPage.module.css"; import { Tabs } from "@mantine/core"; import PageBlock from "../../components/PageBlock/PageBlock.tsx"; import { - IconBriefcase, + IconTopologyStar3, IconCalendarUser, IconCoins, IconCurrencyDollar, IconQrcode, IconUser, } from "@tabler/icons-react"; -import RolesAndPositionsTab from "./tabs/RolesAndPositions/RolesAndPositionsTab.tsx"; import UsersTab from "./tabs/Users/UsersTab.tsx"; import { motion } from "framer-motion"; import FinancesTab from "./tabs/Finances/FinancesTab.tsx"; @@ -18,6 +17,7 @@ import { WorkShiftsTab } from "./tabs/WorkShifts/WorkShiftsTab.tsx"; import { TransactionsTab } from "./tabs/Transactions/TransactionsTab.tsx"; import { useSelector } from "react-redux"; import { RootState } from "../../redux/store.ts"; +import OrganizationalStructureTab from "./tabs/OrganizationalStructureTab/OrganizationalStructureTab.tsx"; const AdminPage = () => { const userRole = useSelector((state: RootState) => state.auth.role); @@ -45,8 +45,8 @@ const AdminPage = () => { )} }> - Должности + leftSection={}> + Организационная структура {isAdmin && ( { initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.2 }}> - + diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/OrganizationalStructureTab.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/OrganizationalStructureTab.tsx new file mode 100644 index 0000000..88739d6 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/OrganizationalStructureTab.tsx @@ -0,0 +1,48 @@ +import { Tabs } from "@mantine/core"; +import { IconBriefcase, IconSitemap } from "@tabler/icons-react"; +import { motion } from "framer-motion"; +import RolesAndPositions from "./components/RolesAndPositions.tsx"; +import Departments from "./components/Departments.tsx"; + + +const OrganizationalStructureTab = () => { + return ( + + + }> + Департаменты и отделы + + }> + Должности + + + + + + + + + + + + + + ); +}; + +export default OrganizationalStructureTab; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentButtons.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentButtons.tsx new file mode 100644 index 0000000..e0c3aa1 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentButtons.tsx @@ -0,0 +1,35 @@ +import { Button, Group, rem } from "@mantine/core"; +import { IconChevronsDown, IconChevronsUp, IconPlus } from "@tabler/icons-react"; +import { useDepartmentContext } from "../contexts/DepartmentContext.tsx"; + + +const DepartmentButtons = () => { + const { + departmentIds, + toggleAllDepartmentIds, + onCreateDepartmentClick, + } = useDepartmentContext(); + + + return ( + + + + + ); +}; + +export default DepartmentButtons; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/Departments.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/Departments.tsx new file mode 100644 index 0000000..1e7a47f --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/Departments.tsx @@ -0,0 +1,17 @@ +import { Stack } from "@mantine/core"; +import DepartmentsTree from "./DepartmentsTree.tsx"; +import DepartmentButtons from "./DepartmentButtons.tsx"; +import { DepartmentContextProvider } from "../contexts/DepartmentContext.tsx"; + +const Departments = () => { + return ( + + + + + + + ); +}; + +export default Departments; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentsTree.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentsTree.tsx new file mode 100644 index 0000000..ba8d2d1 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/DepartmentsTree.tsx @@ -0,0 +1,139 @@ +import { Accordion, ActionIcon, Center, Flex, Text, Title, Tooltip } from "@mantine/core"; +import { IconEdit, IconPlaylistAdd, IconTrash, IconUserPlus } from "@tabler/icons-react"; +import { DepartmentSchema, DepartmentSectionSchema } from "../../../../../client"; +import { useDepartmentContext } from "../contexts/DepartmentContext.tsx"; +import UsersTable from "./UsersTable.tsx"; +import { ReactNode } from "react"; + + +const DepartmentsTree = () => { + const { + departments, + departmentIds, + setDepartmentIds, + onCreateDepartmentClick, + onUpdateDepartmentClick, + onDeleteDepartmentClick, + onAddUserClick, + } = useDepartmentContext(); + + const getAction = (label: string, func: () => void, icon: ReactNode) => { + return ( + + + {icon} + + + ); + }; + + const getActions = ( + element: DepartmentSectionSchema | DepartmentSchema, + isSection: boolean, + ) => { + const actions = [ + isSection ? ( + getAction( + "Добавить пользователя в отдел", + () => onAddUserClick(element as DepartmentSectionSchema), + , + ) + ) : ( + getAction( + "Добавить отдел", + () => onCreateDepartmentClick(true, { departmentId: element.id, name: "" }), + , + ) + ), + getAction( + "Редактировать", + () => onUpdateDepartmentClick(element, isSection), + , + ), + getAction( + "Удалить", + () => onDeleteDepartmentClick(element, isSection), + , + ), + ]; + + return ( + + {...actions} + + ); + }; + + const getUsersTable = (section: DepartmentSectionSchema) => { + if (!section.users || section.users.length === 0) { + return Сотрудники не добавлены; + } + return ; + }; + + const getDepartmentSections = (department: DepartmentSchema) => { + if (!department.sections || department.sections.length === 0) return; + + const accordionIds: string[] = []; + const sortedSections: DepartmentSectionSchema[] = department.sections?.sort((a, b) => a.id - b.id) ?? []; + const items = sortedSections.map(section => { + const value = `section ${section.id}`; + accordionIds.push(value); + return ( + +
+ + Отдел - {section.name} + + {getActions(section, true)} +
+ + {getUsersTable(section)} + +
+ ); + }); + + return ( + + {items} + + ); + }; + + const getDepartments = departments.map((department) => { + return ( + +
+ + Департамент - {department.name} + + {getActions(department, false)} +
+ + {getDepartmentSections(department)} + +
+ ); + }); + + return ( + setDepartmentIds(value)} + bd={"solid 1px gray"} + > + {getDepartments} + + ); +}; + +export default DepartmentsTree; diff --git a/src/pages/AdminPage/tabs/RolesAndPositions/RolesAndPositionsTab.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/RolesAndPositions.tsx similarity index 71% rename from src/pages/AdminPage/tabs/RolesAndPositions/RolesAndPositionsTab.tsx rename to src/pages/AdminPage/tabs/OrganizationalStructureTab/components/RolesAndPositions.tsx index 5e857eb..4f3d904 100644 --- a/src/pages/AdminPage/tabs/RolesAndPositions/RolesAndPositionsTab.tsx +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/RolesAndPositions.tsx @@ -1,9 +1,9 @@ -import PositionsTable from "../../components/PositionsTable/PositionsTable.tsx"; -import usePositionsList from "../../hooks/usePositionsList.tsx"; -import { PositionSchema, PositionService } from "../../../../client"; -import { notifications } from "../../../../shared/lib/notifications.ts"; +import PositionsTable from "../../../components/PositionsTable/PositionsTable.tsx"; +import usePositionsList from "../../../hooks/usePositionsList.tsx"; +import { PositionSchema, PositionService } from "../../../../../client"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; -const RolesAndPositionsTab = () => { +const RolesAndPositions = () => { const { objects: positions, refetch } = usePositionsList(); const onCreate = (position: PositionSchema) => { PositionService.createPosition({ @@ -36,4 +36,4 @@ const RolesAndPositionsTab = () => { /> ); }; -export default RolesAndPositionsTab; +export default RolesAndPositions; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UserForDepartmentSelect.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UserForDepartmentSelect.tsx new file mode 100644 index 0000000..3043708 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UserForDepartmentSelect.tsx @@ -0,0 +1,27 @@ +import { FC } from "react"; +import ObjectSelect, { ObjectSelectProps } from "../../../../../components/ObjectSelect/ObjectSelect.tsx"; +import { UserSchema } from "../../../../../client"; +import useAvailableUsersList from "../hooks/useAvailableUsersList.tsx"; + +type SectionData = { + sectionId: number; +} + +type Props = SectionData & Omit< + ObjectSelectProps, + "data" | "getValueFn" | "getLabelFn" +>; + +const UserForDepartmentSelect: FC = props => { + const { objects: users } = useAvailableUsersList({ sectionId: props.sectionId }); + + return ( + `${user.firstName} ${user.secondName}`} + getValueFn={(user: UserSchema) => user.id.toString()} + {...props} + /> + ); +}; +export default UserForDepartmentSelect; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UsersTable.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UsersTable.tsx new file mode 100644 index 0000000..72b523b --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/components/UsersTable.tsx @@ -0,0 +1,63 @@ +import { BaseTable } from "../../../../../components/BaseTable/BaseTable.tsx"; +import useUsersTableColumns from "../hooks/useUsersTableColumns.tsx"; +import { DepartmentService, UserSchema } from "../../../../../client"; +import { ActionIcon, Flex, Tooltip } from "@mantine/core"; +import { IconTrash } from "@tabler/icons-react"; +import { MRT_TableOptions } from "mantine-react-table"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; +import { useDepartmentContext } from "../contexts/DepartmentContext.tsx"; + + +type Props = { + users: UserSchema[]; + sectionId: number; +} + +const UsersTable = ({ users, sectionId }: Props) => { + const columns = useUsersTableColumns(); + const { fetchDepartments } = useDepartmentContext(); + + const onDeleteUserClick = (userId: number) => { + DepartmentService.deleteUser({ + requestBody: { + sectionId, + userId, + } + }) + .then(({ok, message}) => { + fetchDepartments(); + if (ok) return; + notifications.error({ message }); + }) + .catch(err => console.log(err)); + } + + return ( + ( + + + onDeleteUserClick(row.original.id)} + variant={"default"}> + + + + + ), + } as MRT_TableOptions + } + /> + ) +} + +export default UsersTable; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/contexts/DepartmentContext.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/contexts/DepartmentContext.tsx new file mode 100644 index 0000000..763c721 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/contexts/DepartmentContext.tsx @@ -0,0 +1,153 @@ +import React, { createContext, FC, useContext, useEffect, useState } from "react"; +import { + DepartmentSchema, + DepartmentSectionBaseSchema, + DepartmentSectionSchema, + DepartmentService, +} from "../../../../../client"; +import { modals } from "@mantine/modals"; +import { Text } from "@mantine/core"; +import useDepartmentCrud from "../hooks/useDepartmentCrud.tsx"; +import useDepartmentSectionCrud from "../hooks/useDepartmentSectionCrud.tsx"; + +type DepartmentContextState = { + departments: DepartmentSchema[], + departmentIds: string[], + setDepartmentIds: React.Dispatch>, + fetchDepartments: () => void, + onCreateDepartmentClick: (isSection: boolean, element?: DepartmentSectionBaseSchema) => void, + onUpdateDepartmentClick: (element: DepartmentSchema | DepartmentSectionSchema, isSection: boolean) => void, + onDeleteDepartmentClick: (element: DepartmentSchema, isSection: boolean) => void, + onAddUserClick: (departmentSection: DepartmentSectionSchema) => void, + toggleAllDepartmentIds: () => void, +}; + +const DepartmentContext = createContext( + undefined, +); + +const useDepartmentContextState = () => { + const [departments, setDepartments] = useState([]); + const [departmentIds, setDepartmentIds] = useState([]); + + const fetchDepartments = () => { + DepartmentService.getDepartments() + .then(res => { + setDepartments(res.departments); + if (departmentIds.length === 0) { + setDepartmentIds(res.departments.map(dep => dep.id.toString())); + } + }) + .catch(e => console.log(e)); + }; + + const departmentsCrud = useDepartmentCrud({ fetchDepartments }); + const departmentSectionsCrud = useDepartmentSectionCrud({ fetchDepartments }); + + useEffect(() => { + fetchDepartments(); + }, []); + + const openDepartmentModal = ( + title: string, + isDepartmentSection: boolean, + element?: DepartmentSchema | DepartmentSectionSchema | DepartmentSectionBaseSchema, + ) => { + modals.openContextModal({ + modal: "departmentModal", + title, + withCloseButton: false, + innerProps: { + departmentsCrud, + departmentSectionsCrud, + isDepartmentSection, + element, + }, + }); + }; + + const onCreateDepartmentClick = (isSection: boolean, element?: DepartmentSectionBaseSchema) => { + const title: string = isSection ? "Создание отдела" : "Создание департамента"; + openDepartmentModal(title, isSection, element); + }; + + const onUpdateDepartmentClick = (element: DepartmentSchema | DepartmentSectionSchema, isSection: boolean) => { + const title: string = isSection ? "Редактирование отдела" : "Редактирование департамента"; + openDepartmentModal(title, isSection, element); + }; + + const onDeleteDepartmentClick = (element: DepartmentSchema | DepartmentSectionSchema, isSection: boolean) => { + modals.openConfirmModal({ + title: "Удаление " + (isSection ? "отдела" : "департамента"), + children: ( + + Вы уверены что хотите удалить {isSection ? "отдел" : "департамент"} {element.name}? + + ), + labels: { confirm: "Да", cancel: "Нет" }, + confirmProps: { color: "red" }, + onConfirm: () => { + if (isSection) { + departmentSectionsCrud.onDelete(element as DepartmentSectionSchema); + } else { + departmentsCrud.onDelete(element); + } + }, + }); + }; + + const onAddUserClick = (departmentSection: DepartmentSectionSchema) => { + modals.openContextModal({ + modal: "addUserToDepartmentModal", + title: `Добавление пользователя в отдел ${departmentSection.name}`, + withCloseButton: false, + innerProps: { + departmentSection, + fetchDepartments, + }, + }); + } + + const toggleAllDepartmentIds = () => { + if (departmentIds.length > 0) { + setDepartmentIds([]); + return; + } + setDepartmentIds(departments.map(department => department.id.toString())); + } + + return { + departments, + departmentIds, + setDepartmentIds, + fetchDepartments, + onCreateDepartmentClick, + onUpdateDepartmentClick, + onDeleteDepartmentClick, + onAddUserClick, + toggleAllDepartmentIds, + }; +}; + +type DepartmentContextProviderProps = { + children: React.ReactNode; +}; + +export const DepartmentContextProvider: FC = ({ children }) => { + const state = useDepartmentContextState(); + return ( + + {children} + + ); +}; + +export const useDepartmentContext = () => { + const context = useContext(DepartmentContext); + if (!context) { + throw new Error( + "useDepartmentContext must be used within a DepartmentContextProvider", + ); + } + return context; +}; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useAvailableUsersList.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useAvailableUsersList.tsx new file mode 100644 index 0000000..3057a85 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useAvailableUsersList.tsx @@ -0,0 +1,16 @@ +import { DepartmentService } from "../../../../../client"; +import ObjectList from "../../../../../hooks/objectList.tsx"; + + +type Props = { + sectionId: number; +} + +const useAvailableUsersList = ({ sectionId }: Props) => + ObjectList({ + queryFn: () => DepartmentService.getAvailableUsersForSection({ sectionId }), + getObjectsFn: response => response.users, + queryKey: "getAvailableUsersForDepartmentSection", + }); + +export default useAvailableUsersList; \ No newline at end of file diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentCrud.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentCrud.tsx new file mode 100644 index 0000000..5558672 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentCrud.tsx @@ -0,0 +1,49 @@ +import { useCRUD } from "../../../../../hooks/useCRUD.tsx"; +import { DepartmentBaseSchema, DepartmentSchema, DepartmentService } from "../../../../../client"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; + + +export type DepartmentCrud = { + onCreate: (element: DepartmentBaseSchema) => void, + onDelete: (element: DepartmentSchema) => void, + onChange: (element: DepartmentSchema) => void +} + +type Props = { + fetchDepartments: () => void; +} + +const useDepartmentCrud = ({ fetchDepartments }: Props): DepartmentCrud => { + return useCRUD({ + onChange: department => { + DepartmentService.updateDepartment({ + requestBody: { department }, + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + onCreate: department => { + DepartmentService.createDepartment({ + requestBody: { department }, + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + onDelete: department => { + DepartmentService.deleteDepartment({ departmentId: department.id }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + }); +}; + +export default useDepartmentCrud; \ No newline at end of file diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentSectionCrud.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentSectionCrud.tsx new file mode 100644 index 0000000..9dcc6a5 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useDepartmentSectionCrud.tsx @@ -0,0 +1,49 @@ +import { useCRUD } from "../../../../../hooks/useCRUD.tsx"; +import { DepartmentSectionBaseSchema, DepartmentSectionSchema, DepartmentService } from "../../../../../client"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; + + +export type DepartmentSectionCrud = { + onCreate: (element: DepartmentSectionBaseSchema) => void, + onDelete: (element: DepartmentSectionSchema) => void, + onChange: (element: DepartmentSectionSchema) => void +} + +type Props = { + fetchDepartments: () => void; +} + +const useDepartmentSectionCrud = ({ fetchDepartments }: Props): DepartmentSectionCrud => { + return useCRUD({ + onChange: section => { + DepartmentService.updateSection({ + requestBody: { section }, + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + onCreate: section => { + DepartmentService.createSection({ + requestBody: { section }, + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + onDelete: section => { + DepartmentService.deleteSection({ sectionId: section.id }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + fetchDepartments(); + }) + .catch(err => console.log(err)); + }, + }); +}; + +export default useDepartmentSectionCrud; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useUsersTableColumns.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useUsersTableColumns.tsx new file mode 100644 index 0000000..1b41f4e --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/hooks/useUsersTableColumns.tsx @@ -0,0 +1,31 @@ +import { useMemo } from "react"; +import { MRT_ColumnDef } from "mantine-react-table"; +import { UserSchema } from "../../../../../client"; + + +const useUsersTableColumns = () => { + return useMemo[]>( + () => [ + { + header: "ФИО", + Cell: ({ row }) => + `${row.original.secondName} ${row.original.firstName} ${row.original.patronymic}`, + }, + { + accessorKey: "role.name", + header: "Роль", + }, + { + accessorKey: "position.name", + header: "Должность", + }, + { + accessorKey: "comment", + header: "Доп. информация", + } + ], + [], + ); +}; + +export default useUsersTableColumns; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/AddUserToDepartmentModal.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/AddUserToDepartmentModal.tsx new file mode 100644 index 0000000..1f9437c --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/AddUserToDepartmentModal.tsx @@ -0,0 +1,64 @@ +import { useForm } from "@mantine/form"; +import { ContextModalProps } from "@mantine/modals"; +import { Button, Flex, rem } from "@mantine/core"; +import { DepartmentSectionSchema, DepartmentService } from "../../../../../client"; +import AddUserToDepartmentModalForm from "../types/AddUserToDepartmentModalForm.tsx"; +import { notifications } from "../../../../../shared/lib/notifications.ts"; +import UserForDepartmentSelect from "../components/UserForDepartmentSelect.tsx"; + +type Props = { + departmentSection: DepartmentSectionSchema; + fetchDepartments: () => void; +} + +const AddUserToDepartmentModal = ({ + context, + id, + innerProps, + }: ContextModalProps) => { + const form = useForm>({ + validate: { + user: user => !user && "Необходимо выбрать пользователя", + }, + }); + + const onSubmit = () => { + if (!form.values.user) return; + DepartmentService.addUser({ + requestBody: { + userId: form.values.user.id, + sectionId: innerProps.departmentSection.id, + } + }) + .then(({ ok, message }) => { + notifications.guess(ok, { message }); + innerProps.fetchDepartments(); + }) + .catch(err => console.log(err)); + + context.closeContextModal(id); + }; + + return ( +
onSubmit())}> + + + + +
+ ); +}; + +export default AddUserToDepartmentModal; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/DepartmentModal.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/DepartmentModal.tsx new file mode 100644 index 0000000..5615922 --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/modals/DepartmentModal.tsx @@ -0,0 +1,79 @@ +import { useForm } from "@mantine/form"; +import { ContextModalProps } from "@mantine/modals"; +import { Button, Flex, rem, TextInput } from "@mantine/core"; +import { DepartmentModalForm } from "../types/DepartmentModalForm.tsx"; +import { DepartmentSchema, DepartmentSectionBaseSchema, DepartmentSectionSchema } from "../../../../../client"; +import { DepartmentCrud } from "../hooks/useDepartmentCrud.tsx"; +import { DepartmentSectionCrud } from "../hooks/useDepartmentSectionCrud.tsx"; + +type Props = { + departmentsCrud: DepartmentCrud; + departmentSectionsCrud: DepartmentSectionCrud; + element?: DepartmentSchema | DepartmentSectionSchema | DepartmentSectionBaseSchema; + isDepartmentSection: boolean; +} + +const DepartmentModal = ({ + context, + id, + innerProps, + }: ContextModalProps) => { + const { + departmentsCrud, + departmentSectionsCrud, + element, + isDepartmentSection, + } = innerProps; + + const initialValues: DepartmentModalForm = { + name: element?.name ?? "", + }; + const form = useForm({ + initialValues, + validate: { + name: name => !name && "Необходимо указать название", + }, + }); + + const onSubmit = () => { + if (isDepartmentSection) { + const sectionData = { ...element as DepartmentSectionSchema, ...form.values }; + if (sectionData.id) { + departmentSectionsCrud.onChange(sectionData); + } else { + departmentSectionsCrud.onCreate(sectionData); + } + } else { + const departmentData = element as DepartmentSchema; + if (element) { + departmentsCrud.onChange({ ...form.values, id: departmentData.id }); + } else { + departmentsCrud.onCreate(form.values); + } + } + context.closeContextModal(id); + }; + + return ( +
onSubmit())}> + + + + + +
+ ); +}; + +export default DepartmentModal; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/AddUserToDepartmentModalForm.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/AddUserToDepartmentModalForm.tsx new file mode 100644 index 0000000..493d29d --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/AddUserToDepartmentModalForm.tsx @@ -0,0 +1,7 @@ +import { UserSchema } from "../../../../../client"; + +type AddUserToDepartmentModalForm = { + user: UserSchema; +} + +export default AddUserToDepartmentModalForm; diff --git a/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/DepartmentModalForm.tsx b/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/DepartmentModalForm.tsx new file mode 100644 index 0000000..736a8ad --- /dev/null +++ b/src/pages/AdminPage/tabs/OrganizationalStructureTab/types/DepartmentModalForm.tsx @@ -0,0 +1,3 @@ +export type DepartmentModalForm = { + name: string; +}