From be7d0ff4d9cda77934ef59ae9b2f5dfb6a6f39f5 Mon Sep 17 00:00:00 2001 From: aid-orchestrator Date: Sat, 25 Apr 2026 16:04:45 +0000 Subject: [PATCH] feat: add generated code --- backend/prisma/schema.prisma | 193 ++++++++++++++++++ backend/src/app.module.ts | 27 +++ .../category-resource.controller.ts | 58 ++++++ .../category-resource.module.ts | 10 + .../category-resource.service.ts | 41 ++++ .../dto/create-category-resource.dto.ts | 14 ++ .../dto/update-category-resource.dto.ts | 4 + .../change-equipment-status.controller.ts | 58 ++++++ .../change-equipment-status.module.ts | 10 + .../change-equipment-status.service.ts | 41 ++++ .../dto/create-change-equipment-status.dto.ts | 40 ++++ .../dto/update-change-equipment-status.dto.ts | 4 + .../confirmation-document.controller.ts | 58 ++++++ .../confirmation-document.module.ts | 10 + .../confirmation-document.service.ts | 41 ++++ .../dto/create-confirmation-document.dto.ts | 30 +++ .../dto/update-confirmation-document.dto.ts | 4 + .../consumption-registration.controller.ts | 58 ++++++ .../consumption-registration.module.ts | 10 + .../consumption-registration.service.ts | 41 ++++ .../create-consumption-registration.dto.ts | 32 +++ .../update-consumption-registration.dto.ts | 4 + .../src/employee/dto/create-employee.dto.ts | 42 ++++ .../src/employee/dto/update-employee.dto.ts | 4 + backend/src/employee/employee.controller.ts | 58 ++++++ backend/src/employee/employee.module.ts | 10 + backend/src/employee/employee.service.ts | 41 ++++ .../src/equipment/dto/create-equipment.dto.ts | 73 +++++++ .../src/equipment/dto/update-equipment.dto.ts | 4 + backend/src/equipment/equipment.controller.ts | 58 ++++++ backend/src/equipment/equipment.module.ts | 10 + backend/src/equipment/equipment.service.ts | 41 ++++ backend/src/part/dto/create-part.dto.ts | 32 +++ backend/src/part/dto/update-part.dto.ts | 4 + backend/src/part/part.controller.ts | 58 ++++++ backend/src/part/part.module.ts | 10 + backend/src/part/part.service.ts | 41 ++++ .../dto/create-repair-order.dto.ts | 72 +++++++ .../dto/update-repair-order.dto.ts | 4 + .../repair-order/repair-order.controller.ts | 58 ++++++ .../src/repair-order/repair-order.module.ts | 10 + .../src/repair-order/repair-order.service.ts | 41 ++++ frontend/src/App.tsx | 90 ++++++++ frontend/src/main.tsx | 19 ++ .../CategoryResourceCreate.tsx | 14 ++ .../CategoryResourceEdit.tsx | 14 ++ .../CategoryResourceList.tsx | 12 ++ .../CategoryResourceShow.tsx | 15 ++ .../src/resources/category-resource/index.ts | 4 + .../ChangeEquipmentStatusCreate.tsx | 24 +++ .../ChangeEquipmentStatusEdit.tsx | 25 +++ .../ChangeEquipmentStatusList.tsx | 17 ++ .../ChangeEquipmentStatusShow.tsx | 20 ++ .../change-equipment-status/index.ts | 4 + .../ConfirmationDocumentCreate.tsx | 17 ++ .../ConfirmationDocumentEdit.tsx | 18 ++ .../ConfirmationDocumentList.tsx | 15 ++ .../ConfirmationDocumentShow.tsx | 20 ++ .../resources/confirmation-document/index.ts | 4 + .../ConsumptionRegistrationCreate.tsx | 15 ++ .../ConsumptionRegistrationEdit.tsx | 16 ++ .../ConsumptionRegistrationList.tsx | 15 ++ .../ConsumptionRegistrationShow.tsx | 18 ++ .../consumption-registration/index.ts | 4 + .../src/resources/employee/EmployeeCreate.tsx | 23 +++ .../src/resources/employee/EmployeeEdit.tsx | 23 +++ .../src/resources/employee/EmployeeList.tsx | 16 ++ .../src/resources/employee/EmployeeShow.tsx | 17 ++ frontend/src/resources/employee/index.ts | 4 + .../resources/equipment/EquipmentCreate.tsx | 43 ++++ .../src/resources/equipment/EquipmentEdit.tsx | 44 ++++ .../src/resources/equipment/EquipmentList.tsx | 22 ++ .../src/resources/equipment/EquipmentShow.tsx | 24 +++ frontend/src/resources/equipment/index.ts | 4 + frontend/src/resources/part/PartCreate.tsx | 20 ++ frontend/src/resources/part/PartEdit.tsx | 21 ++ frontend/src/resources/part/PartList.tsx | 15 ++ frontend/src/resources/part/PartShow.tsx | 14 ++ frontend/src/resources/part/index.ts | 4 + .../repair-order/RepairOrderCreate.tsx | 40 ++++ .../repair-order/RepairOrderEdit.tsx | 41 ++++ .../repair-order/RepairOrderList.tsx | 21 ++ .../repair-order/RepairOrderShow.tsx | 26 +++ frontend/src/resources/repair-order/index.ts | 4 + 84 files changed, 2285 insertions(+) create mode 100644 backend/prisma/schema.prisma create mode 100644 backend/src/app.module.ts create mode 100644 backend/src/category-resource/category-resource.controller.ts create mode 100644 backend/src/category-resource/category-resource.module.ts create mode 100644 backend/src/category-resource/category-resource.service.ts create mode 100644 backend/src/category-resource/dto/create-category-resource.dto.ts create mode 100644 backend/src/category-resource/dto/update-category-resource.dto.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.controller.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.module.ts create mode 100644 backend/src/change-equipment-status/change-equipment-status.service.ts create mode 100644 backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts create mode 100644 backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts create mode 100644 backend/src/confirmation-document/confirmation-document.controller.ts create mode 100644 backend/src/confirmation-document/confirmation-document.module.ts create mode 100644 backend/src/confirmation-document/confirmation-document.service.ts create mode 100644 backend/src/confirmation-document/dto/create-confirmation-document.dto.ts create mode 100644 backend/src/confirmation-document/dto/update-confirmation-document.dto.ts create mode 100644 backend/src/consumption-registration/consumption-registration.controller.ts create mode 100644 backend/src/consumption-registration/consumption-registration.module.ts create mode 100644 backend/src/consumption-registration/consumption-registration.service.ts create mode 100644 backend/src/consumption-registration/dto/create-consumption-registration.dto.ts create mode 100644 backend/src/consumption-registration/dto/update-consumption-registration.dto.ts create mode 100644 backend/src/employee/dto/create-employee.dto.ts create mode 100644 backend/src/employee/dto/update-employee.dto.ts create mode 100644 backend/src/employee/employee.controller.ts create mode 100644 backend/src/employee/employee.module.ts create mode 100644 backend/src/employee/employee.service.ts create mode 100644 backend/src/equipment/dto/create-equipment.dto.ts create mode 100644 backend/src/equipment/dto/update-equipment.dto.ts create mode 100644 backend/src/equipment/equipment.controller.ts create mode 100644 backend/src/equipment/equipment.module.ts create mode 100644 backend/src/equipment/equipment.service.ts create mode 100644 backend/src/part/dto/create-part.dto.ts create mode 100644 backend/src/part/dto/update-part.dto.ts create mode 100644 backend/src/part/part.controller.ts create mode 100644 backend/src/part/part.module.ts create mode 100644 backend/src/part/part.service.ts create mode 100644 backend/src/repair-order/dto/create-repair-order.dto.ts create mode 100644 backend/src/repair-order/dto/update-repair-order.dto.ts create mode 100644 backend/src/repair-order/repair-order.controller.ts create mode 100644 backend/src/repair-order/repair-order.module.ts create mode 100644 backend/src/repair-order/repair-order.service.ts create mode 100644 frontend/src/App.tsx create mode 100644 frontend/src/main.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceCreate.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceEdit.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceList.tsx create mode 100644 frontend/src/resources/category-resource/CategoryResourceShow.tsx create mode 100644 frontend/src/resources/category-resource/index.ts create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx create mode 100644 frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx create mode 100644 frontend/src/resources/change-equipment-status/index.ts create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx create mode 100644 frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx create mode 100644 frontend/src/resources/confirmation-document/index.ts create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx create mode 100644 frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx create mode 100644 frontend/src/resources/consumption-registration/index.ts create mode 100644 frontend/src/resources/employee/EmployeeCreate.tsx create mode 100644 frontend/src/resources/employee/EmployeeEdit.tsx create mode 100644 frontend/src/resources/employee/EmployeeList.tsx create mode 100644 frontend/src/resources/employee/EmployeeShow.tsx create mode 100644 frontend/src/resources/employee/index.ts create mode 100644 frontend/src/resources/equipment/EquipmentCreate.tsx create mode 100644 frontend/src/resources/equipment/EquipmentEdit.tsx create mode 100644 frontend/src/resources/equipment/EquipmentList.tsx create mode 100644 frontend/src/resources/equipment/EquipmentShow.tsx create mode 100644 frontend/src/resources/equipment/index.ts create mode 100644 frontend/src/resources/part/PartCreate.tsx create mode 100644 frontend/src/resources/part/PartEdit.tsx create mode 100644 frontend/src/resources/part/PartList.tsx create mode 100644 frontend/src/resources/part/PartShow.tsx create mode 100644 frontend/src/resources/part/index.ts create mode 100644 frontend/src/resources/repair-order/RepairOrderCreate.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderEdit.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderList.tsx create mode 100644 frontend/src/resources/repair-order/RepairOrderShow.tsx create mode 100644 frontend/src/resources/repair-order/index.ts diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma new file mode 100644 index 0000000..929af92 --- /dev/null +++ b/backend/prisma/schema.prisma @@ -0,0 +1,193 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +enum EquipmentStatus { + Active + Repair + Reserve + WriteOff +} + +enum RepairOrderStatus { + Draft + Approved + InWork + Done + Cancelled +} + +enum RepairKind { + TO + TR + TRE + KR + AR + MP +} + +enum laborOperation { + Manual + MachineManual + Machine +} + +enum EnumPeriodicityTO { + Ежедневное + Еженедельное + Ежемесячное + Полугодовое + Годовое +} + +enum Role { + Исполнитель + Подписант + Пользователь +} + +enum CategoryPart { + Расходник + Запчасть + Инструмент + Спецодежда +} + +enum EquipmentType { + Производственное + Энергетическое + Насосное + Компрессорное +} + +model Equipment { + id String @id @default(uuid()) + name String + serialNumber String + inventoryNumber String @unique + equipmentType EquipmentType + dateOfInspection DateTime? @db.Date + periodicityTO EnumPeriodicityTO + location String? + status EquipmentStatus + commissionedAt DateTime? @db.Date + totalEngineHours Decimal? + engineHoursSinceLastRepair Decimal? + lastRepairAt DateTime? @db.Date + notes String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + repairOrders RepairOrder[] + changeEquipmentStatuses ChangeEquipmentStatus[] + consumptionRegistrations ConsumptionRegistration[] +} + +model Employee { + code String @id + fullName String + role Role + position String + price Float? + phoneNumber Float? + + // Self-referential relation for boss/subordinates + bossId String? + boss Employee? @relation("EmployeeHierarchy", fields: [bossId], references: [code]) + subordinates Employee[] @relation("EmployeeHierarchy") + + // Relations + categoryResources CategoryResource[] + confirmationDocuments ConfirmationDocument[] +} + +model Part { + id String @id @default(uuid()) + name String + categories CategoryPart? + price Float? + description String? + serialNumber String? + + // Relations + categoryResources CategoryResource[] +} + +model CategoryResource { + id String @id @default(uuid()) + + // Relations to Part and Employee (mutually exclusive) + partId String? + part Part? @relation(fields: [partId], references: [id]) + + employeeCode String? + employee Employee? @relation(fields: [employeeCode], references: [code]) +} + +model RepairOrder { + id String @id @default(uuid()) + number String @unique + date DateTime @unique @db.Date + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + repairKind RepairKind + status RepairOrderStatus @default(Draft) + plannedAt DateTime @db.Date + startedAt DateTime? @db.Date + completedAt DateTime? @db.Date + contractor String? + engineHoursAtRepair Decimal? + description String? + notes String? + confirmed Boolean? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + confirmationDocuments ConfirmationDocument[] +} + +model ChangeEquipmentStatus { + id String @id @default(uuid()) + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + newStatus EquipmentStatus + number String? + comment String? + date DateTime @db.Date + responsible String? + document String? // File path or reference + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model ConfirmationDocument { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + managerCode String? + manager Employee? @relation(fields: [managerCode], references: [code]) + orderId String + order RepairOrder @relation(fields: [orderId], references: [id]) + confirmed Boolean? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model ConsumptionRegistration { + id String @id @default(uuid()) + number String? + date DateTime @db.Date + equipmentId String + equipment Equipment @relation(fields: [equipmentId], references: [id]) + totalEngineHours Decimal? + fuelConsumption Decimal? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts new file mode 100644 index 0000000..59f1e14 --- /dev/null +++ b/backend/src/app.module.ts @@ -0,0 +1,27 @@ +import { Module } from '@nestjs/common'; +import { AuthModule } from './auth/auth.module'; +import { PrismaService } from './prisma/prisma.service'; +import { EquipmentModule } from './equipment/equipment.module'; +import { EmployeeModule } from './employee/employee.module'; +import { PartModule } from './part/part.module'; +import { CategoryResourceModule } from './category-resource/category-resource.module'; +import { RepairOrderModule } from './repair-order/repair-order.module'; +import { ChangeEquipmentStatusModule } from './change-equipment-status/change-equipment-status.module'; +import { ConfirmationDocumentModule } from './confirmation-document/confirmation-document.module'; +import { ConsumptionRegistrationModule } from './consumption-registration/consumption-registration.module'; + +@Module({ + imports: [ + AuthModule, + EquipmentModule, + EmployeeModule, + PartModule, + CategoryResourceModule, + RepairOrderModule, + ChangeEquipmentStatusModule, + ConfirmationDocumentModule, + ConsumptionRegistrationModule, + ], + providers: [PrismaService], +}) +export class AppModule {} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.controller.ts b/backend/src/category-resource/category-resource.controller.ts new file mode 100644 index 0000000..359979f --- /dev/null +++ b/backend/src/category-resource/category-resource.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { CategoryResourceService } from './category-resource.service'; +import { CreateCategoryResourceDto } from './dto/create-category-resource.dto'; +import { UpdateCategoryResourceDto } from './dto/update-category-resource.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('category-resource') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('category-resource') +export class CategoryResourceController { + constructor(private readonly categoryResourceService: CategoryResourceService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.categoryResourceService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.categoryResourceService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateCategoryResourceDto) { + return this.categoryResourceService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateCategoryResourceDto) { + return this.categoryResourceService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.categoryResourceService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.module.ts b/backend/src/category-resource/category-resource.module.ts new file mode 100644 index 0000000..093bd07 --- /dev/null +++ b/backend/src/category-resource/category-resource.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { CategoryResourceService } from './category-resource.service'; +import { CategoryResourceController } from './category-resource.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [CategoryResourceController], + providers: [CategoryResourceService, PrismaService], +}) +export class CategoryResourceModule {} \ No newline at end of file diff --git a/backend/src/category-resource/category-resource.service.ts b/backend/src/category-resource/category-resource.service.ts new file mode 100644 index 0000000..b0460fe --- /dev/null +++ b/backend/src/category-resource/category-resource.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { CategoryResource, Prisma } from '@prisma/client'; + +@Injectable() +export class CategoryResourceService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.CategoryResourceWhereInput; + orderBy?: Prisma.CategoryResourceOrderByWithRelationInput; + }): Promise<{ data: CategoryResource[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.categoryResource.findMany({ skip, take, where, orderBy }), + this.prisma.categoryResource.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.CategoryResourceWhereUniqueInput): Promise { + return this.prisma.categoryResource.findUnique({ where }); + } + + async create(data: Prisma.CategoryResourceCreateInput): Promise { + return this.prisma.categoryResource.create({ data }); + } + + async update(params: { + where: Prisma.CategoryResourceWhereUniqueInput; + data: Prisma.CategoryResourceUpdateInput; + }): Promise { + return this.prisma.categoryResource.update(params); + } + + async remove(where: Prisma.CategoryResourceWhereUniqueInput): Promise { + return this.prisma.categoryResource.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/category-resource/dto/create-category-resource.dto.ts b/backend/src/category-resource/dto/create-category-resource.dto.ts new file mode 100644 index 0000000..b472e1e --- /dev/null +++ b/backend/src/category-resource/dto/create-category-resource.dto.ts @@ -0,0 +1,14 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString, IsOptional } from 'class-validator'; + +export class CreateCategoryResourceDto { + @ApiProperty({ required: false, description: 'Идентификатор ЗИП/ТМЦ' }) + @IsString() + @IsOptional() + partId?: string; + + @ApiProperty({ required: false, description: 'Код сотрудника' }) + @IsString() + @IsOptional() + employeeCode?: string; +} \ No newline at end of file diff --git a/backend/src/category-resource/dto/update-category-resource.dto.ts b/backend/src/category-resource/dto/update-category-resource.dto.ts new file mode 100644 index 0000000..fb0d3e0 --- /dev/null +++ b/backend/src/category-resource/dto/update-category-resource.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateCategoryResourceDto } from './create-category-resource.dto'; + +export class UpdateCategoryResourceDto extends PartialType(CreateCategoryResourceDto) {} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.controller.ts b/backend/src/change-equipment-status/change-equipment-status.controller.ts new file mode 100644 index 0000000..8a48660 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { ChangeEquipmentStatusService } from './change-equipment-status.service'; +import { CreateChangeEquipmentStatusDto } from './dto/create-change-equipment-status.dto'; +import { UpdateChangeEquipmentStatusDto } from './dto/update-change-equipment-status.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('change-equipment-status') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('change-equipment-status') +export class ChangeEquipmentStatusController { + constructor(private readonly changeEquipmentStatusService: ChangeEquipmentStatusService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.changeEquipmentStatusService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.changeEquipmentStatusService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateChangeEquipmentStatusDto) { + return this.changeEquipmentStatusService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.changeEquipmentStatusService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.module.ts b/backend/src/change-equipment-status/change-equipment-status.module.ts new file mode 100644 index 0000000..27bf136 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ChangeEquipmentStatusService } from './change-equipment-status.service'; +import { ChangeEquipmentStatusController } from './change-equipment-status.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ChangeEquipmentStatusController], + providers: [ChangeEquipmentStatusService, PrismaService], +}) +export class ChangeEquipmentStatusModule {} \ No newline at end of file diff --git a/backend/src/change-equipment-status/change-equipment-status.service.ts b/backend/src/change-equipment-status/change-equipment-status.service.ts new file mode 100644 index 0000000..972f1b2 --- /dev/null +++ b/backend/src/change-equipment-status/change-equipment-status.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ChangeEquipmentStatus, Prisma } from '@prisma/client'; + +@Injectable() +export class ChangeEquipmentStatusService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ChangeEquipmentStatusWhereInput; + orderBy?: Prisma.ChangeEquipmentStatusOrderByWithRelationInput; + }): Promise<{ data: ChangeEquipmentStatus[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.changeEquipmentStatus.findMany({ skip, take, where, orderBy }), + this.prisma.changeEquipmentStatus.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ChangeEquipmentStatusWhereUniqueInput): Promise { + return this.prisma.changeEquipmentStatus.findUnique({ where }); + } + + async create(data: Prisma.ChangeEquipmentStatusCreateInput): Promise { + return this.prisma.changeEquipmentStatus.create({ data }); + } + + async update(params: { + where: Prisma.ChangeEquipmentStatusWhereUniqueInput; + data: Prisma.ChangeEquipmentStatusUpdateInput; + }): Promise { + return this.prisma.changeEquipmentStatus.update(params); + } + + async remove(where: Prisma.ChangeEquipmentStatusWhereUniqueInput): Promise { + return this.prisma.changeEquipmentStatus.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts b/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts new file mode 100644 index 0000000..72a7b9d --- /dev/null +++ b/backend/src/change-equipment-status/dto/create-change-equipment-status.dto.ts @@ -0,0 +1,40 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional } from 'class-validator'; +import { EquipmentStatus } from '@prisma/client'; + +export class CreateChangeEquipmentStatusDto { + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus', description: 'Новый статус' }) + @IsEnum(EquipmentStatus) + newStatus: EquipmentStatus; + + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ required: false, description: 'Комментарий' }) + @IsString() + @IsOptional() + comment?: string; + + @ApiProperty({ description: 'Дата изменения статуса' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ required: false, description: 'Ответственный' }) + @IsString() + @IsOptional() + responsible?: string; + + @ApiProperty({ required: false, description: 'Прикрепить документ (путь к файлу)' }) + @IsString() + @IsOptional() + document?: string; +} \ No newline at end of file diff --git a/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts b/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts new file mode 100644 index 0000000..662bc07 --- /dev/null +++ b/backend/src/change-equipment-status/dto/update-change-equipment-status.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateChangeEquipmentStatusDto } from './create-change-equipment-status.dto'; + +export class UpdateChangeEquipmentStatusDto extends PartialType(CreateChangeEquipmentStatusDto) {} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.controller.ts b/backend/src/confirmation-document/confirmation-document.controller.ts new file mode 100644 index 0000000..33ca159 --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { ConfirmationDocumentService } from './confirmation-document.service'; +import { CreateConfirmationDocumentDto } from './dto/create-confirmation-document.dto'; +import { UpdateConfirmationDocumentDto } from './dto/update-confirmation-document.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('confirmation-document') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('confirmation-document') +export class ConfirmationDocumentController { + constructor(private readonly confirmationDocumentService: ConfirmationDocumentService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.confirmationDocumentService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.confirmationDocumentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConfirmationDocumentDto) { + return this.confirmationDocumentService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateConfirmationDocumentDto) { + return this.confirmationDocumentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.confirmationDocumentService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.module.ts b/backend/src/confirmation-document/confirmation-document.module.ts new file mode 100644 index 0000000..e594c3d --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ConfirmationDocumentService } from './confirmation-document.service'; +import { ConfirmationDocumentController } from './confirmation-document.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ConfirmationDocumentController], + providers: [ConfirmationDocumentService, PrismaService], +}) +export class ConfirmationDocumentModule {} \ No newline at end of file diff --git a/backend/src/confirmation-document/confirmation-document.service.ts b/backend/src/confirmation-document/confirmation-document.service.ts new file mode 100644 index 0000000..6d4029e --- /dev/null +++ b/backend/src/confirmation-document/confirmation-document.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ConfirmationDocument, Prisma } from '@prisma/client'; + +@Injectable() +export class ConfirmationDocumentService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ConfirmationDocumentWhereInput; + orderBy?: Prisma.ConfirmationDocumentOrderByWithRelationInput; + }): Promise<{ data: ConfirmationDocument[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.confirmationDocument.findMany({ skip, take, where, orderBy }), + this.prisma.confirmationDocument.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ConfirmationDocumentWhereUniqueInput): Promise { + return this.prisma.confirmationDocument.findUnique({ where }); + } + + async create(data: Prisma.ConfirmationDocumentCreateInput): Promise { + return this.prisma.confirmationDocument.create({ data }); + } + + async update(params: { + where: Prisma.ConfirmationDocumentWhereUniqueInput; + data: Prisma.ConfirmationDocumentUpdateInput; + }): Promise { + return this.prisma.confirmationDocument.update(params); + } + + async remove(where: Prisma.ConfirmationDocumentWhereUniqueInput): Promise { + return this.prisma.confirmationDocument.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts b/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts new file mode 100644 index 0000000..44934ea --- /dev/null +++ b/backend/src/confirmation-document/dto/create-confirmation-document.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsBoolean } from 'class-validator'; + +export class CreateConfirmationDocumentDto { + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ description: 'Дата согласования' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ required: false, description: 'Код руководителя' }) + @IsString() + @IsOptional() + managerCode?: string; + + @ApiProperty({ description: 'Идентификатор заявки' }) + @IsString() + @IsNotEmpty() + orderId: string; + + @ApiProperty({ required: false, description: 'Согласовано/Не согласовано' }) + @IsBoolean() + @IsOptional() + confirmed?: boolean; +} \ No newline at end of file diff --git a/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts b/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts new file mode 100644 index 0000000..0e9a805 --- /dev/null +++ b/backend/src/confirmation-document/dto/update-confirmation-document.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateConfirmationDocumentDto } from './create-confirmation-document.dto'; + +export class UpdateConfirmationDocumentDto extends PartialType(CreateConfirmationDocumentDto) {} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.controller.ts b/backend/src/consumption-registration/consumption-registration.controller.ts new file mode 100644 index 0000000..fdf095c --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { ConsumptionRegistrationService } from './consumption-registration.service'; +import { CreateConsumptionRegistrationDto } from './dto/create-consumption-registration.dto'; +import { UpdateConsumptionRegistrationDto } from './dto/update-consumption-registration.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('consumption-registration') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('consumption-registration') +export class ConsumptionRegistrationController { + constructor(private readonly consumptionRegistrationService: ConsumptionRegistrationService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.consumptionRegistrationService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.consumptionRegistrationService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateConsumptionRegistrationDto) { + return this.consumptionRegistrationService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.consumptionRegistrationService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.module.ts b/backend/src/consumption-registration/consumption-registration.module.ts new file mode 100644 index 0000000..f2d1d67 --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ConsumptionRegistrationService } from './consumption-registration.service'; +import { ConsumptionRegistrationController } from './consumption-registration.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [ConsumptionRegistrationController], + providers: [ConsumptionRegistrationService, PrismaService], +}) +export class ConsumptionRegistrationModule {} \ No newline at end of file diff --git a/backend/src/consumption-registration/consumption-registration.service.ts b/backend/src/consumption-registration/consumption-registration.service.ts new file mode 100644 index 0000000..f54fa7d --- /dev/null +++ b/backend/src/consumption-registration/consumption-registration.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { ConsumptionRegistration, Prisma } from '@prisma/client'; + +@Injectable() +export class ConsumptionRegistrationService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.ConsumptionRegistrationWhereInput; + orderBy?: Prisma.ConsumptionRegistrationOrderByWithRelationInput; + }): Promise<{ data: ConsumptionRegistration[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.consumptionRegistration.findMany({ skip, take, where, orderBy }), + this.prisma.consumptionRegistration.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.ConsumptionRegistrationWhereUniqueInput): Promise { + return this.prisma.consumptionRegistration.findUnique({ where }); + } + + async create(data: Prisma.ConsumptionRegistrationCreateInput): Promise { + return this.prisma.consumptionRegistration.create({ data }); + } + + async update(params: { + where: Prisma.ConsumptionRegistrationWhereUniqueInput; + data: Prisma.ConsumptionRegistrationUpdateInput; + }): Promise { + return this.prisma.consumptionRegistration.update(params); + } + + async remove(where: Prisma.ConsumptionRegistrationWhereUniqueInput): Promise { + return this.prisma.consumptionRegistration.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts b/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts new file mode 100644 index 0000000..bea5215 --- /dev/null +++ b/backend/src/consumption-registration/dto/create-consumption-registration.dto.ts @@ -0,0 +1,32 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsISO8601, IsOptional, IsNumber } from 'class-validator'; + +export class CreateConsumptionRegistrationDto { + @ApiProperty({ required: false, description: 'Номер' }) + @IsString() + @IsOptional() + number?: string; + + @ApiProperty({ description: 'Дата регистрации' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ required: false, description: 'Наработка' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + totalEngineHours?: number; + + @ApiProperty({ required: false, description: 'Расход топлива' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + fuelConsumption?: number; +} \ No newline at end of file diff --git a/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts b/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts new file mode 100644 index 0000000..e03517a --- /dev/null +++ b/backend/src/consumption-registration/dto/update-consumption-registration.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateConsumptionRegistrationDto } from './create-consumption-registration.dto'; + +export class UpdateConsumptionRegistrationDto extends PartialType(CreateConsumptionRegistrationDto) {} \ No newline at end of file diff --git a/backend/src/employee/dto/create-employee.dto.ts b/backend/src/employee/dto/create-employee.dto.ts new file mode 100644 index 0000000..bf6682c --- /dev/null +++ b/backend/src/employee/dto/create-employee.dto.ts @@ -0,0 +1,42 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { Role } from '@prisma/client'; + +export class CreateEmployeeDto { + @ApiProperty({ description: 'Номер сотрудника (Табельный номер)' }) + @IsString() + @IsNotEmpty() + code: string; + + @ApiProperty({ description: 'ФИО сотрудника' }) + @IsString() + @IsNotEmpty() + fullName: string; + + @ApiProperty({ enum: Role, enumName: 'Role', description: 'Роль сотрудника' }) + @IsEnum(Role) + role: Role; + + @ApiProperty({ description: 'Должность сотрудника' }) + @IsString() + @IsNotEmpty() + position: string; + + @ApiProperty({ required: false, description: 'Код руководителя' }) + @IsString() + @IsOptional() + bossId?: string; + + @ApiProperty({ required: false, description: 'Стоимость часа работы сотрудника' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false, description: 'Номер телефона' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + phoneNumber?: number; +} \ No newline at end of file diff --git a/backend/src/employee/dto/update-employee.dto.ts b/backend/src/employee/dto/update-employee.dto.ts new file mode 100644 index 0000000..7180917 --- /dev/null +++ b/backend/src/employee/dto/update-employee.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateEmployeeDto } from './create-employee.dto'; + +export class UpdateEmployeeDto extends PartialType(CreateEmployeeDto) {} \ No newline at end of file diff --git a/backend/src/employee/employee.controller.ts b/backend/src/employee/employee.controller.ts new file mode 100644 index 0000000..5fe3d52 --- /dev/null +++ b/backend/src/employee/employee.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { EmployeeService } from './employee.service'; +import { CreateEmployeeDto } from './dto/create-employee.dto'; +import { UpdateEmployeeDto } from './dto/update-employee.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('employee') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('employee') +export class EmployeeController { + constructor(private readonly employeeService: EmployeeService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.employeeService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':code') + findOne(@Param('code') code: string) { + return this.employeeService.findOne({ code }); + } + + @Post() + create(@Body() dto: CreateEmployeeDto) { + return this.employeeService.create(dto); + } + + @Patch(':code') + update(@Param('code') code: string, @Body() dto: UpdateEmployeeDto) { + return this.employeeService.update({ where: { code }, data: dto }); + } + + @Delete(':code') + remove(@Param('code') code: string) { + return this.employeeService.remove({ code }); + } +} \ No newline at end of file diff --git a/backend/src/employee/employee.module.ts b/backend/src/employee/employee.module.ts new file mode 100644 index 0000000..d5b87d0 --- /dev/null +++ b/backend/src/employee/employee.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { EmployeeService } from './employee.service'; +import { EmployeeController } from './employee.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [EmployeeController], + providers: [EmployeeService, PrismaService], +}) +export class EmployeeModule {} \ No newline at end of file diff --git a/backend/src/employee/employee.service.ts b/backend/src/employee/employee.service.ts new file mode 100644 index 0000000..59b71e3 --- /dev/null +++ b/backend/src/employee/employee.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Employee, Prisma } from '@prisma/client'; + +@Injectable() +export class EmployeeService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.EmployeeWhereInput; + orderBy?: Prisma.EmployeeOrderByWithRelationInput; + }): Promise<{ data: Employee[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.employee.findMany({ skip, take, where, orderBy }), + this.prisma.employee.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.EmployeeWhereUniqueInput): Promise { + return this.prisma.employee.findUnique({ where }); + } + + async create(data: Prisma.EmployeeCreateInput): Promise { + return this.prisma.employee.create({ data }); + } + + async update(params: { + where: Prisma.EmployeeWhereUniqueInput; + data: Prisma.EmployeeUpdateInput; + }): Promise { + return this.prisma.employee.update(params); + } + + async remove(where: Prisma.EmployeeWhereUniqueInput): Promise { + return this.prisma.employee.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/equipment/dto/create-equipment.dto.ts b/backend/src/equipment/dto/create-equipment.dto.ts new file mode 100644 index 0000000..28510d7 --- /dev/null +++ b/backend/src/equipment/dto/create-equipment.dto.ts @@ -0,0 +1,73 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsNumber } from 'class-validator'; +import { EquipmentType, EnumPeriodicityTO, EquipmentStatus } from '@prisma/client'; + +export class CreateEquipmentDto { + @ApiProperty({ description: 'Название оборудования' }) + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty({ description: 'Заводской (серийный) номер' }) + @IsString() + @IsNotEmpty() + serialNumber: string; + + @ApiProperty({ description: 'Инвентарный номер' }) + @IsString() + @IsNotEmpty() + inventoryNumber: string; + + @ApiProperty({ enum: EquipmentType, enumName: 'EquipmentType', description: 'Тип оборудования' }) + @IsEnum(EquipmentType) + equipmentType: EquipmentType; + + @ApiProperty({ required: false, description: 'Дата проверки' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + dateOfInspection?: Date; + + @ApiProperty({ enum: EnumPeriodicityTO, enumName: 'EnumPeriodicityTO', description: 'Периодичность ТО' }) + @IsEnum(EnumPeriodicityTO) + periodicityTO: EnumPeriodicityTO; + + @ApiProperty({ required: false, description: 'Место эксплуатации / скважина / куст' }) + @IsString() + @IsOptional() + location?: string; + + @ApiProperty({ enum: EquipmentStatus, enumName: 'EquipmentStatus', description: 'Текущий статус' }) + @IsEnum(EquipmentStatus) + status: EquipmentStatus; + + @ApiProperty({ required: false, description: 'Год изготовления' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + commissionedAt?: Date; + + @ApiProperty({ required: false, description: 'Общая наработка, моточасов' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + totalEngineHours?: number; + + @ApiProperty({ required: false, description: 'Наработка с последнего ремонта, моточасов' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + engineHoursSinceLastRepair?: number; + + @ApiProperty({ required: false, description: 'Дата последнего ремонта' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + lastRepairAt?: Date; + + @ApiProperty({ required: false, description: 'Примечания' }) + @IsString() + @IsOptional() + notes?: string; +} \ No newline at end of file diff --git a/backend/src/equipment/dto/update-equipment.dto.ts b/backend/src/equipment/dto/update-equipment.dto.ts new file mode 100644 index 0000000..b6c9a4b --- /dev/null +++ b/backend/src/equipment/dto/update-equipment.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateEquipmentDto } from './create-equipment.dto'; + +export class UpdateEquipmentDto extends PartialType(CreateEquipmentDto) {} \ No newline at end of file diff --git a/backend/src/equipment/equipment.controller.ts b/backend/src/equipment/equipment.controller.ts new file mode 100644 index 0000000..d8c2c2f --- /dev/null +++ b/backend/src/equipment/equipment.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { EquipmentService } from './equipment.service'; +import { CreateEquipmentDto } from './dto/create-equipment.dto'; +import { UpdateEquipmentDto } from './dto/update-equipment.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('equipment') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('equipment') +export class EquipmentController { + constructor(private readonly equipmentService: EquipmentService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.equipmentService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.equipmentService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateEquipmentDto) { + return this.equipmentService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateEquipmentDto) { + return this.equipmentService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.equipmentService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/equipment/equipment.module.ts b/backend/src/equipment/equipment.module.ts new file mode 100644 index 0000000..4b324f7 --- /dev/null +++ b/backend/src/equipment/equipment.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { EquipmentService } from './equipment.service'; +import { EquipmentController } from './equipment.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [EquipmentController], + providers: [EquipmentService, PrismaService], +}) +export class EquipmentModule {} \ No newline at end of file diff --git a/backend/src/equipment/equipment.service.ts b/backend/src/equipment/equipment.service.ts new file mode 100644 index 0000000..26098ec --- /dev/null +++ b/backend/src/equipment/equipment.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Equipment, Prisma } from '@prisma/client'; + +@Injectable() +export class EquipmentService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.EquipmentWhereInput; + orderBy?: Prisma.EquipmentOrderByWithRelationInput; + }): Promise<{ data: Equipment[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.equipment.findMany({ skip, take, where, orderBy }), + this.prisma.equipment.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.EquipmentWhereUniqueInput): Promise { + return this.prisma.equipment.findUnique({ where }); + } + + async create(data: Prisma.EquipmentCreateInput): Promise { + return this.prisma.equipment.create({ data }); + } + + async update(params: { + where: Prisma.EquipmentWhereUniqueInput; + data: Prisma.EquipmentUpdateInput; + }): Promise { + return this.prisma.equipment.update(params); + } + + async remove(where: Prisma.EquipmentWhereUniqueInput): Promise { + return this.prisma.equipment.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/part/dto/create-part.dto.ts b/backend/src/part/dto/create-part.dto.ts new file mode 100644 index 0000000..dd9fbc3 --- /dev/null +++ b/backend/src/part/dto/create-part.dto.ts @@ -0,0 +1,32 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsOptional, IsNumber } from 'class-validator'; +import { CategoryPart } from '@prisma/client'; + +export class CreatePartDto { + @ApiProperty({ description: 'Название' }) + @IsString() + @IsNotEmpty() + name: string; + + @ApiProperty({ enum: CategoryPart, enumName: 'CategoryPart', required: false, description: 'Категории' }) + @IsEnum(CategoryPart) + @IsOptional() + categories?: CategoryPart; + + @ApiProperty({ required: false, description: 'Стоимость ЗИП/ТМЦ' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + price?: number; + + @ApiProperty({ required: false, description: 'Описание ЗИП/ТМЦ' }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false, description: 'Серийный номер запасных частей / инструментов / расходников' }) + @IsString() + @IsOptional() + serialNumber?: string; +} \ No newline at end of file diff --git a/backend/src/part/dto/update-part.dto.ts b/backend/src/part/dto/update-part.dto.ts new file mode 100644 index 0000000..bba96fe --- /dev/null +++ b/backend/src/part/dto/update-part.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePartDto } from './create-part.dto'; + +export class UpdatePartDto extends PartialType(CreatePartDto) {} \ No newline at end of file diff --git a/backend/src/part/part.controller.ts b/backend/src/part/part.controller.ts new file mode 100644 index 0000000..e9ccfe5 --- /dev/null +++ b/backend/src/part/part.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { PartService } from './part.service'; +import { CreatePartDto } from './dto/create-part.dto'; +import { UpdatePartDto } from './dto/update-part.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('part') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('part') +export class PartController { + constructor(private readonly partService: PartService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.partService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.partService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreatePartDto) { + return this.partService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdatePartDto) { + return this.partService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.partService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/part/part.module.ts b/backend/src/part/part.module.ts new file mode 100644 index 0000000..94f417f --- /dev/null +++ b/backend/src/part/part.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PartService } from './part.service'; +import { PartController } from './part.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [PartController], + providers: [PartService, PrismaService], +}) +export class PartModule {} \ No newline at end of file diff --git a/backend/src/part/part.service.ts b/backend/src/part/part.service.ts new file mode 100644 index 0000000..7c08f11 --- /dev/null +++ b/backend/src/part/part.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { Part, Prisma } from '@prisma/client'; + +@Injectable() +export class PartService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.PartWhereInput; + orderBy?: Prisma.PartOrderByWithRelationInput; + }): Promise<{ data: Part[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.part.findMany({ skip, take, where, orderBy }), + this.prisma.part.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.PartWhereUniqueInput): Promise { + return this.prisma.part.findUnique({ where }); + } + + async create(data: Prisma.PartCreateInput): Promise { + return this.prisma.part.create({ data }); + } + + async update(params: { + where: Prisma.PartWhereUniqueInput; + data: Prisma.PartUpdateInput; + }): Promise { + return this.prisma.part.update(params); + } + + async remove(where: Prisma.PartWhereUniqueInput): Promise { + return this.prisma.part.delete({ where }); + } +} \ No newline at end of file diff --git a/backend/src/repair-order/dto/create-repair-order.dto.ts b/backend/src/repair-order/dto/create-repair-order.dto.ts new file mode 100644 index 0000000..be2cac7 --- /dev/null +++ b/backend/src/repair-order/dto/create-repair-order.dto.ts @@ -0,0 +1,72 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsString, IsNotEmpty, IsEnum, IsISO8601, IsOptional, IsBoolean, IsNumber } from 'class-validator'; +import { RepairKind, RepairOrderStatus } from '@prisma/client'; + +export class CreateRepairOrderDto { + @ApiProperty({ description: 'Номер заявки' }) + @IsString() + @IsNotEmpty() + number: string; + + @ApiProperty({ description: 'Дата заявки' }) + @IsISO8601() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Идентификатор оборудования' }) + @IsString() + @IsNotEmpty() + equipmentId: string; + + @ApiProperty({ enum: RepairKind, enumName: 'RepairKind', description: 'Вид ремонта' }) + @IsEnum(RepairKind) + repairKind: RepairKind; + + @ApiProperty({ enum: RepairOrderStatus, enumName: 'RepairOrderStatus', description: 'Статус заявки' }) + @IsEnum(RepairOrderStatus) + status: RepairOrderStatus; + + @ApiProperty({ description: 'Плановая дата начала' }) + @IsISO8601() + @Type(() => Date) + plannedAt: Date; + + @ApiProperty({ required: false, description: 'Фактическая дата начала' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + startedAt?: Date; + + @ApiProperty({ required: false, description: 'Фактическая дата завершения' }) + @IsISO8601() + @IsOptional() + @Type(() => Date) + completedAt?: Date; + + @ApiProperty({ required: false, description: 'Подрядная организация (если внешний ремонт)' }) + @IsString() + @IsOptional() + contractor?: string; + + @ApiProperty({ required: false, description: 'Наработка на момент ремонта, моточасов' }) + @IsNumber() + @IsOptional() + @Type(() => Number) + engineHoursAtRepair?: number; + + @ApiProperty({ required: false, description: 'Описание работ / дефекта' }) + @IsString() + @IsOptional() + description?: string; + + @ApiProperty({ required: false, description: 'Примечания' }) + @IsString() + @IsOptional() + notes?: string; + + @ApiProperty({ required: false, description: 'Согласовано/Не согласовано' }) + @IsBoolean() + @IsOptional() + confirmed?: boolean; +} \ No newline at end of file diff --git a/backend/src/repair-order/dto/update-repair-order.dto.ts b/backend/src/repair-order/dto/update-repair-order.dto.ts new file mode 100644 index 0000000..dc04866 --- /dev/null +++ b/backend/src/repair-order/dto/update-repair-order.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateRepairOrderDto } from './create-repair-order.dto'; + +export class UpdateRepairOrderDto extends PartialType(CreateRepairOrderDto) {} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.controller.ts b/backend/src/repair-order/repair-order.controller.ts new file mode 100644 index 0000000..4864dfb --- /dev/null +++ b/backend/src/repair-order/repair-order.controller.ts @@ -0,0 +1,58 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common'; +import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger'; +import { RepairOrderService } from './repair-order.service'; +import { CreateRepairOrderDto } from './dto/create-repair-order.dto'; +import { UpdateRepairOrderDto } from './dto/update-repair-order.dto'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; + +const parseJson = (value?: string): T | undefined => { + if (!value) return undefined; + try { return JSON.parse(value) as T; } catch { return undefined; } +}; + +@ApiTags('repair-order') +@ApiBearerAuth() +@UseGuards(JwtAuthGuard) +@Controller('repair-order') +export class RepairOrderController { + constructor(private readonly repairOrderService: RepairOrderService) {} + + @Get() + @ApiQuery({ name: 'skip', required: false, type: String }) + @ApiQuery({ name: 'take', required: false, type: String }) + @ApiQuery({ name: 'orderBy', required: false, type: String }) + @ApiQuery({ name: 'where', required: false, type: String }) + findAll( + @Query('skip') skip?: string, + @Query('take') take?: string, + @Query('orderBy') orderBy?: string, + @Query('where') where?: string, + ) { + return this.repairOrderService.findAll({ + skip: skip ? Number(skip) : 0, + take: take ? Number(take) : 25, + orderBy: parseJson(orderBy), + where: parseJson(where), + }); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.repairOrderService.findOne({ id }); + } + + @Post() + create(@Body() dto: CreateRepairOrderDto) { + return this.repairOrderService.create(dto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() dto: UpdateRepairOrderDto) { + return this.repairOrderService.update({ where: { id }, data: dto }); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.repairOrderService.remove({ id }); + } +} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.module.ts b/backend/src/repair-order/repair-order.module.ts new file mode 100644 index 0000000..a30fd57 --- /dev/null +++ b/backend/src/repair-order/repair-order.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { RepairOrderService } from './repair-order.service'; +import { RepairOrderController } from './repair-order.controller'; +import { PrismaService } from '../prisma/prisma.service'; + +@Module({ + controllers: [RepairOrderController], + providers: [RepairOrderService, PrismaService], +}) +export class RepairOrderModule {} \ No newline at end of file diff --git a/backend/src/repair-order/repair-order.service.ts b/backend/src/repair-order/repair-order.service.ts new file mode 100644 index 0000000..493d9ac --- /dev/null +++ b/backend/src/repair-order/repair-order.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { RepairOrder, Prisma } from '@prisma/client'; + +@Injectable() +export class RepairOrderService { + constructor(private prisma: PrismaService) {} + + async findAll(params: { + skip?: number; + take?: number; + where?: Prisma.RepairOrderWhereInput; + orderBy?: Prisma.RepairOrderOrderByWithRelationInput; + }): Promise<{ data: RepairOrder[]; total: number }> { + const { skip, take, where, orderBy } = params; + const [data, total] = await this.prisma.$transaction([ + this.prisma.repairOrder.findMany({ skip, take, where, orderBy }), + this.prisma.repairOrder.count({ where }), + ]); + return { data, total }; + } + + async findOne(where: Prisma.RepairOrderWhereUniqueInput): Promise { + return this.prisma.repairOrder.findUnique({ where }); + } + + async create(data: Prisma.RepairOrderCreateInput): Promise { + return this.prisma.repairOrder.create({ data }); + } + + async update(params: { + where: Prisma.RepairOrderWhereUniqueInput; + data: Prisma.RepairOrderUpdateInput; + }): Promise { + return this.prisma.repairOrder.update(params); + } + + async remove(where: Prisma.RepairOrderWhereUniqueInput): Promise { + return this.prisma.repairOrder.delete({ where }); + } +} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx new file mode 100644 index 0000000..a4f2ce4 --- /dev/null +++ b/frontend/src/App.tsx @@ -0,0 +1,90 @@ +import { Admin, Resource } from 'react-admin'; +import { dataProvider } from './dataProvider'; +import { authProvider } from './authProvider'; + +// Equipment resources +import { EquipmentList, EquipmentCreate, EquipmentEdit, EquipmentShow } from './resources/equipment'; + +// Employee resources +import { EmployeeList, EmployeeCreate, EmployeeEdit, EmployeeShow } from './resources/employee'; + +// Part resources +import { PartList, PartCreate, PartEdit, PartShow } from './resources/part'; + +// CategoryResource resources +import { CategoryResourceList, CategoryResourceCreate, CategoryResourceEdit, CategoryResourceShow } from './resources/category-resource'; + +// RepairOrder resources +import { RepairOrderList, RepairOrderCreate, RepairOrderEdit, RepairOrderShow } from './resources/repair-order'; + +// ChangeEquipmentStatus resources +import { ChangeEquipmentStatusList, ChangeEquipmentStatusCreate, ChangeEquipmentStatusEdit, ChangeEquipmentStatusShow } from './resources/change-equipment-status'; + +// ConfirmationDocument resources +import { ConfirmationDocumentList, ConfirmationDocumentCreate, ConfirmationDocumentEdit, ConfirmationDocumentShow } from './resources/confirmation-document'; + +// ConsumptionRegistration resources +import { ConsumptionRegistrationList, ConsumptionRegistrationCreate, ConsumptionRegistrationEdit, ConsumptionRegistrationShow } from './resources/consumption-registration'; + +const App = () => ( + + + + + + + + + + +); + +export default App; \ No newline at end of file diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx new file mode 100644 index 0000000..2272d58 --- /dev/null +++ b/frontend/src/main.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { initKeycloak } from './authProvider'; +import App from './App'; + +const renderApp = async () => { + try { + await initKeycloak(); + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + ); + } catch (error) { + console.error('Failed to initialize Keycloak:', error); + } +}; + +renderApp(); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceCreate.tsx b/frontend/src/resources/category-resource/CategoryResourceCreate.tsx new file mode 100644 index 0000000..a00f591 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceCreate.tsx @@ -0,0 +1,14 @@ +import { Create, SimpleForm, ReferenceInput, SelectInput } from 'react-admin'; + +export const CategoryResourceCreate = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceEdit.tsx b/frontend/src/resources/category-resource/CategoryResourceEdit.tsx new file mode 100644 index 0000000..e751754 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceEdit.tsx @@ -0,0 +1,14 @@ +import { Edit, SimpleForm, ReferenceInput, SelectInput } from 'react-admin'; + +export const CategoryResourceEdit = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceList.tsx b/frontend/src/resources/category-resource/CategoryResourceList.tsx new file mode 100644 index 0000000..028e64a --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceList.tsx @@ -0,0 +1,12 @@ +import { List, DataTable, TextField, ReferenceField, EditButton } from 'react-admin'; + +export const CategoryResourceList = () => ( + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/CategoryResourceShow.tsx b/frontend/src/resources/category-resource/CategoryResourceShow.tsx new file mode 100644 index 0000000..52282d9 --- /dev/null +++ b/frontend/src/resources/category-resource/CategoryResourceShow.tsx @@ -0,0 +1,15 @@ +import { Show, SimpleShowLayout, TextField, ReferenceField } from 'react-admin'; + +export const CategoryResourceShow = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/category-resource/index.ts b/frontend/src/resources/category-resource/index.ts new file mode 100644 index 0000000..d195feb --- /dev/null +++ b/frontend/src/resources/category-resource/index.ts @@ -0,0 +1,4 @@ +export { CategoryResourceList } from './CategoryResourceList'; +export { CategoryResourceCreate } from './CategoryResourceCreate'; +export { CategoryResourceEdit } from './CategoryResourceEdit'; +export { CategoryResourceShow } from './CategoryResourceShow'; \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx new file mode 100644 index 0000000..c90ea0d --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusCreate.tsx @@ -0,0 +1,24 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const equipmentStatusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +export const ChangeEquipmentStatusCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx new file mode 100644 index 0000000..b55c450 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusEdit.tsx @@ -0,0 +1,25 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, ReferenceInput } from 'react-admin'; + +const equipmentStatusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +export const ChangeEquipmentStatusEdit = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx new file mode 100644 index 0000000..6199b32 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusList.tsx @@ -0,0 +1,17 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +export const ChangeEquipmentStatusList = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx new file mode 100644 index 0000000..0e6ff6a --- /dev/null +++ b/frontend/src/resources/change-equipment-status/ChangeEquipmentStatusShow.tsx @@ -0,0 +1,20 @@ +import { Show, SimpleShowLayout, TextField, DateField, ReferenceField } from 'react-admin'; + +export const ChangeEquipmentStatusShow = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/change-equipment-status/index.ts b/frontend/src/resources/change-equipment-status/index.ts new file mode 100644 index 0000000..1960ad0 --- /dev/null +++ b/frontend/src/resources/change-equipment-status/index.ts @@ -0,0 +1,4 @@ +export { ChangeEquipmentStatusList } from './ChangeEquipmentStatusList'; +export { ChangeEquipmentStatusCreate } from './ChangeEquipmentStatusCreate'; +export { ChangeEquipmentStatusEdit } from './ChangeEquipmentStatusEdit'; +export { ChangeEquipmentStatusShow } from './ChangeEquipmentStatusShow'; \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx new file mode 100644 index 0000000..eac28c5 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentCreate.tsx @@ -0,0 +1,17 @@ +import { Create, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConfirmationDocumentCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx new file mode 100644 index 0000000..ecc41bf --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentEdit.tsx @@ -0,0 +1,18 @@ +import { Edit, SimpleForm, TextInput, DateInput, BooleanInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConfirmationDocumentEdit = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx new file mode 100644 index 0000000..ccd1398 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, DateField, BooleanField, EditButton } from 'react-admin'; + +export const ConfirmationDocumentList = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx b/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx new file mode 100644 index 0000000..75fd471 --- /dev/null +++ b/frontend/src/resources/confirmation-document/ConfirmationDocumentShow.tsx @@ -0,0 +1,20 @@ +import { Show, SimpleShowLayout, TextField, DateField, BooleanField, ReferenceField } from 'react-admin'; + +export const ConfirmationDocumentShow = () => ( + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/confirmation-document/index.ts b/frontend/src/resources/confirmation-document/index.ts new file mode 100644 index 0000000..8e3f843 --- /dev/null +++ b/frontend/src/resources/confirmation-document/index.ts @@ -0,0 +1,4 @@ +export { ConfirmationDocumentList } from './ConfirmationDocumentList'; +export { ConfirmationDocumentCreate } from './ConfirmationDocumentCreate'; +export { ConfirmationDocumentEdit } from './ConfirmationDocumentEdit'; +export { ConfirmationDocumentShow } from './ConfirmationDocumentShow'; \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx new file mode 100644 index 0000000..7dbbaac --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationCreate.tsx @@ -0,0 +1,15 @@ +import { Create, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConsumptionRegistrationCreate = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx new file mode 100644 index 0000000..35b6bbb --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationEdit.tsx @@ -0,0 +1,16 @@ +import { Edit, SimpleForm, TextInput, DateInput, NumberInput, ReferenceInput, SelectInput } from 'react-admin'; + +export const ConsumptionRegistrationEdit = () => ( + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx new file mode 100644 index 0000000..0561c50 --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +export const ConsumptionRegistrationList = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx b/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx new file mode 100644 index 0000000..43512fc --- /dev/null +++ b/frontend/src/resources/consumption-registration/ConsumptionRegistrationShow.tsx @@ -0,0 +1,18 @@ +import { Show, SimpleShowLayout, TextField, DateField, ReferenceField } from 'react-admin'; + +export const ConsumptionRegistrationShow = () => ( + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/consumption-registration/index.ts b/frontend/src/resources/consumption-registration/index.ts new file mode 100644 index 0000000..f2d3906 --- /dev/null +++ b/frontend/src/resources/consumption-registration/index.ts @@ -0,0 +1,4 @@ +export { ConsumptionRegistrationList } from './ConsumptionRegistrationList'; +export { ConsumptionRegistrationCreate } from './ConsumptionRegistrationCreate'; +export { ConsumptionRegistrationEdit } from './ConsumptionRegistrationEdit'; +export { ConsumptionRegistrationShow } from './ConsumptionRegistrationShow'; \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeCreate.tsx b/frontend/src/resources/employee/EmployeeCreate.tsx new file mode 100644 index 0000000..3d9e904 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeCreate.tsx @@ -0,0 +1,23 @@ +import { Create, SimpleForm, TextInput, NumberInput, SelectInput, ReferenceInput } from 'react-admin'; + +const roleChoices = [ + { id: 'Исполнитель', name: 'Исполнитель' }, + { id: 'Подписант', name: 'Подписант' }, + { id: 'Пользователь', name: 'Пользователь' }, +]; + +export const EmployeeCreate = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeEdit.tsx b/frontend/src/resources/employee/EmployeeEdit.tsx new file mode 100644 index 0000000..3ea4c35 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeEdit.tsx @@ -0,0 +1,23 @@ +import { Edit, SimpleForm, TextInput, NumberInput, SelectInput, ReferenceInput } from 'react-admin'; + +const roleChoices = [ + { id: 'Исполнитель', name: 'Исполнитель' }, + { id: 'Подписант', name: 'Подписант' }, + { id: 'Пользователь', name: 'Пользователь' }, +]; + +export const EmployeeEdit = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeList.tsx b/frontend/src/resources/employee/EmployeeList.tsx new file mode 100644 index 0000000..651c7ba --- /dev/null +++ b/frontend/src/resources/employee/EmployeeList.tsx @@ -0,0 +1,16 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; + +export const EmployeeList = () => ( + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/EmployeeShow.tsx b/frontend/src/resources/employee/EmployeeShow.tsx new file mode 100644 index 0000000..d4a06f6 --- /dev/null +++ b/frontend/src/resources/employee/EmployeeShow.tsx @@ -0,0 +1,17 @@ +import { Show, SimpleShowLayout, TextField, NumberField, ReferenceField } from 'react-admin'; + +export const EmployeeShow = () => ( + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/employee/index.ts b/frontend/src/resources/employee/index.ts new file mode 100644 index 0000000..e93c622 --- /dev/null +++ b/frontend/src/resources/employee/index.ts @@ -0,0 +1,4 @@ +export { EmployeeList } from './EmployeeList'; +export { EmployeeCreate } from './EmployeeCreate'; +export { EmployeeEdit } from './EmployeeEdit'; +export { EmployeeShow } from './EmployeeShow'; \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentCreate.tsx b/frontend/src/resources/equipment/EquipmentCreate.tsx new file mode 100644 index 0000000..c8732e6 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentCreate.tsx @@ -0,0 +1,43 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, NumberInput } from 'react-admin'; + +const equipmentTypeChoices = [ + { id: 'Производственное', name: 'производственное' }, + { id: 'Энергетическое', name: 'энергетическое' }, + { id: 'Насосное', name: 'насосное' }, + { id: 'Компрессорное', name: 'компрессорное' }, +]; + +const periodicityTOChoices = [ + { id: 'Ежедневное', name: 'Ежедневное' }, + { id: 'Еженедельное', name: 'Еженедельное' }, + { id: 'Ежемесячное', name: 'Ежемесячное' }, + { id: 'Полугодовое', name: 'Полугодовое' }, + { id: 'Годовое', name: 'Годовое' }, +]; + +const equipmentStatusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +export const EquipmentCreate = () => ( + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentEdit.tsx b/frontend/src/resources/equipment/EquipmentEdit.tsx new file mode 100644 index 0000000..fce2683 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentEdit.tsx @@ -0,0 +1,44 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, NumberInput } from 'react-admin'; + +const equipmentTypeChoices = [ + { id: 'Производственное', name: 'производственное' }, + { id: 'Энергетическое', name: 'энергетическое' }, + { id: 'Насосное', name: 'насосное' }, + { id: 'Компрессорное', name: 'компрессорное' }, +]; + +const periodicityTOChoices = [ + { id: 'Ежедневное', name: 'Ежедневное' }, + { id: 'Еженедельное', name: 'Еженедельное' }, + { id: 'Ежемесячное', name: 'Ежемесячное' }, + { id: 'Полугодовое', name: 'Полугодовое' }, + { id: 'Годовое', name: 'Годовое' }, +]; + +const equipmentStatusChoices = [ + { id: 'Active', name: 'В эксплуатации' }, + { id: 'Repair', name: 'В ремонте' }, + { id: 'Reserve', name: 'В резерве' }, + { id: 'WriteOff', name: 'Списано' }, +]; + +export const EquipmentEdit = () => ( + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentList.tsx b/frontend/src/resources/equipment/EquipmentList.tsx new file mode 100644 index 0000000..30136cf --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentList.tsx @@ -0,0 +1,22 @@ +import { List, DataTable, TextField, DateField, EditButton } from 'react-admin'; + +export const EquipmentList = () => ( + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/EquipmentShow.tsx b/frontend/src/resources/equipment/EquipmentShow.tsx new file mode 100644 index 0000000..0df2379 --- /dev/null +++ b/frontend/src/resources/equipment/EquipmentShow.tsx @@ -0,0 +1,24 @@ +import { Show, SimpleShowLayout, TextField, DateField } from 'react-admin'; + +export const EquipmentShow = () => ( + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/equipment/index.ts b/frontend/src/resources/equipment/index.ts new file mode 100644 index 0000000..a98271f --- /dev/null +++ b/frontend/src/resources/equipment/index.ts @@ -0,0 +1,4 @@ +export { EquipmentList } from './EquipmentList'; +export { EquipmentCreate } from './EquipmentCreate'; +export { EquipmentEdit } from './EquipmentEdit'; +export { EquipmentShow } from './EquipmentShow'; \ No newline at end of file diff --git a/frontend/src/resources/part/PartCreate.tsx b/frontend/src/resources/part/PartCreate.tsx new file mode 100644 index 0000000..024e759 --- /dev/null +++ b/frontend/src/resources/part/PartCreate.tsx @@ -0,0 +1,20 @@ +import { Create, SimpleForm, TextInput, NumberInput, SelectInput } from 'react-admin'; + +const categoryPartChoices = [ + { id: 'Расходник', name: 'Расходник' }, + { id: 'Запчасть', name: 'Запчасть' }, + { id: 'Инструмент', name: 'Инструмент' }, + { id: 'Спецодежда', name: 'Спецодежда' }, +]; + +export const PartCreate = () => ( + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartEdit.tsx b/frontend/src/resources/part/PartEdit.tsx new file mode 100644 index 0000000..43e4215 --- /dev/null +++ b/frontend/src/resources/part/PartEdit.tsx @@ -0,0 +1,21 @@ +import { Edit, SimpleForm, TextInput, NumberInput, SelectInput } from 'react-admin'; + +const categoryPartChoices = [ + { id: 'Расходник', name: 'Расходник' }, + { id: 'Запчасть', name: 'Запчасть' }, + { id: 'Инструмент', name: 'Инструмент' }, + { id: 'Спецодежда', name: 'Спецодежда' }, +]; + +export const PartEdit = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartList.tsx b/frontend/src/resources/part/PartList.tsx new file mode 100644 index 0000000..424e668 --- /dev/null +++ b/frontend/src/resources/part/PartList.tsx @@ -0,0 +1,15 @@ +import { List, DataTable, TextField, NumberField, EditButton } from 'react-admin'; + +export const PartList = () => ( + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/PartShow.tsx b/frontend/src/resources/part/PartShow.tsx new file mode 100644 index 0000000..82c67a0 --- /dev/null +++ b/frontend/src/resources/part/PartShow.tsx @@ -0,0 +1,14 @@ +import { Show, SimpleShowLayout, TextField, NumberField } from 'react-admin'; + +export const PartShow = () => ( + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/part/index.ts b/frontend/src/resources/part/index.ts new file mode 100644 index 0000000..45ddc1c --- /dev/null +++ b/frontend/src/resources/part/index.ts @@ -0,0 +1,4 @@ +export { PartList } from './PartList'; +export { PartCreate } from './PartCreate'; +export { PartEdit } from './PartEdit'; +export { PartShow } from './PartShow'; \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderCreate.tsx b/frontend/src/resources/repair-order/RepairOrderCreate.tsx new file mode 100644 index 0000000..acbe6ce --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderCreate.tsx @@ -0,0 +1,40 @@ +import { Create, SimpleForm, TextInput, DateInput, SelectInput, BooleanInput, ReferenceInput, NumberInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +const repairOrderStatusChoices = [ + { id: 'Draft', name: 'Черновик' }, + { id: 'Approved', name: 'Утверждена' }, + { id: 'InWork', name: 'В работе' }, + { id: 'Done', name: 'Выполнена' }, + { id: 'Cancelled', name: 'Отменена' }, +]; + +export const RepairOrderCreate = () => ( + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderEdit.tsx b/frontend/src/resources/repair-order/RepairOrderEdit.tsx new file mode 100644 index 0000000..291efa1 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderEdit.tsx @@ -0,0 +1,41 @@ +import { Edit, SimpleForm, TextInput, DateInput, SelectInput, BooleanInput, ReferenceInput, NumberInput } from 'react-admin'; + +const repairKindChoices = [ + { id: 'TO', name: 'Техническое обслуживание' }, + { id: 'TR', name: 'Текущий ремонт' }, + { id: 'TRE', name: 'Текущий расширенный ремонт' }, + { id: 'KR', name: 'Капитальный ремонт' }, + { id: 'AR', name: 'Аварийный ремонт' }, + { id: 'MP', name: 'Метрологическая поверка' }, +]; + +const repairOrderStatusChoices = [ + { id: 'Draft', name: 'Черновик' }, + { id: 'Approved', name: 'Утверждена' }, + { id: 'InWork', name: 'В работе' }, + { id: 'Done', name: 'Выполнена' }, + { id: 'Cancelled', name: 'Отменена' }, +]; + +export const RepairOrderEdit = () => ( + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderList.tsx b/frontend/src/resources/repair-order/RepairOrderList.tsx new file mode 100644 index 0000000..1a131c8 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderList.tsx @@ -0,0 +1,21 @@ +import { List, DataTable, TextField, DateField, BooleanField, EditButton } from 'react-admin'; + +export const RepairOrderList = () => ( + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/RepairOrderShow.tsx b/frontend/src/resources/repair-order/RepairOrderShow.tsx new file mode 100644 index 0000000..3900e32 --- /dev/null +++ b/frontend/src/resources/repair-order/RepairOrderShow.tsx @@ -0,0 +1,26 @@ +import { Show, SimpleShowLayout, TextField, DateField, BooleanField, ReferenceField } from 'react-admin'; + +export const RepairOrderShow = () => ( + + + + + + + + + + + + + + + + + + + + + + +); \ No newline at end of file diff --git a/frontend/src/resources/repair-order/index.ts b/frontend/src/resources/repair-order/index.ts new file mode 100644 index 0000000..1d8fbda --- /dev/null +++ b/frontend/src/resources/repair-order/index.ts @@ -0,0 +1,4 @@ +export { RepairOrderList } from './RepairOrderList'; +export { RepairOrderCreate } from './RepairOrderCreate'; +export { RepairOrderEdit } from './RepairOrderEdit'; +export { RepairOrderShow } from './RepairOrderShow'; \ No newline at end of file