Skip to content

Commit

Permalink
feat: add checklist to each task (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
hudy9x authored Apr 12, 2024
1 parent 98490b0 commit bda24a6
Show file tree
Hide file tree
Showing 31 changed files with 808 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/be-gateway/src/exceptions/BadRequestException.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ export default class BadRequestException extends Error {
status: number
constructor(message?: string) {
super(message || 'BAD_REQUEST')
this.status = 500
this.status = 400
}
}
4 changes: 3 additions & 1 deletion packages/be-gateway/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import TaskReorderController from './task/reorder.controller'
import { EventController } from './event/index.controller'
import { TestController } from './test'
import ProjectSetting from './project/setting.controller'
import TaskChecklistController from './task/checklist.controller'

const router = Router()

Expand All @@ -53,7 +54,8 @@ router.use(
OrganizationStorageController,
OrganizationMemberController,
SchedulerController,
TaskReorderController
TaskReorderController,
TaskChecklistController
])
)
// middlewares
Expand Down
40 changes: 40 additions & 0 deletions packages/be-gateway/src/routes/task/checklist.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { BaseController, UseMiddleware, Controller, Get, Post, Req, Delete, Put, Body, Param } from "../../core";
import { authMiddleware, beProjectMemberMiddleware } from "../../middlewares";
import { TaskChecklist } from "@prisma/client";
import TaskChecklistService from "../../services/task/checklist.service";

@Controller('/project/task/checklist')
@UseMiddleware([authMiddleware, beProjectMemberMiddleware])
export default class TaskChecklistController extends BaseController {
private checklistService: TaskChecklistService

constructor() {
super()
this.checklistService = new TaskChecklistService()
}
@Get('/:taskId')
async getChecklistByTaskId(@Param() params: { taskId: string }) {
console.log(1)
const { taskId } = params
const results = await this.checklistService.get(taskId)
return results
}

@Put('')
async updateChecklist(@Body() body: TaskChecklist) {
const ret = await this.checklistService.update(body)
return ret
}

@Post('')
async createChecklist(@Body() body: TaskChecklist) {
const result = await this.checklistService.create(body)
return result
}

@Delete('/:checklistId')
async deleteChecklist(@Param() params: { checklistId: string }) {
const result = await this.checklistService.delete(params.checklistId)
return result
}
}
8 changes: 8 additions & 0 deletions packages/be-gateway/src/routes/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ExpressRequest,
ExpressResponse,
Get,
Post,
Req,
Res
} from '../../core'
Expand All @@ -30,6 +31,13 @@ export class TestController extends BaseController {
this.taskQueue = getTaskQueueInstance()
}

@Post('/hanet-webhook')
async testHanetWebhook() {
console.log(this.req.url, this.req.method)
console.log('body:', this.req.body)
return 1
}

calculateSecondBetween2Date() {
const d1 = new Date()
const d2 = new Date(
Expand Down
122 changes: 122 additions & 0 deletions packages/be-gateway/src/services/task/checklist.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Task, TaskChecklist } from "@prisma/client"
import BadRequestException from "../../exceptions/BadRequestException"
import { TaskChecklistRepository, mdTaskGetOne, mdTaskUpdate } from "@shared/models"
import { CKEY, findNDelCaches } from "../../lib/redis"

export default class TaskChecklistService {
private checklistRepo: TaskChecklistRepository
constructor() {
this.checklistRepo = new TaskChecklistRepository()
}

async get(taskId: string) {
const results = await this.checklistRepo.getAllByTaskId(taskId)
return results
}

async delete(checklistId: string) {

if (!checklistId) {
throw new BadRequestException()
}

const result = await this.checklistRepo.deleteById(checklistId)
await this._updateTaskChecklistCounter(result.taskId)

console.log(result)

return result

}

async create(body: TaskChecklist) {
const { title, order, taskId } = body

const result = await this.checklistRepo.create({
title,
order: 1,
taskId,
done: false,
doneAt: null
})

await this._updateTaskChecklistCounter(taskId)

return result

}

async update(data: TaskChecklist) {
const { title, done, order, id } = data


if (!id) {
throw new BadRequestException()
}

const checklistData = await this.checklistRepo.getById(id)
let changed = false

if (title !== checklistData.title) {
checklistData.title = title
changed = true
}

if (done !== checklistData.done) {
checklistData.done = done
changed = true
}

if (order !== checklistData.order) {
checklistData.order = order

if (order) {
checklistData.doneAt = new Date()
}

changed = true
}

if (changed) {
const { id, ...restData } = checklistData
await this.checklistRepo.updateById(id, restData)
await this._updateTaskChecklistCounter(checklistData.taskId)
return 1
}

return 0

}

private async _updateTaskChecklistCounter(taskId) {
const promises = [mdTaskGetOne(taskId), this.checklistRepo.getAllByTaskId(taskId)]

const data = await Promise.all(promises)
const taskData = data[0] as Task
const checklist = data[1] as TaskChecklist[]


if (!checklist || !checklist.length) return

const [todo, done] = checklist.reduce((total, c) => {
if (c.done) {
total[1] += 1
} else {
total[0] += 1
}

return total
}, [0, 0])


taskData.checklistTodos = todo
taskData.checklistDone = done

await mdTaskUpdate(taskData)

const key = [CKEY.TASK_QUERY, taskData.projectId]
await findNDelCaches(key)

}

}
2 changes: 2 additions & 0 deletions packages/be-gateway/src/services/task/create.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export default class TaskCreateService {
plannedStartDate: dueDate || null,
plannedDueDate: dueDate || null,
assigneeIds,
checklistDone: 0,
checklistTodos: 0,
desc,
done,
fileIds: [],
Expand Down
3 changes: 3 additions & 0 deletions packages/shared-models/src/lib/_prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ export const Log = logtail

export const pmClient = new PrismaClient()
export const pmTrans = pmClient.$transaction

export const projectModel = pmClient.project
export const projectViewModel = pmClient.projectView
export const projectNotifyModel = pmClient.projectSettingNotification
export const taskStatusModel = pmClient.taskStatus
export const taskPointModel = pmClient.taskPoint
export const taskChecklistModel = pmClient.taskChecklist
export const tagModel = pmClient.tag
export const favModel = pmClient.favorites
export const taskModel = pmClient.task
Expand All @@ -28,3 +30,4 @@ export const fileStorageModel = pmClient.fileStorage
export const visionModel = pmClient.vision
export const activityModel = pmClient.activity
export const commentModel = pmClient.comment

1 change: 1 addition & 0 deletions packages/shared-models/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from './storage'
export * from './activity'
export * from './scheduler.repository'
export * from './comment.repository'
export * from './task.checklist.repository'
60 changes: 60 additions & 0 deletions packages/shared-models/src/lib/task.checklist.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { TaskChecklist } from "@prisma/client"
import { taskChecklistModel } from "./_prisma"

export class TaskChecklistRepository {
constructor(private model = taskChecklistModel) {

}

async getById(cid: string) {
return this.model.findFirst({
where: {
id: cid
}
})
}

async getAllByTaskId(taskId: string) {
return this.model.findMany({
where: {
taskId
},
orderBy: {
order: 'asc'
}

})
}

async create(data: Omit<TaskChecklist, 'id'>) {

return this.model.create({
data
})
}

async updateById(id: string, data: Partial<Omit<TaskChecklist, 'id'>>) {
return this.model.update({
where: {
id
},
data
})
}

async deleteById(id: string) {
return this.model.delete({
where: { id }
})
}




}






12 changes: 12 additions & 0 deletions packages/shared-models/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ model Task {
order Int
type TaskType?
checklistDone Int?
checklistTodos Int?
cover String?
plannedStartDate DateTime?
plannedDueDate DateTime?
Expand Down Expand Up @@ -189,6 +192,15 @@ model TaskStatus {
type StatusType @default(TODO)
}

model TaskChecklist {
id String @id @default(auto()) @map("_id") @db.ObjectId
taskId String @db.ObjectId
title String
order Int
done Boolean?
doneAt DateTime?
}

// Tag used for Projects and Tasks
model Tag {
id String @id @default(auto()) @map("_id") @db.ObjectId
Expand Down
2 changes: 1 addition & 1 deletion packages/shared-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import LoadingContainer from './components/Loading/LoadingContainer'
import TimelineContainer from './components/Timeline'
import DropdownMenuContainer from './components/Dropdown'
import TabContainer from './components/Tab'
import PopoverContainer from './components/Popover'
import PopoverContainer from './components/Controls/PopoverControl'
import SwitchContainer from './components/Switch'

export {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export const TaskUpdate = () => {
<>
<FileKitContainer fileIds={currentTask.fileIds}>
<TaskDetail
id={taskId || ''}
cover={currentTask.cover || ''}
defaultValue={currentTask}
onSubmit={v => handleSubmit(v)}
Expand Down
Loading

0 comments on commit bda24a6

Please sign in to comment.