From 988559b1fcbb65f82d9cd325c46831b97fa66fa4 Mon Sep 17 00:00:00 2001 From: Donald Wu Date: Mon, 2 Jan 2023 17:39:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20assignIncident,=20?= =?UTF-8?q?updateIncidentStatus=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../incident/dto/assignIncidentStatus.dto.ts | 3 + .../incident/dto/updateIncidentStatus.dto.ts | 5 ++ apps/api/src/incident/incident.controller.ts | 56 ++++++++++++++++++- apps/api/src/incident/incident.repository.ts | 34 ++++++++++- apps/api/src/incident/incident.service.ts | 18 +++++- .../interface/assignIncident.interface.ts | 6 ++ .../updateIncidentStatus.interface.ts | 6 ++ .../src/components/dashboard/dashboard.tsx | 3 + .../incidentCardList/IncidentCardList.tsx | 5 +- apps/web/src/services/incidentService.ts | 42 +++++++++++++- 10 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 apps/api/src/incident/dto/assignIncidentStatus.dto.ts create mode 100644 apps/api/src/incident/dto/updateIncidentStatus.dto.ts create mode 100644 apps/api/src/incident/interface/assignIncident.interface.ts create mode 100644 apps/api/src/incident/interface/updateIncidentStatus.interface.ts diff --git a/apps/api/src/incident/dto/assignIncidentStatus.dto.ts b/apps/api/src/incident/dto/assignIncidentStatus.dto.ts new file mode 100644 index 0000000..8b46303 --- /dev/null +++ b/apps/api/src/incident/dto/assignIncidentStatus.dto.ts @@ -0,0 +1,3 @@ +export class AssignIncidentStatusDto { + assigneeId: string; +} diff --git a/apps/api/src/incident/dto/updateIncidentStatus.dto.ts b/apps/api/src/incident/dto/updateIncidentStatus.dto.ts new file mode 100644 index 0000000..a49e876 --- /dev/null +++ b/apps/api/src/incident/dto/updateIncidentStatus.dto.ts @@ -0,0 +1,5 @@ +import { Status } from '@prisma/client'; + +export class UpdateIncidentStatusDto { + status: Status; +} diff --git a/apps/api/src/incident/incident.controller.ts b/apps/api/src/incident/incident.controller.ts index 69878da..a4a89e3 100644 --- a/apps/api/src/incident/incident.controller.ts +++ b/apps/api/src/incident/incident.controller.ts @@ -3,16 +3,21 @@ import { Post, Body, Get, + Patch, Delete, Query, Param, } from '@nestjs/common'; import { CreateIncidentDto } from './dto/createIncident.dto'; +import { UpdateIncidentStatusDto } from './dto/updateIncidentStatus.dto'; +import { AssignIncidentStatusDto } from './dto/assignIncidentStatus.dto'; import { IncidentService } from './incident.service'; import { CreateIncidentRes } from './interface/createIncident.interface'; import { GetIncidentsRes } from './interface/getIncidents.interface'; import { GetIncidentByIdRes } from './interface/getIncidentById.interface'; import { DeleteIncidentByIdRes } from './interface/deleteIncidentById.interface'; +import { UpdateIncidentStatusRes } from './interface/updateIncidentStatus.interface'; +import { AssignIncidentRes } from './interface/assignIncident.interface'; import { UserRole } from '@prisma/client'; @Controller('incidents') @@ -53,7 +58,7 @@ export class IncidentController { @Query('userRole') userRole: UserRole, @Query('userId') userId: string, @Query('searchText') searchText?: string - ) { + ): Promise { let response: GetIncidentsRes; const incidents = await this.incidentService.getIncidents( @@ -72,7 +77,7 @@ export class IncidentController { } @Get('/:id') - async getIncidentById(@Param('id') id: string) { + async getIncidentById(@Param('id') id: string): Promise { let response: GetIncidentByIdRes; const incident = await this.incidentService.getIncidentById(id); @@ -86,8 +91,53 @@ export class IncidentController { return response; } + @Patch('/:id/assignIncident') + async assignIncident( + @Param('id') id: string, + @Body() assignIncidentStatusDto: AssignIncidentStatusDto + ): Promise { + let response: AssignIncidentRes; + + const assigneeId = assignIncidentStatusDto.assigneeId; + + const incident = await this.incidentService.assignIncident(id, assigneeId); + if (incident) { + response = { + message: 'update incident status', + incident: incident, + }; + } + + return response; + } + + @Patch('/:id/updateIncidentStatus') + async updateIncidentStatus( + @Param('id') id: string, + @Body() updateIncidentStatusDto: UpdateIncidentStatusDto + ): Promise { + let response: UpdateIncidentStatusRes; + + const status = updateIncidentStatusDto.status; + + const incident = await this.incidentService.updateIncidentStatus( + id, + status + ); + if (incident) { + response = { + message: 'update incident status', + incident: incident, + }; + } + + return response; + } + @Delete('/:id') - async deleteIncidentById(@Param('id') id: string) { + async deleteIncidentById( + @Param('id') id: string + ): Promise { let response: DeleteIncidentByIdRes; const incident = await this.incidentService.deleteIncidentById(id); diff --git a/apps/api/src/incident/incident.repository.ts b/apps/api/src/incident/incident.repository.ts index 0ed2e4b..859709a 100644 --- a/apps/api/src/incident/incident.repository.ts +++ b/apps/api/src/incident/incident.repository.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { Incident, IncidentType, UserRole } from '@prisma/client'; +import { Incident, IncidentType, UserRole, Status } from '@prisma/client'; import { PrismaService } from '../prisma.service'; @Injectable() @@ -102,6 +102,38 @@ export class IncidentRepository { return incident; } + async assignIncident(id: string, assigneeId: string) { + const incident = await this.prisma.incident.update({ + where: { + id: id, + }, + data: { + assignee_id: assigneeId, + }, + include: { + creator: true, + assignee: true, + }, + }); + return incident; + } + + async updateIncidentStatus(id: string, status: Status) { + const incident = await this.prisma.incident.update({ + where: { + id: id, + }, + data: { + status: status, + }, + include: { + creator: true, + assignee: true, + }, + }); + return incident; + } + async deleteIncidentById(id: string) { const incident = await this.prisma.incident.delete({ where: { diff --git a/apps/api/src/incident/incident.service.ts b/apps/api/src/incident/incident.service.ts index 498b146..16e4832 100644 --- a/apps/api/src/incident/incident.service.ts +++ b/apps/api/src/incident/incident.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { IncidentType, UserRole } from '@prisma/client'; +import { IncidentType, UserRole, Status } from '@prisma/client'; import { IncidentRepository } from './incident.repository'; @Injectable() @@ -37,6 +37,22 @@ export class IncidentService { return incident; } + async assignIncident(id: string, assigneeId: string) { + const incident = await this.incidentRepository.assignIncident( + id, + assigneeId + ); + return incident; + } + + async updateIncidentStatus(id: string, status: Status) { + const incident = await this.incidentRepository.updateIncidentStatus( + id, + status + ); + return incident; + } + async deleteIncidentById(id: string) { const incident = await this.incidentRepository.deleteIncidentById(id); return incident; diff --git a/apps/api/src/incident/interface/assignIncident.interface.ts b/apps/api/src/incident/interface/assignIncident.interface.ts new file mode 100644 index 0000000..229b6ef --- /dev/null +++ b/apps/api/src/incident/interface/assignIncident.interface.ts @@ -0,0 +1,6 @@ +import { Incident } from '@prisma/client'; + +export interface AssignIncidentRes { + message: string; + incident: Incident; +} diff --git a/apps/api/src/incident/interface/updateIncidentStatus.interface.ts b/apps/api/src/incident/interface/updateIncidentStatus.interface.ts new file mode 100644 index 0000000..cd6c7ba --- /dev/null +++ b/apps/api/src/incident/interface/updateIncidentStatus.interface.ts @@ -0,0 +1,6 @@ +import { Incident } from '@prisma/client'; + +export interface UpdateIncidentStatusRes { + message: string; + incident: Incident; +} diff --git a/apps/web/src/components/dashboard/dashboard.tsx b/apps/web/src/components/dashboard/dashboard.tsx index 7e14539..b3100c5 100644 --- a/apps/web/src/components/dashboard/dashboard.tsx +++ b/apps/web/src/components/dashboard/dashboard.tsx @@ -194,6 +194,9 @@ function Dashboard() { margin="normal" required fullWidth + multiline + rows={5} + maxRows={10} name="description" label="Description" type="text" diff --git a/apps/web/src/components/incidentCardList/IncidentCardList.tsx b/apps/web/src/components/incidentCardList/IncidentCardList.tsx index 1579c1e..169de20 100644 --- a/apps/web/src/components/incidentCardList/IncidentCardList.tsx +++ b/apps/web/src/components/incidentCardList/IncidentCardList.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import CardView from '../cardView/CardView'; -import { Incident } from '@prisma/client'; +import { Incident, UserRole } from '@prisma/client'; import * as userService from '../../services/userService'; interface Props { @@ -19,7 +19,8 @@ function IncidentCardList({ incidents, getIncidents }: Props) { const getNormalUsers = async () => { const token = localStorage.getItem('token'); - if (token) { + const userRole = localStorage.getItem('userRole'); + if (token && userRole && userRole === UserRole.ADMIN) { const response = await userService.getNormalUsers(token); console.log('response = ', response); diff --git a/apps/web/src/services/incidentService.ts b/apps/web/src/services/incidentService.ts index f215f79..441c672 100644 --- a/apps/web/src/services/incidentService.ts +++ b/apps/web/src/services/incidentService.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { UserRole, IncidentType } from '@prisma/client'; +import { UserRole, IncidentType, Status } from '@prisma/client'; import { getRootUrl } from '../helper/helper'; const rootUrl = getRootUrl(); @@ -58,6 +58,46 @@ export const getIncidentById = async (token: string, id: string) => { return response; }; +export const assignIncident = async ( + token: string, + id: string, + assigneeId: string +) => { + const data = { + assigneeId: assigneeId, + }; + const response = await axios.patch( + `${rootUrl}/incidents/${id}/assignIncident`, + data, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + return response; +}; + +export const updateIncidentStatus = async ( + token: string, + id: string, + status: Status +) => { + const data = { + status: status, + }; + const response = await axios.patch( + `${rootUrl}/incidents/${id}/updateIncidentStatus`, + data, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + return response; +}; + export const deleteIncidentById = async (token: string, id: string) => { const response = await axios.delete(`${rootUrl}/incidents/${id}`, { headers: {