Skip to content

Commit

Permalink
feat(agenda3): ✨ support for displaying future recurring tasks on Kanban
Browse files Browse the repository at this point in the history
  • Loading branch information
haydenull committed Nov 6, 2023
1 parent 6d34dd7 commit 7a162fa
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 47 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"react-icons": "^4.11.0",
"react-router-dom": "^6.4.3",
"react-sortablejs": "^6.1.4",
"rrule": "^2.7.2",
"sortablejs": "^1.15.0",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
Expand Down
58 changes: 30 additions & 28 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/constants/agenda.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import dayjs from 'dayjs'

export const TIME_FORMATTER = 'HH:mm'
export const DATE_FORMATTER = 'YYYY-MM-DD'
export const DATE_TIME_FORMATTER = 'YYYY-MM-DD HH:mm'
Expand Down Expand Up @@ -37,3 +39,6 @@ export const BACKGROUND_COLOR = {
blueGrey: '#607d8b',
}
export const DEFAULT_BG_COLOR_NAME = 'blue'

const today = dayjs()
export const recentDaysRange = [today.subtract(14, 'day'), today.add(14, 'day')] as const
57 changes: 43 additions & 14 deletions src/newHelper/task.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable no-useless-escape */
import type { BlockEntity } from '@logseq/libs/dist/LSPlugin'
import dayjs, { type Dayjs } from 'dayjs'
import { RRule as RRuleClass } from 'rrule'

import { DEFAULT_ESTIMATED_TIME } from '@/constants/agenda'
import { DEFAULT_ESTIMATED_TIME, recentDaysRange } from '@/constants/agenda'
import type { KanBanItem } from '@/pages/NewDashboard/components/KanBan'
import type { RRule } from '@/types/fullcalendar'
import type { AgendaTask, AgendaTaskWithStart, AgendaTaskPage } from '@/types/task'
Expand All @@ -11,6 +12,21 @@ import { genDays } from '@/util/util'
import { parseAgendaDrawer } from './block'
import { transformPageToProject } from './project'

export const FREQ_ENUM_MAP = {
hourly: RRuleClass.HOURLY,
daily: RRuleClass.DAILY,
weekly: RRuleClass.WEEKLY,
monthly: RRuleClass.MONTHLY,
yearly: RRuleClass.YEARLY,
} as const
const FREQ_MAP = {
h: 'hourly',
d: 'daily',
w: 'weekly',
m: 'monthly',
y: 'yearly',
} as const

export type BlockFromQuery = BlockEntity & {
marker: 'TODO' | 'DOING' | 'NOW' | 'LATER' | 'WAITING' | 'DONE' | 'CANCELED'
deadline: number
Expand Down Expand Up @@ -233,18 +249,11 @@ function parseRRule(input: string): RRule | null {
const parts = cleanedInput.split(' ')

function parseFreq(freq: string) {
const freqMap = {
h: 'hourly',
d: 'daily',
w: 'weekly',
m: 'monthly',
y: 'yearly',
}
const rruleReg = /[.+]*\+(\d+)([hdwmy])/
const res = freq.match(rruleReg)
if (!res) return null
return {
freq: freqMap[res[2]],
freq: FREQ_MAP[res[2]],
interval: Number(res[1]),
}
}
Expand Down Expand Up @@ -293,13 +302,14 @@ export const separateTasksInDay = (tasks: AgendaTaskWithStart[]): Map<string, Ag

/**
* adapt task to kanban
* splitting multi-days task into single-day tasks
*/
export const transformTasksToKanbanTasks = (tasks: AgendaTaskWithStart[]): KanBanItem[] => {
const today = dayjs()
return tasks
.map((task) => {
const { allDay, end, start } = task

// splitting multi-days task into single-day tasks
if (allDay && end) {
const days = genDays(start, end)
return days.map((day) => {
Expand All @@ -308,16 +318,35 @@ export const transformTasksToKanbanTasks = (tasks: AgendaTaskWithStart[]): KanBa
return {
...task,
start: day,
filtered: true,
// filtered: true,
// 过去且不是结束日期的任务默认为已完成
status: (isPast && !isEndDay) || task.status === 'done' ? 'done' : 'todo',
} as KanBanItem
})
}
return {
...task,
filtered: task.recurringPast || Boolean(task.rrule),

// show recurring task
if (task.rrule) {
const rruleInstance = new RRuleClass({
...task.rrule,
freq: FREQ_ENUM_MAP[task.rrule.freq],
dtstart: dayjs(task.rrule.dtstart).toDate(),
})
const [startDay, endDay] = recentDaysRange
const dates = rruleInstance.between(startDay.toDate(), endDay.add(1, 'day').toDate())
return dates.map((date) => {
return {
...task,
start: dayjs(date),
}
})
}

return task
// return {
// ...task,
// filtered: task.recurringPast || Boolean(task.rrule),
// }
})
.flat()
}
Expand Down
Loading

0 comments on commit 7a162fa

Please sign in to comment.