Skip to content

Commit

Permalink
feat(task-sync): sync task as users do update/delete/create actions (#…
Browse files Browse the repository at this point in the history
…169)

* feat: sync task changes

* fix comments

---------

Co-authored-by: hudy@mac-air <[email protected]>
  • Loading branch information
huypl53 and hudy9x authored Apr 30, 2024
1 parent 6740890 commit 6d1585c
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 44 deletions.
15 changes: 15 additions & 0 deletions packages/be-gateway/src/jobs/task.pusher.job.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { pusherServer } from '../lib/pusher-server'

export default class TaskPusherJob {
async triggerUpdateEvent({
projectId,
uid
}: {
projectId: string
uid: string
}) {
pusherServer.trigger('team-collab', `projectTask:update-${projectId}`, {
triggerBy: uid
})
}
}
12 changes: 12 additions & 0 deletions packages/be-gateway/src/routes/task/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import { createModuleLog } from '../../lib/log'
import TaskCreateService from '../../services/task/create.service'
import TaskUpdateService from '../../services/task/update.service'
import TaskReminderJob from '../../jobs/reminder.job'
import TaskPusherJob from '../../jobs/task.pusher.job'

const taskPusherJob = new TaskPusherJob()

const logging = createModuleLog('ProjectTask')
// import { Log } from '../../lib/log'
Expand Down Expand Up @@ -337,6 +340,11 @@ router.delete('/project/task', async (req: AuthRequest, res) => {
}

await findNDelCaches(key)
taskPusherJob.triggerUpdateEvent({
projectId,
uid: req.authen.id
})

console.log('deleted task', id)
res.json({
status: 200,
Expand Down Expand Up @@ -367,6 +375,10 @@ router.put('/project/task-many', async (req: AuthRequest, res) => {
await mdTaskUpdateMany(ids, data)
await findNDelCaches(key)
logging.info('TaskUpdateMany - successfully')
taskPusherJob.triggerUpdateEvent({
projectId: data.projectId,
uid: userId
})

res.json({
result: 1
Expand Down
7 changes: 7 additions & 0 deletions packages/be-gateway/src/services/task/create.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ import { notifyToWebUsers } from '../../lib/buzzer'
import InternalErrorException from '../../exceptions/InternalErrorException'

import TaskReminderJob from '../../jobs/reminder.job'
import TaskPusherJob from '../../jobs/task.pusher.job'

export default class TaskCreateService {
activityService: ActivityService
taskReminderJob: TaskReminderJob
projectSettingRepo: ProjectSettingRepository
taskSyncJob: TaskPusherJob

constructor() {
this.activityService = new ActivityService()
this.projectSettingRepo = new ProjectSettingRepository()
this.taskReminderJob = new TaskReminderJob()
this.taskSyncJob = new TaskPusherJob()
}

async createNewTask({ uid, body }: { uid: string; body: Task }) {
Expand Down Expand Up @@ -94,6 +97,10 @@ export default class TaskCreateService {

this.notifyNewTaskToAssignee({ uid, task: result })

this.taskSyncJob.triggerUpdateEvent({
projectId,
uid
})
if (!done) {
this.createTaskReminder(result)
}
Expand Down
9 changes: 9 additions & 0 deletions packages/be-gateway/src/services/task/update.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ import InternalErrorException from '../../exceptions/InternalErrorException'
import { serviceGetStatusById } from '../status'
import { serviceGetProjectById } from '../project'
import TaskReminderJob from '../../jobs/reminder.job'
import TaskPusherJob from '../../jobs/task.pusher.job'

export default class TaskUpdateService {
activityService: ActivityService
projectSettingRepo: ProjectSettingRepository
taskReminderJob: TaskReminderJob
taskSyncJob: TaskPusherJob

constructor() {
this.activityService = new ActivityService()
this.projectSettingRepo = new ProjectSettingRepository()
this.taskReminderJob = new TaskReminderJob()
this.taskSyncJob = new TaskPusherJob()
}
async doUpdate({ userId, body }: { userId: string; body: Task }) {
const activityService = this.activityService
Expand Down Expand Up @@ -51,6 +55,11 @@ export default class TaskUpdateService {
userId
})

this.taskSyncJob.triggerUpdateEvent({
projectId: result.projectId,
uid: userId
})

await this._clearRelativeCaches({
assigneeIds: result.assigneeIds,
oldAssigneeId,
Expand Down
31 changes: 31 additions & 0 deletions packages/ui-app/app/_events/useEventSyncProjectTask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useEffect } from 'react'
import { usePusher } from './usePusher'
import { useUser } from '@goalie/nextjs'

import { useGetTaskHandler } from '@/features/ProjectContainer/useGetTask'

// @description
// it will be ran as an user create / delete / update a view
export const useEventSyncProjectTask = (projectId: string) => {
const { user } = useUser()
const { channelTeamCollab } = usePusher()
const { fetchNCache } = useGetTaskHandler()

useEffect(() => {
if (!user || !user.id) return

const eventUpdateName = `projectTask:update-${projectId}`

console.log('bind event:', eventUpdateName)
channelTeamCollab &&
channelTeamCollab.bind(eventUpdateName, (data: { triggerBy: string }) => {
if (data.triggerBy === user.id) return

fetchNCache()
})

return () => {
channelTeamCollab && channelTeamCollab.unbind(eventUpdateName)
}
}, [channelTeamCollab, user])
}
2 changes: 2 additions & 0 deletions packages/ui-app/app/_features/ProjectContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useEventSyncProjectMember } from '@/events/useEventSyncProjectMember'
import { useEventSyncProjectView } from '@/events/useEventSyncProjectView'
import { useEventSyncProjectStatus } from '@/events/useEventSyncProjectStatus'
import { useGetProjectViewList } from './useGetProjectViewList'
import { useEventSyncProjectTask } from '@/events/useEventSyncProjectTask'

function SaveRecentVisitPage() {
const { projectId, orgID } = useParams()
Expand Down Expand Up @@ -48,6 +49,7 @@ function useRegisterEvents() {
useEventSyncProjectMember(projectId)
useEventSyncProjectView(projectId)
useEventSyncProjectStatus(projectId)
useEventSyncProjectTask(projectId)
}

function useGetAutomationRulesByProject() {
Expand Down
105 changes: 61 additions & 44 deletions packages/ui-app/app/_features/ProjectContainer/useGetTask.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
import { useEffect } from 'react'
import { useCallback, useEffect } from 'react'
import { extractDueDate } from '@shared/libs'
import { ExtendedTask, useTaskStore } from '@/store/task'
import { taskGetByCond } from '@/services/task'
import { useParams } from 'next/navigation'
import { messageError } from '@shared/ui'
import localforage from 'localforage'
import useTaskFilterContext from '../TaskFilter/useTaskFilterContext'
import differenceInDays from 'date-fns/differenceInDays'
import { Task } from '@prisma/client'

export default function useGetTask() {
const getAssigneeIds = (assigneeIds: string[]) => {
if (assigneeIds.includes('ALL')) return undefined
if (!assigneeIds.length) return ['null']

return assigneeIds.filter(a => a !== 'ALL')
}

export const useGetTaskHandler = () => {
const { projectId } = useParams()
const { addAllTasks, setTaskLoading } = useTaskStore()
const { filter } = useTaskFilterContext()

const { groupBy, status, statusIds, ...filterWithoutGroupBy } = filter
// const { groupBy, status,...filterWithoutGroupBy } = filter
const key = `TASKLIST_${projectId}`

const getAssigneeIds = (assigneeIds: string[]) => {
if (assigneeIds.includes('ALL')) return undefined
if (!assigneeIds.length) return ['null']

return assigneeIds.filter(a => a !== 'ALL')
}

useEffect(() => {
localforage
.getItem(key)
.then(val => {
if (val) {
addAllTasks(val as ExtendedTask[])
}
})
.catch(err => {
console.log('errpr loading cached task', err)
})
}, [projectId])
const key = `TASKLIST_${projectId}`

useEffect(() => {
const fetchNCache = useCallback(() => {
const controller = new AbortController()
const {
term,
Expand Down Expand Up @@ -72,31 +56,64 @@ export default function useGetTask() {
dueDate: [startDate || 'null', endDate || 'null']
},
controller.signal
)
.then(res => {
const { data, status, error } = res.data

if (status !== 200) {
addAllTasks([])
localforage.removeItem(key)
setTaskLoading(false)
messageError(error)
return
}
).then(res => {
const { data, status, error } = res.data

localforage.setItem(key, data)
setTimeout(() => {
addAllTasks(data)
setTaskLoading(false)
}, 300)
if (status !== 200) {
addAllTasks([])
localforage.removeItem(key)
setTaskLoading(false)
messageError(error)
return
}

})
localforage.setItem(key, data)
setTimeout(() => {
addAllTasks(data)
setTaskLoading(false)
}, 300)
})

return () => {
controller.abort()
}

// only re-fetching data when filter changes
// excpet groupBy filter
}, [projectId, filter, key, addAllTasks, setTaskLoading])

return {
fetchNCache,
filterWithoutGroupBy
}
}

function useFillTaskFromCache() {
const { projectId } = useParams()
const { addAllTasks } = useTaskStore()
const key = `TASKLIST_${projectId}`

useEffect(() => {
localforage
.getItem(key)
.then(val => {
if (val) {
addAllTasks(val as ExtendedTask[])
}
})
.catch(err => {
console.log('errpr loading cached task', err)
})
}, [projectId])
}

export default function useGetTask() {
const { fetchNCache, filterWithoutGroupBy } = useGetTaskHandler()
useFillTaskFromCache()

useEffect(() => {
fetchNCache()
// only re-fetch data as filter changed
}, [JSON.stringify(filterWithoutGroupBy)])

}

0 comments on commit 6d1585c

Please sign in to comment.