Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/KeyResult/Single/Drawer/Body/body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { KeyResult } from 'src/components/KeyResult/types'
import { keyResultAtomFamily } from 'src/state/recoil/key-result'
import { keyResultChecklistAtom } from 'src/state/recoil/key-result/checklist'

import { KeyResultChecklistWrapper } from '../../Sections/Checklist/wrapper'
import { KeyResultHistory } from '../../Sections/KeyResultHistory'
import { KeyResultProgress } from '../../Sections/Progress/wrapper'
import { KeyResultTasks } from '../../Sections/Tasks'

import { SCROLLBAR_ID } from './constants'
import messages from './messages'
Expand Down Expand Up @@ -120,7 +120,7 @@ const KeyResultDrawerBody = ({
<Divider borderColor="gray.100" />
</>
)}
<KeyResultChecklistWrapper keyResultID={keyResultID} isLoading={isLoading} />
<KeyResultTasks keyResultID={keyResultID} isLoading={isLoading} />
<Divider borderColor="gray.100" />
<KeyResultSectionOwner keyResultID={keyResultID} />
<Divider borderColor="gray.100" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export const CreateTaskButton = ({
const { dispatch } = useEvent(EventType.TASK_MANAGER_CREATE_TASK_CLICK)

const keyResult = useRecoilValue(keyResultAtomFamily(keyResultID))
const hasData = Boolean(keyResult?.teamId)

const handleNewCheckMark = async (title: NewTask['title']) => {
if (isSubmitting) return
Expand Down Expand Up @@ -115,7 +114,7 @@ export const CreateTaskButton = ({
/>
</StyledEditableWrapper>
)}
{(teamId ?? hasData) && (
{(teamId ?? keyResult) && (
<Button
ref={createButtonReference}
variant="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const KeyResultChecklist = ({
</StyledStack>
)}

{canCreate && teamId && (
{canCreate && (
<CreateTaskButton
mt={5}
keyResultID={keyResultID}
Expand Down
26 changes: 14 additions & 12 deletions src/components/KeyResult/Single/Sections/Checklist/wrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ParsedUrlQuery } from 'querystring'

import { Collapse, Stack } from '@chakra-ui/react'
import { Collapse, Stack, Skeleton } from '@chakra-ui/react'
import React, { useEffect, useState } from 'react'
import { useIntl } from 'react-intl'
import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
Expand Down Expand Up @@ -58,7 +58,6 @@ export const KeyResultChecklistWrapper = ({
const intl = useIntl()

const keyResult = useRecoilValue(keyResultAtomFamily(keyResultID))
const hasData = Boolean(keyResult?.teamId)

const toggleChecklistCollapse = () => {
setIsChecklistOpen((previous) => !previous)
Expand Down Expand Up @@ -109,7 +108,7 @@ export const KeyResultChecklistWrapper = ({
setHiddingModal(false)
}

return isLoading || hasData ? (
return (
<Stack spacing={0}>
<Stack direction="row" alignItems="flex-start" position="relative">
<IntlLink
Expand Down Expand Up @@ -138,13 +137,17 @@ export const KeyResultChecklistWrapper = ({
</svg>
</span>
</IntlLink>
<OptionBarWrapper
keyResultID={keyResultID}
progress={progress}
canCreate={canCreate}
onCreate={handleChecklistCreation}
/>
{hasItems && <ToggleCollapse isOpen={isChecklistOpen} onToggle={toggleChecklistCollapse} />}
<Skeleton isLoaded={isLoading}>
<OptionBarWrapper
keyResultID={keyResultID}
progress={progress}
canCreate={canCreate}
onCreate={handleChecklistCreation}
/>
{hasItems && (
<ToggleCollapse isOpen={isChecklistOpen} onToggle={toggleChecklistCollapse} />
)}
</Skeleton>
</Stack>
{isSuccess ? (
<Collapse in={isChecklistOpen}>
Expand All @@ -158,6 +161,5 @@ export const KeyResultChecklistWrapper = ({
</Collapse>
) : undefined}
</Stack>
) : // eslint-disable-next-line unicorn/no-null
null
)
}
96 changes: 96 additions & 0 deletions src/components/KeyResult/Single/Sections/Tasks/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Collapse, Stack, Skeleton } from '@chakra-ui/react'
import React from 'react'
import { useIntl } from 'react-intl'

import { IntlLink } from 'src/components/Base'

import { OptionBarWrapper } from '../Checklist/OptionBar/wrapper'
import { KeyResultChecklist } from '../Checklist/checklist'
import { ToggleCollapse } from '../Checklist/toggle-collapse'
import { KeyResultSectionHeading } from '../Heading/wrapper'

import messages from './messages'
import { useLogic } from './use-logic'

interface KeyResultTasksProperties {
keyResultID?: string
isLoading?: boolean
}

export const KeyResultTasks = ({ keyResultID, isLoading }: KeyResultTasksProperties) => {
const intl = useIntl()

const {
keyResult,
progress,
tasks,
isChecklistOpen,
isSuccess,
refetch,
handleClose,
handleChecklistCreation,
toggleChecklistCollapse,
} = useLogic({
keyResultID,
})

return (
<Stack spacing={0}>
<Stack
direction="row"
alignItems="flex-start"
position="relative"
justifyContent="space-between"
>
<IntlLink
href={
keyResult?.teamId && keyResultID
? `/explore/${keyResult?.teamId}?activeTab=tasks&key_result_id__id=${keyResultID}`
: '#'
}
onClick={handleClose}
>
<span style={{ display: 'flex', alignItems: 'baseline' }}>
<KeyResultSectionHeading mt="0.3rem" textDecoration="underline" mr="4px">
{intl.formatMessage(messages.heading)}
</KeyResultSectionHeading>
<svg
xmlns="http://www.w3.org/2000/svg"
width="6"
height="7"
viewBox="0 0 6 7"
fill="none"
>
<path
d="M6 0.881836V6.39914H4.9918V2.61911L0.724748 6.88184L0.665866 6.86992L0 6.19621L4.26518 1.89145H0.490787V0.881836H6Z"
fill="#525F7F"
/>
</svg>
</span>
</IntlLink>
<Skeleton isLoaded={!isLoading} display="flex">
<OptionBarWrapper
keyResultID={keyResultID}
progress={progress}
canCreate={tasks.length === 0}
onCreate={handleChecklistCreation}
/>
{tasks.length > 0 && (
<ToggleCollapse isOpen={isChecklistOpen} onToggle={toggleChecklistCollapse} />
)}
</Skeleton>
</Stack>
{isSuccess ? (
<Collapse in={isChecklistOpen}>
<KeyResultChecklist
nodes={tasks}
keyResultID={keyResultID}
canCreate={tasks.length > 0}
teamId={keyResult?.teamId}
onUpdate={refetch}
/>
</Collapse>
) : undefined}
</Stack>
)
}
53 changes: 53 additions & 0 deletions src/components/KeyResult/Single/Sections/Tasks/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { defineMessages } from 'react-intl'

type KeyResultsSectionChecklistMessage =
| 'heading'
| 'collapseButtonDesc'
| 'pendingColumnHeading'
| 'todoColumnHeading'
| 'doingColumnHeading'
| 'doneColumnHeading'
| 'addTaskButton'

export default defineMessages<KeyResultsSectionChecklistMessage>({
heading: {
defaultMessage: 'Tarefas',
id: 'BQha3x',
description: 'This is the title of our checklist section inside the key-result sidebar',
},

collapseButtonDesc: {
defaultMessage: 'Uma seta que ao ser clicada expande a checklist deste resultado-chave',
id: 'SsQRcF',
description:
'This message is used by screen readers to explain the collapse icon in our key-result sidebar on the checklist section',
},
pendingColumnHeading: {
defaultMessage: 'pendências',
id: 'pD5/TL',
description: 'This message appears on header of the pending column',
},

todoColumnHeading: {
defaultMessage: 'para fazer',
id: 'Sz6ZOB',
description: 'This message appears on header of the todo column',
},

doingColumnHeading: {
defaultMessage: 'em andamento',
id: 'MANxqE',
description: 'This message appears on header of the doing column',
},

doneColumnHeading: {
defaultMessage: 'concluído',
id: 'rw4RIa',
description: 'This message appears on header of the done column',
},
addTaskButton: {
defaultMessage: 'nova tarefa',
id: 'pfygkg',
description: 'This message appears on the add task button',
},
})
103 changes: 103 additions & 0 deletions src/components/KeyResult/Single/Sections/Tasks/use-logic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { ParsedUrlQuery } from 'querystring'

import { useEffect, useState } from 'react'
import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'

import { KeyResult } from 'src/components/KeyResult/types'
import { useTeamTasksData } from 'src/components/TaskManagement/hooks/new-task/use-get-team-tasks'
import { TASK_STATUS } from 'src/services/new-task-management/@types/task-status.enum'
import { Task } from 'src/services/new-task-management/@types/task.type'
import { keyResultAtomFamily } from 'src/state/recoil/key-result'
import buildPartialSelector from 'src/state/recoil/key-result/build-partial-selector'
import {
keyResultCheckInCommentEnabled,
keyResultCheckInProgressDraft,
keyResultLatestCheckIn,
} from 'src/state/recoil/key-result/check-in'
import isCheckInModalOpenAtom from 'src/state/recoil/key-result/check-in/is-check-in-modal-open'
import { draftCheckMarksAtom } from 'src/state/recoil/key-result/checklist'
import { keyResultReadDrawerOpenedKeyResultID } from 'src/state/recoil/key-result/drawers/read/opened-key-result-id'
import { isKeyResultListOpenAtom } from 'src/state/recoil/key-result/key-result-list'
import { createdByCheckInNotificationAtom } from 'src/state/recoil/notifications'

interface useLogicProperties {
keyResultID?: string
}

export const useLogic = ({ keyResultID }: useLogicProperties) => {
const [isChecklistOpen, setIsChecklistOpen] = useState(false)
const [progress, setProgress] = useState({ total: 0, numberOfDone: 0, progress: 0 })

// Fetch tasks
const {
data: tasks = [],
isFetching,
isSuccess,
refetch,
} = useTeamTasksData({ key_result_id__id: keyResultID } as ParsedUrlQuery)

// Refetch tasks after creation
const handleChecklistCreation = () => {
refetch()
if (!isChecklistOpen) setIsChecklistOpen(true)
}

// Change checklist state
const toggleChecklistCollapse = () => {
setIsChecklistOpen((previous) => !previous)
}

// Effect hooks
useEffect(() => {
// Calculate progress
const numberOfDone = tasks.filter((task: Task) => task.status === TASK_STATUS.done).length
if (tasks.length === 0) {
setProgress({ total: 0, numberOfDone: 0, progress: 0 })
} else {
setProgress({
total: tasks.length,
numberOfDone,
progress: (numberOfDone / tasks.length) * 100,
})
}
}, [isFetching, tasks, tasks.length])

// Global state management
const keyResult = useRecoilValue(keyResultAtomFamily(keyResultID))

// Global state related to the handle close action
const timelineSelector = buildPartialSelector<KeyResult['timeline']>('timeline')
const resetOpenDrawer = useResetRecoilState(keyResultReadDrawerOpenedKeyResultID)
const resetTimeline = useResetRecoilState(timelineSelector(keyResultID))
const resetCommentEnabled = useResetRecoilState(keyResultCheckInCommentEnabled(keyResultID))
const resetCheckmarkDrafts = useResetRecoilState(draftCheckMarksAtom(keyResultID))
const latestKeyResultCheckIn = useRecoilValue(keyResultLatestCheckIn(keyResultID))
const setDraftValue = useSetRecoilState(keyResultCheckInProgressDraft(keyResultID))
const setIsCheckInModalOpen = useSetRecoilState(isCheckInModalOpenAtom)
const setCreatedByNotification = useSetRecoilState(createdByCheckInNotificationAtom)
const setHiddingModal = useSetRecoilState(isKeyResultListOpenAtom)

// Close Key Result Drawer
const handleClose = () => {
resetOpenDrawer()
resetTimeline()
resetCommentEnabled()
resetCheckmarkDrafts()
setDraftValue(latestKeyResultCheckIn?.value)
setIsCheckInModalOpen(false)
setCreatedByNotification(false)
setHiddingModal(false)
}

return {
keyResult,
progress,
tasks,
isChecklistOpen,
isSuccess,
refetch,
handleClose,
handleChecklistCreation,
toggleChecklistCollapse,
}
}
Loading