начал работу на функционалом Thread, мелкие правки
This commit is contained in:
parent
7ccdcd4227
commit
ed3f2cb63e
9
client/.prettierrc
Normal file
9
client/.prettierrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"semi": true,
|
||||
"jsxSingleQuote": false,
|
||||
"bracketSpacing": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 90,
|
||||
"tabWidth": 2,
|
||||
"arrowParens": "always"
|
||||
}
|
@ -1 +0,0 @@
|
||||
module.exports = {}
|
@ -9,6 +9,8 @@ import UserEdit from "./components/User/Edit";
|
||||
import SectionsList from "./components/Section/List";
|
||||
import SectionCreate from "./components/Section/Create";
|
||||
import SectionEdit from "./components/Section/Edit";
|
||||
import ThreadsList from "./components/Thread/List";
|
||||
import ThreadCreate from "./components/Thread/Create";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@ -31,6 +33,12 @@ function App() {
|
||||
create={<SectionCreate />}
|
||||
edit={<SectionEdit />}
|
||||
/>
|
||||
<Resource
|
||||
name="threads"
|
||||
list={<ThreadsList />}
|
||||
create={<ThreadCreate />}
|
||||
// edit={<SectionEdit />}
|
||||
/>
|
||||
</Admin>
|
||||
);
|
||||
}
|
||||
|
26
client/src/components/Thread/Create.tsx
Normal file
26
client/src/components/Thread/Create.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import {
|
||||
Create,
|
||||
ReferenceInput,
|
||||
SelectInput,
|
||||
SimpleForm,
|
||||
TextInput,
|
||||
required
|
||||
} from "react-admin";
|
||||
|
||||
function ThreadCreate() {
|
||||
return (
|
||||
<Create>
|
||||
<SimpleForm>
|
||||
<TextInput source="name" fullWidth />
|
||||
<ReferenceInput source="section_id" reference="sections">
|
||||
<SelectInput optionText="name" fullWidth validate={required()} />
|
||||
</ReferenceInput>
|
||||
<ReferenceInput source="creator_id" reference="users">
|
||||
<SelectInput optionText="nickname" fullWidth validate={required()} />
|
||||
</ReferenceInput>
|
||||
</SimpleForm>
|
||||
</Create>
|
||||
);
|
||||
}
|
||||
|
||||
export default ThreadCreate;
|
31
client/src/components/Thread/Edit.tsx
Normal file
31
client/src/components/Thread/Edit.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import {
|
||||
Edit,
|
||||
ReferenceInput,
|
||||
SelectInput,
|
||||
SimpleForm,
|
||||
TextInput,
|
||||
useGetRecordId,
|
||||
} from "react-admin";
|
||||
import Title from "../Title";
|
||||
|
||||
function SectionEdit() {
|
||||
const recordId = useGetRecordId();
|
||||
|
||||
return (
|
||||
<Edit title={<Title prefixText="Роль" />} actions={false}>
|
||||
<SimpleForm>
|
||||
<TextInput source="name" fullWidth />
|
||||
|
||||
<ReferenceInput
|
||||
source="root_section_id"
|
||||
reference="sections"
|
||||
filter={{ id: recordId }}
|
||||
>
|
||||
<SelectInput optionText="name" fullWidth />
|
||||
</ReferenceInput>
|
||||
</SimpleForm>
|
||||
</Edit>
|
||||
);
|
||||
}
|
||||
|
||||
export default SectionEdit;
|
17
client/src/components/Thread/List.tsx
Normal file
17
client/src/components/Thread/List.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { List, Datagrid, TextField, EditButton } from "react-admin";
|
||||
|
||||
function ThreadsList() {
|
||||
return (
|
||||
<List>
|
||||
<Datagrid>
|
||||
<TextField source="id" />
|
||||
<TextField source="name" />
|
||||
<TextField source="section_id" />
|
||||
<TextField source="creator_id" />
|
||||
<EditButton />
|
||||
</Datagrid>
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThreadsList;
|
145
server/controllers/thread/thread.controller.ts
Normal file
145
server/controllers/thread/thread.controller.ts
Normal file
@ -0,0 +1,145 @@
|
||||
import { type Order } from "sequelize";
|
||||
import Section from "../../models/section.model";
|
||||
import { ApiErrorHandler } from "../../error/api-error.handler";
|
||||
import Thread from "../../models/thread.model";
|
||||
import type { IThreadDto } from "./thread.dto";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
import type {
|
||||
FilterQueryParamType,
|
||||
RangeQueryParamType,
|
||||
SortQueryParamType
|
||||
} from "../query-param.types";
|
||||
|
||||
class ThreadController {
|
||||
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 threads = await Thread.findAndCountAll({
|
||||
offset: range[0],
|
||||
limit: range[1] - range[0] + 1,
|
||||
order: [sort] as Order
|
||||
});
|
||||
|
||||
return res.json({ data: threads.rows, total: threads.count });
|
||||
} catch (error) {
|
||||
next(ApiErrorHandler.internal((error as Error).message));
|
||||
}
|
||||
};
|
||||
|
||||
getMany = async (
|
||||
req: Request,
|
||||
res: Response<{ data: Thread[] }>,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const filter: FilterQueryParamType = req.query.filter
|
||||
? JSON.parse(req.query.filter.toString())
|
||||
: { ids: [] };
|
||||
|
||||
const threads = await Thread.findAll({
|
||||
where: { id: filter.ids as number[] }
|
||||
});
|
||||
return res.json({ data: threads });
|
||||
} catch (error) {
|
||||
next(ApiErrorHandler.internal((error as Error).message));
|
||||
}
|
||||
};
|
||||
|
||||
create = async (
|
||||
req: Request<object, object, IThreadDto>,
|
||||
res: Response<Thread>,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const { name, section_id, creator_id } = req.body;
|
||||
const thread = await Thread.create({ name, section_id, creator_id });
|
||||
return res.json(thread);
|
||||
} catch (error) {
|
||||
next(ApiErrorHandler.internal((error as Error).message));
|
||||
}
|
||||
};
|
||||
|
||||
getById = async (
|
||||
req: Request<{ id: number }>,
|
||||
res: Response<Thread>,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const thread = await Thread.findByPk(id);
|
||||
if (!thread) return next(ApiErrorHandler.notFound("Такой роли не найдено"));
|
||||
|
||||
return res.json(thread);
|
||||
} catch (error) {
|
||||
next(ApiErrorHandler.internal((error as Error).message));
|
||||
}
|
||||
};
|
||||
|
||||
update = async (
|
||||
req: Request<{ id: number }, object, IThreadDto>,
|
||||
res: Response<Thread>,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, section_id, creator_id } = req.body;
|
||||
|
||||
const thread = await Thread.findByPk(id);
|
||||
if (!thread) return next(ApiErrorHandler.internal("Такой роли не найдено"));
|
||||
|
||||
thread.name = name;
|
||||
thread.section_id = section_id;
|
||||
thread.creator_id = creator_id;
|
||||
await thread.save();
|
||||
|
||||
return res.json(thread);
|
||||
} 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 ThreadController();
|
5
server/controllers/thread/thread.dto.ts
Normal file
5
server/controllers/thread/thread.dto.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface IThreadDto {
|
||||
name: string;
|
||||
section_id: number;
|
||||
creator_id: number;
|
||||
}
|
@ -3,6 +3,7 @@ import { Sequelize } from "sequelize-typescript";
|
||||
import Role from "./models/role.model";
|
||||
import User from "./models/user.model";
|
||||
import Section from "./models/section.model";
|
||||
import Thread from "./models/thread.model";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@ -13,5 +14,5 @@ export const sequelize = new Sequelize({
|
||||
password: process.env.DB_PASSWORD,
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
models: [Role, User, Section]
|
||||
models: [Role, User, Section, Thread]
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
BelongsTo,
|
||||
HasMany
|
||||
} from "sequelize-typescript";
|
||||
import Thread from "./thread.model";
|
||||
|
||||
@Table({
|
||||
tableName: "sections",
|
||||
@ -48,4 +49,7 @@ export default class Section extends Model {
|
||||
|
||||
@HasMany(() => Section, "root_section_id")
|
||||
declare inner_sections: Section[];
|
||||
|
||||
// @HasMany(() => Thread, "section_id")
|
||||
// declare threads: Thread[];
|
||||
}
|
||||
|
60
server/models/thread.model.ts
Normal file
60
server/models/thread.model.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import {
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
DataType,
|
||||
Length,
|
||||
UpdatedAt,
|
||||
CreatedAt,
|
||||
ForeignKey,
|
||||
BelongsTo
|
||||
} from "sequelize-typescript";
|
||||
import Section from "./section.model";
|
||||
import User from "./user.model";
|
||||
|
||||
@Table({
|
||||
tableName: "threads",
|
||||
modelName: "Thread"
|
||||
})
|
||||
export default class Thread 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,
|
||||
allowNull: false
|
||||
})
|
||||
declare section_id: number;
|
||||
|
||||
@BelongsTo(() => Section, "section_id")
|
||||
declare section: Section;
|
||||
|
||||
@ForeignKey(() => User)
|
||||
@Column({
|
||||
type: DataType.INTEGER,
|
||||
allowNull: false
|
||||
})
|
||||
declare creator_id: number | null;
|
||||
|
||||
@BelongsTo(() => User, "creator_id")
|
||||
declare creator: User;
|
||||
}
|
@ -7,9 +7,11 @@ import {
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
ForeignKey,
|
||||
BelongsTo
|
||||
BelongsTo,
|
||||
HasMany
|
||||
} from "sequelize-typescript";
|
||||
import Role from "./role.model";
|
||||
import Thread from "./thread.model";
|
||||
|
||||
@Table({
|
||||
timestamps: true,
|
||||
@ -69,4 +71,7 @@ export default class User extends Model {
|
||||
|
||||
@BelongsTo(() => Role, "role_id")
|
||||
declare role: Role;
|
||||
|
||||
// @HasMany(() => Thread, "thread_id")
|
||||
// declare threads: Thread[];
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ import { Router } from "express";
|
||||
import roleRouter from "./routes/role.router";
|
||||
import userRouter from "./routes/user.router";
|
||||
import sectionRouter from "./routes/section.router";
|
||||
import threadRouter from "./routes/thread.router";
|
||||
|
||||
export const router = Router();
|
||||
|
||||
router.use("/roles", roleRouter);
|
||||
router.use("/users", userRouter);
|
||||
router.use("/sections", sectionRouter);
|
||||
router.use("/threads", threadRouter);
|
||||
|
14
server/routes/routes/thread.router.ts
Normal file
14
server/routes/routes/thread.router.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Router } from "express";
|
||||
import ThreadController from "../../controllers/thread/thread.controller";
|
||||
|
||||
const threadRouter = Router();
|
||||
|
||||
threadRouter.post("/", ThreadController.create);
|
||||
threadRouter.get("/", ThreadController.getAll);
|
||||
threadRouter.get("/get-many", ThreadController.getMany);
|
||||
threadRouter.get("/:id", ThreadController.getById);
|
||||
threadRouter.put("/:id", ThreadController.update);
|
||||
threadRouter.delete("/delete-many", ThreadController.deleteMany);
|
||||
threadRouter.delete("/:id", ThreadController.delete);
|
||||
|
||||
export default threadRouter;
|
Loading…
Reference in New Issue
Block a user