diff --git a/src/newHelper/fullCalendar.ts b/src/newHelper/fullCalendar.ts index 50b5cff..3dc958a 100644 --- a/src/newHelper/fullCalendar.ts +++ b/src/newHelper/fullCalendar.ts @@ -8,9 +8,11 @@ import { padZero } from '@/util/util' */ export const transformAgendaTaskToCalendarEvent = ( task: AgendaTaskWithStart, - options: { showFirstEventInCycleOnly?: boolean; showTimeLog?: boolean } = {}, + options: { showFirstEventInCycleOnly?: boolean; showTimeLog?: boolean; groupType: 'filter' | 'page' } = { + groupType: 'page', + }, ): CalendarEvent[] => { - const { showFirstEventInCycleOnly = false, showTimeLog = false } = options + const { showFirstEventInCycleOnly = false, showTimeLog = false, groupType } = options const { estimatedTime = DEFAULT_ESTIMATED_TIME, timeLogs = [], status, actualTime } = task const spanTime = status === 'done' && actualTime && showTimeLog ? actualTime : estimatedTime const rrule: CalendarEvent['rrule'] = @@ -29,7 +31,7 @@ export const transformAgendaTaskToCalendarEvent = ( end: log.end.toDate(), extendedProps: task, editable: false, - color: task.project.bgColor, + color: groupType === 'page' ? task.project.bgColor : task.filters?.[0]?.color, })) } return [ @@ -47,7 +49,7 @@ export const transformAgendaTaskToCalendarEvent = ( // 只有时间点事件才能传 duration duration: task.allDay ? undefined : { minute: spanTime }, editable: !(task.recurringPast || task.rrule), - color: task.project.bgColor, + color: groupType === 'page' ? task.project.bgColor : task.filters?.[0]?.color, }, ] } diff --git a/src/newHelper/task.ts b/src/newHelper/task.ts index 6759c47..7c94b27 100644 --- a/src/newHelper/task.ts +++ b/src/newHelper/task.ts @@ -35,6 +35,9 @@ export type BlockFromQuery = BlockEntity & { page: AgendaTaskPage repeated?: boolean } +export type BlockFromQueryWithFilters = BlockFromQuery & { + filters?: Filter[] +} export const getAgendaTasks = async (settings: Settings) => { const favoritePages = (await logseq.App.getCurrentGraphFavorites()) || [] let blocks = (await logseq.DB.datascriptQuery(` @@ -70,16 +73,25 @@ export const getAgendaTasks = async (settings: Settings) => { :where [?block :block/marker ?marker] [(contains? #{"TODO" "DOING" "NOW" "LATER" "WAITING" "DONE"} ?marker)]] - `)) as BlockFromQuery[] + `)) as BlockFromQueryWithFilters[] if (!blocks || blocks?.length === 0) return [] blocks = blocks.flat() const filters = settings.filters?.filter((_filter) => settings.selectedFilters?.includes(_filter.id)) ?? [] - const filterBlocks = await retrieveFilteredBlocks(filters) if (settings.selectedFilters?.length) { + const filterBlocks = await retrieveFilteredBlocks(filters) const filterBlockIds = filterBlocks.map((block) => block.uuid) - blocks = blocks.filter((block) => filterBlockIds.includes(block.uuid)) + blocks = blocks + .filter((block) => filterBlockIds.includes(block.uuid)) + .map((block) => { + return { + ...block, + filters: filterBlocks + .filter((filterBlock) => filterBlock.uuid === block.uuid) + .map((filterBlock) => filterBlock.filter), + } + }) } const promiseList: Promise[] = blocks.map(async (block) => { const _block = { @@ -136,7 +148,16 @@ export const transformBlockToAgendaTask = async ( settings: Settings, ): Promise => { const { general = {} } = settings - const { uuid, marker, content, scheduled: scheduledNumber, deadline: deadlineNumber, properties, page } = block + const { + uuid, + marker, + content, + scheduled: scheduledNumber, + deadline: deadlineNumber, + properties, + page, + filters, + } = block const title = content.split('\n')[0]?.replace(marker, '')?.trim() @@ -240,6 +261,7 @@ export const transformBlockToAgendaTask = async ( estimatedTime, actualTime, project: transformPageToProject(page, favoritePages), + filters, timeLogs, // TODO: read from logseq // label: page, @@ -439,10 +461,17 @@ export const execQuery = async (query: string): Promise => return logseq.DB.datascriptQuery(query) } -export const retrieveFilteredBlocks = async (filters: Filter[]): Promise => { - const list = filters.map((filter) => { - return execQuery(filter.query) +type BlockEntityWithFilter = BlockEntity & { + filter: Filter +} +export const retrieveFilteredBlocks = async (filters: Filter[]): Promise => { + const list = filters.map(async (filter) => { + const blocks = await execQuery(filter.query) + return blocks?.flat(Infinity)?.map((block) => ({ + ...block, + filter, + })) }) const result = await Promise.all(list) - return result.flat(Infinity).filter(Boolean) as BlockEntity[] + return result.flat(Infinity).filter(Boolean) as BlockEntityWithFilter[] } diff --git a/src/newModel/settings.ts b/src/newModel/settings.ts index bb25e97..cf5b29b 100644 --- a/src/newModel/settings.ts +++ b/src/newModel/settings.ts @@ -23,4 +23,5 @@ export type Filter = { id: string name: string query: string + color: string } diff --git a/src/pages/NewDashboard/components/Backlog.tsx b/src/pages/NewDashboard/components/Backlog.tsx index 06c714c..fce794e 100644 --- a/src/pages/NewDashboard/components/Backlog.tsx +++ b/src/pages/NewDashboard/components/Backlog.tsx @@ -10,6 +10,7 @@ import { ReactSortable } from 'react-sortablejs' import { navToLogseqBlock } from '@/newHelper/logseq' import { categorizeTasksByPage, formatTaskTitle } from '@/newHelper/task' import { logseqAtom } from '@/newModel/logseq' +import { settingsAtom } from '@/newModel/settings' import { backlogTasksAtom } from '@/newModel/tasks' import LogseqLogo from './LogseqLogo' @@ -21,6 +22,8 @@ const Backlog = ({ bindCalendar = true }: { bindCalendar?: boolean }) => { const { currentGraph } = useAtomValue(logseqAtom) const categorizedTasks = categorizeTasksByPage(backlogTasks) const projects = categorizedTasks.map(({ project }) => project) + const settings = useAtomValue(settingsAtom) + const groupType = settings.selectedFilters?.length ? 'filter' : 'page' const [filterProjectIds, setFilterProjectIds] = useState([]) @@ -101,7 +104,7 @@ const Backlog = ({ bindCalendar = true }: { bindCalendar?: boolean }) => { data-event={JSON.stringify({ id: task.id, title: showTitle, - color: task.project.bgColor, + color: groupType === 'page' ? task.project.bgColor : task.filters?.[0]?.color, backlog: true, })} > diff --git a/src/pages/NewDashboard/components/Calendar.tsx b/src/pages/NewDashboard/components/Calendar.tsx index f5f64ba..0a6fc91 100644 --- a/src/pages/NewDashboard/components/Calendar.tsx +++ b/src/pages/NewDashboard/components/Calendar.tsx @@ -51,6 +51,7 @@ const Calendar = ({ onCalendarTitleChange }: CalendarProps, ref) => { const { updateTaskData, deleteTask, addNewTask } = useAgendaTasks() const tasksWithStart = useAtomValue(tasksWithStartAtom) const settings = useAtomValue(settingsAtom) + const groupType = settings.selectedFilters?.length ? 'filter' : 'page' const showTasks = tasksWithStart?.filter((task) => settings.viewOptions?.hideCompleted ? task.status === 'todo' : true, ) @@ -60,6 +61,7 @@ const Calendar = ({ onCalendarTitleChange }: CalendarProps, ref) => { transformAgendaTaskToCalendarEvent(task, { showFirstEventInCycleOnly: settings.viewOptions?.showFirstEventInCycleOnly, showTimeLog: settings.viewOptions?.showTimeLog, + groupType, }), ) .flat() diff --git a/src/pages/NewDashboard/components/ColorPickerCom.tsx b/src/pages/NewDashboard/components/ColorPickerCom.tsx new file mode 100644 index 0000000..989f0a3 --- /dev/null +++ b/src/pages/NewDashboard/components/ColorPickerCom.tsx @@ -0,0 +1,31 @@ +import { Button, ColorPicker } from 'antd' +import type { Color } from 'antd/es/color-picker' + +import { BACKGROUND_COLOR } from '@/constants/agenda' + +const ColorPickerCom = ({ value, onChange }: { value?: string; onChange?: (value: string) => void }) => { + // const [color, setColor] = useState(BACKGROUND_COLOR[DEFAULT_BG_COLOR_NAME]) + + // const bgColor = useMemo(() => (typeof color === 'string' ? color : color.toHexString()), [color]) + + const btnStyle: React.CSSProperties = { + backgroundColor: value, + } + + return ( + { + onChange?.(hex) + }} + > + + + ) +} + +export default ColorPickerCom diff --git a/src/pages/NewDashboard/components/EditFilterModal.tsx b/src/pages/NewDashboard/components/EditFilterModal.tsx index 714902b..553b7b6 100644 --- a/src/pages/NewDashboard/components/EditFilterModal.tsx +++ b/src/pages/NewDashboard/components/EditFilterModal.tsx @@ -1,9 +1,12 @@ -import { Form, Input, Modal } from 'antd' +import { Button, ColorPicker, Form, Input, Modal } from 'antd' import { useState } from 'react' +import { BACKGROUND_COLOR, DEFAULT_BG_COLOR_NAME } from '@/constants/agenda' import type { Filter } from '@/newModel/settings' import { genRandomString } from '@/util/util' +import ColorPickerCom from './ColorPickerCom' + const EditFilterModal = ({ children, type, @@ -35,7 +38,16 @@ const EditFilterModal = ({ onCancel={() => setOpen(false)} onOk={handleClickOk} > - form={formRef} layout="vertical" initialValues={initialValues} preserve={false} className="mt-8"> + + form={formRef} + layout="vertical" + initialValues={initialValues ?? { color: BACKGROUND_COLOR[DEFAULT_BG_COLOR_NAME] }} + preserve={false} + className="mt-8" + > + + + diff --git a/src/pages/NewDashboard/components/Filter.tsx b/src/pages/NewDashboard/components/Filter.tsx index 489aeac..0204988 100644 --- a/src/pages/NewDashboard/components/Filter.tsx +++ b/src/pages/NewDashboard/components/Filter.tsx @@ -50,7 +50,10 @@ const Filter = () => { )} onClick={() => onClickItem(filter)} > - {filter.name} +
+ + {filter.name} +
) diff --git a/src/pages/NewDashboard/components/Group.tsx b/src/pages/NewDashboard/components/Group.tsx new file mode 100644 index 0000000..dc0402b --- /dev/null +++ b/src/pages/NewDashboard/components/Group.tsx @@ -0,0 +1,33 @@ +import { type AgendaTask } from '@/types/task' + +const Group = ({ task, type }: { task: AgendaTask; type: 'page' | 'filter' }) => { + return type === 'page' ? : +} + +function RenderPage({ task }: { task: AgendaTask }) { + return ( + <> + {task.project.isJournal ? null : ( +
+ + {task.project?.originalName} +
+ )} + + ) +} + +function RenderFilter({ task }: { task: AgendaTask }) { + return ( +
+ {task.filters?.map((filter) => ( +
+ + {filter.name} +
+ ))} +
+ ) +} + +export default Group diff --git a/src/pages/NewDashboard/components/KanBan.tsx b/src/pages/NewDashboard/components/KanBan.tsx index d724fe9..8f14ad5 100644 --- a/src/pages/NewDashboard/components/KanBan.tsx +++ b/src/pages/NewDashboard/components/KanBan.tsx @@ -28,6 +28,7 @@ import { recentTasksAtom } from '@/newModel/tasks' import type { AgendaTaskWithStart, AgendaTask } from '@/types/task' import { cn, genDays, replaceDateInfo } from '@/util/util' +import Group from './Group' import LogseqLogo from './LogseqLogo' import PlannerModal from './PlannerModal' import TaskModal from './TaskModal' @@ -57,6 +58,8 @@ const KanBan = (props, ref) => { const days = getRecentDays() const today = dayjs() + const groupType = settings.selectedFilters?.length ? 'filter' : 'page' + const app = useAtomValue(appAtom) const [editTaskModal, setEditTaskModal] = useState<{ @@ -261,7 +264,7 @@ const KanBan = (props, ref) => { id: task.id, title: showTitle, duration: minutesToHHmm(estimatedTime), - color: task.project.bgColor, + color: groupType === 'page' ? task.project.bgColor : task?.filters?.[0]?.color, })} > { {task.start.format('HH:mm')} @@ -333,12 +337,7 @@ const KanBan = (props, ref) => {
{showTitle}
- {task.project.isJournal ? null : ( -
- - {task.project?.originalName} -
- )} +
diff --git a/src/pages/NewDashboard/components/PageSelect.tsx b/src/pages/NewDashboard/components/PageSelect.tsx index f935e84..6eb1580 100644 --- a/src/pages/NewDashboard/components/PageSelect.tsx +++ b/src/pages/NewDashboard/components/PageSelect.tsx @@ -2,8 +2,17 @@ import { Select } from 'antd' import usePages from '@/hooks/usePages' -const PageSelect = ({ value, onChange }: { value?: string; onChange?: (value: string) => void }) => { +const PageSelect = ({ + value, + onChange, + showPageColor = true, +}: { + value?: string + onChange?: (value: string) => void + showPageColor?: boolean +}) => { const { allPages: pages } = usePages() + return (