Skip to content

Commit

Permalink
feat: [skip ci] completed edit objective modal
Browse files Browse the repository at this point in the history
  • Loading branch information
haydenull committed Dec 11, 2023
1 parent 521c40c commit fe90ab1
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 87 deletions.
92 changes: 47 additions & 45 deletions src/Agenda3/components/kanban/taskCard/ObjectiveCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { cn } from '@/util/util'

import Group from '../../Group'
import LogseqLogo from '../../icons/LogseqLogo'
import EditObjectiveModal from '../../modals/ObjectiveModal/EditObjectiveModal'

const ObjectiveCard = ({ objective }: { objective: AgendaObjective }) => {
const { currentGraph } = useAtomValue(logseqAtom)
Expand All @@ -21,56 +22,57 @@ const ObjectiveCard = ({ objective }: { objective: AgendaObjective }) => {
const showTitle = formatTaskTitle(objective)

return (
<div
key={objective.id}
className={cn(
'group/card relative shrink-0 cursor-pointer overflow-hidden whitespace-pre-wrap rounded-md bg-white p-2 shadow',
{
'bg-[#edeef0] opacity-80': objective.status === 'done',
},
)}
>
<GoGoal
className={cn('absolute -right-3 top-1 text-8xl text-gray-100', {
'text-[#e2e3e6]': objective.status === 'done',
})}
/>
<div className="relative">
<div className="flex items-center justify-between">
<div className="flex items-center gap-1">
{objective.status === 'done' ? (
<IoIosCheckmarkCircle
className="cursor-pointer text-xl text-gray-300"
// onClick={(e) => onClickTaskMark(e, task, 'todo')}
/>
) : (
<IoIosCheckmarkCircleOutline
className="cursor-pointer text-xl text-gray-300"
// onClick={(e) => onClickTaskMark(e, task, 'done')}
/>
)}
<EditObjectiveModal initialData={objective}>
<div
className={cn(
'group/card relative shrink-0 cursor-pointer overflow-hidden whitespace-pre-wrap rounded-md bg-white p-2 shadow',
{
'bg-[#edeef0] opacity-80': objective.status === 'done',
},
)}
>
<GoGoal
className={cn('absolute -right-3 top-1 text-8xl text-gray-100', {
'text-[#e2e3e6]': objective.status === 'done',
})}
/>
<div className="relative">
<div className="flex items-center justify-between">
<div className="flex items-center gap-1">
{objective.status === 'done' ? (
<IoIosCheckmarkCircle
className="cursor-pointer text-xl text-gray-300"
// onClick={(e) => onClickTaskMark(e, task, 'todo')}
/>
) : (
<IoIosCheckmarkCircleOutline
className="cursor-pointer text-xl text-gray-300"
// onClick={(e) => onClickTaskMark(e, task, 'done')}
/>
)}

<div
className="cursor-pointer text-gray-300 opacity-0 transition-opacity group-hover/card:opacity-100"
onClick={(e) => {
e.stopPropagation()
navToLogseqBlock(objective, currentGraph)
}}
>
<LogseqLogo />
<div
className="cursor-pointer text-gray-300 opacity-0 transition-opacity group-hover/card:opacity-100"
onClick={(e) => {
e.stopPropagation()
navToLogseqBlock(objective, currentGraph)
}}
>
<LogseqLogo />
</div>
</div>
</div>
<div
className={cn('my-0.5 text-gray-600', {
'line-through': objective.status === 'done',
})}
>
{showTitle}
</div>
<Group task={objective} type={groupType} />
</div>
<div
className={cn('my-0.5 text-gray-600', {
'line-through': objective.status === 'done',
})}
>
{showTitle}
</div>
<Group task={objective} type={groupType} />
</div>
</div>
</EditObjectiveModal>
)
}

Expand Down
107 changes: 102 additions & 5 deletions src/Agenda3/components/modals/ObjectiveModal/BaseObjectiveModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { Input, Modal } from 'antd'
import { Button, Input, Modal, Popconfirm } from 'antd'
import { useAtomValue } from 'jotai'
import React, { useState } from 'react'
import { BsCalendar4Event } from 'react-icons/bs'
import { IoIosCheckmarkCircleOutline } from 'react-icons/io'
import { RiCheckboxBlankCircleLine, RiDeleteBin4Line } from 'react-icons/ri'

import { navToLogseqBlock } from '@/Agenda3/helpers/logseq'
import { logseqAtom } from '@/Agenda3/models/logseq'
import type { AgendaObjective } from '@/types/objective'

import LogseqLogo from '../../icons/LogseqLogo'
import type { CreateTaskForm } from '../TaskModal/useCreate'
import { type CreateObjectiveForm } from './CreateObjectiveModal'
import { type EditObjectiveForm } from './EditObjectiveModal'
Expand All @@ -19,16 +27,105 @@ type ObjectiveModalProps =
type: 'edit'
children: React.ReactNode
formData: EditObjectiveForm
initialObjective: AgendaObjective
updateFormData: (data: Partial<EditObjectiveForm>) => void
action: () => void
onDelete: () => void
onSwitchObjectiveStatus: (status: 'todo' | 'done') => void
}

export const ObjectiveModal = ({ children, formData, updateFormData, action }: ObjectiveModalProps) => {
export const BaseObjectiveModal = (props: ObjectiveModalProps) => {
const { children, formData, updateFormData, action, type } = props
const { currentGraph } = useAtomValue(logseqAtom)
const [open, setOpen] = useState(false)

const handleCancel = () => {
setOpen(false)
}
const handleOk = async () => {
await action()
setOpen(false)
}
const handleDelete = async () => {
if (type === 'edit') {
await props.onDelete()
setOpen(false)
}
}
const handleSwitchObjectiveStatus = async (status: 'todo' | 'done') => {
if (type === 'edit') {
await props.onSwitchObjectiveStatus(status)
setOpen(false)
}
}

return (
<>
<span onClick={() => setOpen(true)}>{children}</span>
<Modal className="!w-[620px]" open={open} onCancel={() => setOpen(false)} onOk={action}>
<Modal
className="!w-[620px]"
open={open}
onCancel={handleCancel}
onOk={handleOk}
footer={
<div className="flex items-center justify-between">
<div>
{type === 'edit' && props.initialObjective.status === 'todo' ? (
<Button
className="inline-flex items-center px-2"
icon={<IoIosCheckmarkCircleOutline className="text-base" />}
onClick={() => handleSwitchObjectiveStatus('done')}
>
Complete
</Button>
) : null}
{type === 'edit' && props.initialObjective.status === 'done' ? (
<Button
className="inline-flex items-center px-2"
icon={<RiCheckboxBlankCircleLine />}
onClick={() => handleSwitchObjectiveStatus('todo')}
>
Incomplete
</Button>
) : null}
{type === 'edit' ? (
<Popconfirm
key="delete"
title="Delete the task"
description="Are you sure to delete this task?"
onConfirm={handleDelete}
>
<Button
className="inline-flex items-center px-2 hover:!border-red-500 hover:!text-red-500"
icon={<RiDeleteBin4Line />}
>
Delete
</Button>
</Popconfirm>
) : null}
{type === 'edit' ? (
<Button
className="inline-flex items-center justify-center text-gray-400"
shape="circle"
icon={<LogseqLogo />}
onClick={() => {
navToLogseqBlock(props.initialObjective, currentGraph)
setOpen(false)
}}
/>
) : null}
</div>
<div>
<Button key="cancel" onClick={handleCancel}>
Cancel
</Button>
<Button key="ok" type="primary" onClick={handleOk}>
{type === 'create' ? 'Add Objective' : 'Save'}
</Button>
</div>
</div>
}
>
<Input
className="!border-0 !px-0 !text-2xl !shadow-none"
placeholder="Objective Title"
Expand All @@ -40,12 +137,12 @@ export const ObjectiveModal = ({ children, formData, updateFormData, action }: O
<BsCalendar4Event /> Period
</div>
<div className="flex items-center gap-1">
<PeriodPicker initialValue={formData?.objective} />
<PeriodPicker initialValue={formData?.objective} onChange={(o) => updateFormData({ objective: o })} />
</div>
</div>
</Modal>
</>
)
}

export default ObjectiveModal
export default BaseObjectiveModal
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
/**
* 创建目标的弹窗
* 基于 BaseObjectiveModal 组件
*/
import dayjs from 'dayjs'
import React from 'react'
import { useState } from 'react'

import useAgendaTasks from '@/Agenda3/hooks/useAgendaTasks'
import type { AgendaTaskObjective } from '@/types/objective'

import { ObjectiveModal } from './BaseObjectiveModal'
import { BaseObjectiveModal } from './BaseObjectiveModal'

export type CreateObjectiveForm = {
title: string
Expand Down Expand Up @@ -42,9 +46,9 @@ const CreateObjectiveModal = ({ children, initialData }: CreateObjectiveModalPro
}

return (
<ObjectiveModal type="create" formData={formData} updateFormData={updateFormData} action={create}>
<BaseObjectiveModal type="create" formData={formData} updateFormData={updateFormData} action={create}>
{children}
</ObjectiveModal>
</BaseObjectiveModal>
)
}

Expand Down
44 changes: 29 additions & 15 deletions src/Agenda3/components/modals/ObjectiveModal/EditObjectiveModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import React from 'react'
import { useState } from 'react'
import { type Output, number, object, string, picklist } from 'valibot'

import { updateBlockTaskStatus } from '@/Agenda3/helpers/block'
import useAgendaTasks from '@/Agenda3/hooks/useAgendaTasks'
import type { AgendaObjective } from '@/types/objective'

import { ObjectiveModal } from './BaseObjectiveModal'
import { BaseObjectiveModal } from './BaseObjectiveModal'

const editFormSchema = object({
title: string(),
Expand All @@ -24,32 +26,44 @@ const EditObjectiveModal = ({ children, initialData }: EditObjectiveModalProps)
const _initialData = { title: initialData.title, objective: initialData.objective }
const [formData, setFormData] = useState<EditObjectiveForm>(_initialData)

const { updateTask, deleteTask } = useAgendaTasks()

const updateFormData = (data: Partial<EditObjectiveForm>) => {
setFormData((_data) => ({
..._data,
...data,
}))
}

const edit = async () => {
// const block = await editObjectiveBlock({
// title: formData.title,
// period: formData.period,
// })
// if (!block) {
// logseq.UI.showMsg('Failed to create objective block')
// throw new Error('Failed to create objective block')
// }
// return block
return updateTask({
type: 'objective',
id: initialData.id,
data: formData,
})
}
const handleDelete = () => {
deleteTask(initialData.id)
}
const reset = () => {
setFormData(_initialData)
const handleSwitchStatus = async (status: 'todo' | 'done') => {
return updateTask({
type: 'objective-status',
id: initialData.id,
data: status,
})
}

return (
<ObjectiveModal type="edit" formData={formData} updateFormData={updateFormData} action={edit}>
<BaseObjectiveModal
type="edit"
initialObjective={initialData}
formData={formData}
updateFormData={updateFormData}
action={edit}
onDelete={handleDelete}
onSwitchObjectiveStatus={handleSwitchStatus}
>
{children}
</ObjectiveModal>
</BaseObjectiveModal>
)
}

Expand Down
1 change: 1 addition & 0 deletions src/Agenda3/components/objectiveBoard/ObjectiveBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { cn } from '@/util/util'
import { appAtom } from '../../models/app'
import { agendaObjectivesAtom } from '../../models/objectives'
import ObjectiveCard from '../kanban/taskCard/ObjectiveCard'
import EditObjectiveModal from '../modals/ObjectiveModal/EditObjectiveModal'
import AddObjectiveCard from './AddObjectiveCard'

const ObjectiveBoard = () => {
Expand Down
Loading

0 comments on commit fe90ab1

Please sign in to comment.