начал работу над функционалом сущности Section
This commit is contained in:
parent
83010d4a0a
commit
14a7fdbf45
@ -6,6 +6,9 @@ import RoleEdit from "./components/Role/Edit";
|
|||||||
import UsersList from "./components/User/List";
|
import UsersList from "./components/User/List";
|
||||||
import UserCreate from "./components/User/Create";
|
import UserCreate from "./components/User/Create";
|
||||||
import UserEdit from "./components/User/Edit";
|
import UserEdit from "./components/User/Edit";
|
||||||
|
import SectionsList from "./components/Section/List";
|
||||||
|
import SectionCreate from "./components/Section/Create";
|
||||||
|
import SectionEdit from "./components/Section/Edit";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
@ -22,6 +25,12 @@ function App() {
|
|||||||
create={<UserCreate />}
|
create={<UserCreate />}
|
||||||
edit={<UserEdit />}
|
edit={<UserEdit />}
|
||||||
/>
|
/>
|
||||||
|
<Resource
|
||||||
|
name="sections"
|
||||||
|
list={<SectionsList />}
|
||||||
|
create={<SectionCreate />}
|
||||||
|
edit={<SectionEdit />}
|
||||||
|
/>
|
||||||
</Admin>
|
</Admin>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
16
client/src/components/Section/Create.tsx
Normal file
16
client/src/components/Section/Create.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Create, ReferenceInput, SelectInput, SimpleForm, TextInput } from "react-admin";
|
||||||
|
|
||||||
|
function SectionCreate() {
|
||||||
|
return (
|
||||||
|
<Create>
|
||||||
|
<SimpleForm>
|
||||||
|
<TextInput source="name" fullWidth />
|
||||||
|
<ReferenceInput source="root_section_id" reference="sections">
|
||||||
|
<SelectInput optionText="name" fullWidth />
|
||||||
|
</ReferenceInput>
|
||||||
|
</SimpleForm>
|
||||||
|
</Create>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SectionCreate;
|
22
client/src/components/Section/Edit.tsx
Normal file
22
client/src/components/Section/Edit.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Edit, ReferenceInput, SelectInput, SimpleForm, TextInput, useGetList, useRecordContext } from "react-admin";
|
||||||
|
import Title from "../Title";
|
||||||
|
|
||||||
|
function SectionEdit() {
|
||||||
|
// const record = useRecordContext();
|
||||||
|
// if (!record) return null;
|
||||||
|
|
||||||
|
// const { data } = useGetList("sections", { id: record.id });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Edit title={<Title prefixText="Роль" />} actions={false}>
|
||||||
|
<SimpleForm>
|
||||||
|
<TextInput source="name" fullWidth />
|
||||||
|
{/* <ReferenceInput source="root_section_id" reference="sections"> */}
|
||||||
|
{/* <SelectInput choices={data} optionText="name" fullWidth /> */}
|
||||||
|
{/* </ReferenceInput> */}
|
||||||
|
</SimpleForm>
|
||||||
|
</Edit>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SectionEdit;
|
16
client/src/components/Section/List.tsx
Normal file
16
client/src/components/Section/List.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { List, Datagrid, TextField, EditButton } from "react-admin";
|
||||||
|
|
||||||
|
function SectionsList() {
|
||||||
|
return (
|
||||||
|
<List>
|
||||||
|
<Datagrid>
|
||||||
|
<TextField source="id" />
|
||||||
|
<TextField source="name" />
|
||||||
|
<TextField source="root_section_id" />
|
||||||
|
<EditButton />
|
||||||
|
</Datagrid>
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SectionsList;
|
142
server/controllers/section/section.controller.ts
Normal file
142
server/controllers/section/section.controller.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import Section from "../../models/section.model";
|
||||||
|
import { ApiErrorHandler } from "../../error/api-error.handler";
|
||||||
|
import type { ISectionDto } from "./section.dto";
|
||||||
|
import type { Order } from "sequelize";
|
||||||
|
import type { NextFunction, Request, Response } from "express";
|
||||||
|
import type {
|
||||||
|
FilterQueryParamType,
|
||||||
|
RangeQueryParamType,
|
||||||
|
SortQueryParamType
|
||||||
|
} from "../query-param.types";
|
||||||
|
|
||||||
|
class SectionController {
|
||||||
|
getAll = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const range: RangeQueryParamType = req.query.range
|
||||||
|
? JSON.parse(req.query.range.toString())
|
||||||
|
: [0, 10];
|
||||||
|
const sort: SortQueryParamType = req.query.sort
|
||||||
|
? JSON.parse(req.query.sort.toString())
|
||||||
|
: ["id", "ASC"];
|
||||||
|
|
||||||
|
const sections = await Section.findAndCountAll({
|
||||||
|
offset: range[0],
|
||||||
|
limit: range[1] - range[0] + 1,
|
||||||
|
order: [sort] as Order
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json({ data: sections.rows, total: sections.count });
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getMany = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response<{ data: Section[] }>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const filter: FilterQueryParamType = req.query.filter
|
||||||
|
? JSON.parse(req.query.filter.toString())
|
||||||
|
: { ids: [] };
|
||||||
|
|
||||||
|
const sections = await Section.findAll({
|
||||||
|
where: { id: filter.ids as number[] }
|
||||||
|
});
|
||||||
|
return res.json({ data: sections });
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
create = async (
|
||||||
|
req: Request<object, object, ISectionDto>,
|
||||||
|
res: Response<Section>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { name, root_section_id } = req.body;
|
||||||
|
const section = await Section.create({ name, root_section_id });
|
||||||
|
return res.json(section);
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getById = async (
|
||||||
|
req: Request<{ id: number }>,
|
||||||
|
res: Response<Section>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
const section = await Section.findByPk(id);
|
||||||
|
if (!section) return next(ApiErrorHandler.notFound("Такой роли не найдено"));
|
||||||
|
|
||||||
|
return res.json(section);
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
update = async (
|
||||||
|
req: Request<{ id: number }, object, ISectionDto>,
|
||||||
|
res: Response<Section>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { name } = req.body;
|
||||||
|
|
||||||
|
const section = await Section.findByPk(id);
|
||||||
|
if (!section) return next(ApiErrorHandler.internal("Такой роли не найдено"));
|
||||||
|
|
||||||
|
section.name = name;
|
||||||
|
await section.save();
|
||||||
|
|
||||||
|
return res.json(section);
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
delete = async (
|
||||||
|
req: Request<{ id: number }>,
|
||||||
|
res: Response<Section>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { id } = req.params;
|
||||||
|
const section = await Section.findByPk(id);
|
||||||
|
if (!section) return next(ApiErrorHandler.internal("Такой роли не найдено"));
|
||||||
|
|
||||||
|
await section.destroy();
|
||||||
|
|
||||||
|
return res.json(section);
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteMany = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response<{ data: Section[] }>,
|
||||||
|
next: NextFunction
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const filter: FilterQueryParamType = req.query.filter
|
||||||
|
? JSON.parse(req.query.filter.toString())
|
||||||
|
: {};
|
||||||
|
const sections = await Section.findAll({ where: filter });
|
||||||
|
|
||||||
|
Section.destroy({ where: filter });
|
||||||
|
|
||||||
|
return res.json({ data: sections });
|
||||||
|
} catch (error) {
|
||||||
|
next(ApiErrorHandler.internal((error as Error).message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new SectionController();
|
4
server/controllers/section/section.dto.ts
Normal file
4
server/controllers/section/section.dto.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface ISectionDto {
|
||||||
|
name: string;
|
||||||
|
root_section_id: number | null;
|
||||||
|
}
|
@ -2,6 +2,7 @@ import dotenv from "dotenv";
|
|||||||
import { Sequelize } from "sequelize-typescript";
|
import { Sequelize } from "sequelize-typescript";
|
||||||
import Role from "./models/role.model";
|
import Role from "./models/role.model";
|
||||||
import User from "./models/user.model";
|
import User from "./models/user.model";
|
||||||
|
import Section from "./models/section.model";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@ -12,5 +13,5 @@ export const sequelize = new Sequelize({
|
|||||||
password: process.env.DB_PASSWORD,
|
password: process.env.DB_PASSWORD,
|
||||||
host: process.env.DB_HOST,
|
host: process.env.DB_HOST,
|
||||||
port: process.env.DB_PORT,
|
port: process.env.DB_PORT,
|
||||||
models: [Role, User]
|
models: [Role, User, Section]
|
||||||
});
|
});
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { DataTypes } from "sequelize";
|
|
||||||
|
|
||||||
export const customCreatedAndUpdatedFields = {
|
|
||||||
createdAt: "created_at",
|
|
||||||
updatedAt: "updated_at"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const idSettingsObject = { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true };
|
|
51
server/models/section.model.ts
Normal file
51
server/models/section.model.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import {
|
||||||
|
Table,
|
||||||
|
Column,
|
||||||
|
Model,
|
||||||
|
DataType,
|
||||||
|
Length,
|
||||||
|
UpdatedAt,
|
||||||
|
CreatedAt,
|
||||||
|
ForeignKey,
|
||||||
|
BelongsTo,
|
||||||
|
HasMany
|
||||||
|
} from "sequelize-typescript";
|
||||||
|
|
||||||
|
@Table({
|
||||||
|
tableName: "sections",
|
||||||
|
modelName: "Section"
|
||||||
|
})
|
||||||
|
export default class Section extends Model {
|
||||||
|
@Column({
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataType.INTEGER
|
||||||
|
})
|
||||||
|
declare id: number;
|
||||||
|
|
||||||
|
@Length({ min: 1 })
|
||||||
|
@Column({
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: "Unknown",
|
||||||
|
type: DataType.STRING
|
||||||
|
})
|
||||||
|
declare name: string;
|
||||||
|
|
||||||
|
@CreatedAt
|
||||||
|
declare created_at: Date;
|
||||||
|
|
||||||
|
@UpdatedAt
|
||||||
|
declare updated_at: Date;
|
||||||
|
|
||||||
|
@ForeignKey(() => Section)
|
||||||
|
@Column({
|
||||||
|
type: DataType.INTEGER
|
||||||
|
})
|
||||||
|
declare root_section_id: number;
|
||||||
|
|
||||||
|
@BelongsTo(() => Section, "root_section_id")
|
||||||
|
declare root_section: Section;
|
||||||
|
|
||||||
|
@HasMany(() => Section, "root_section_id")
|
||||||
|
declare inner_sections: Section[];
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import roleRouter from "./routes/role.router";
|
import roleRouter from "./routes/role.router";
|
||||||
import userRouter from "./routes/user.router";
|
import userRouter from "./routes/user.router";
|
||||||
|
import sectionRouter from "./routes/section.router";
|
||||||
|
|
||||||
export const router = Router();
|
export const router = Router();
|
||||||
|
|
||||||
router.use("/roles", roleRouter);
|
router.use("/roles", roleRouter);
|
||||||
router.use("/users", userRouter);
|
router.use("/users", userRouter);
|
||||||
|
router.use("/sections", sectionRouter);
|
||||||
|
@ -11,4 +11,4 @@ roleRouter.put("/:id", RoleController.update);
|
|||||||
roleRouter.delete("/delete-many", RoleController.deleteMany);
|
roleRouter.delete("/delete-many", RoleController.deleteMany);
|
||||||
roleRouter.delete("/:id", RoleController.delete);
|
roleRouter.delete("/:id", RoleController.delete);
|
||||||
|
|
||||||
export default roleRouter;
|
export default roleRouter;
|
||||||
|
14
server/routes/routes/section.router.ts
Normal file
14
server/routes/routes/section.router.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
import SectionController from "../../controllers/section/section.controller";
|
||||||
|
|
||||||
|
const sectionRouter = Router();
|
||||||
|
|
||||||
|
sectionRouter.post("/", SectionController.create);
|
||||||
|
sectionRouter.get("/", SectionController.getAll);
|
||||||
|
sectionRouter.get("/get-many", SectionController.getMany);
|
||||||
|
sectionRouter.get("/:id", SectionController.getById);
|
||||||
|
sectionRouter.put("/:id", SectionController.update);
|
||||||
|
sectionRouter.delete("/delete-many", SectionController.deleteMany);
|
||||||
|
sectionRouter.delete("/:id", SectionController.delete);
|
||||||
|
|
||||||
|
export default sectionRouter;
|
Loading…
x
Reference in New Issue
Block a user