From d25c291c821c1c372e52caadc9d37cbe3bda9250 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 29 Jul 2025 09:28:04 -0300 Subject: [PATCH 1/6] task board filters --- public/icons/check.svg | 3 + .../hooks/use-get-team-key-result.ts | 4 +- .../Team/Tabs/BoardFilters/filters.module.css | 147 +++++++ .../Page/Team/Tabs/BoardFilters/index.tsx | 395 ++++++++++++++++++ .../Page/Team/Tabs/BoardFilters/messages.ts | 24 ++ .../Team/Tabs/content/board-tab-content.tsx | 79 ++-- .../InsertDrawer/Form/cycle.tsx | 71 ++++ .../InsertDrawer/Form/key-result.tsx | 2 +- .../InsertDrawer/Form/wrapper.tsx | 8 +- .../hooks/new-task/use-get-team-cycles.ts | 19 + .../hooks/use-get-team-cycles-date.ts | 19 + src/services/okr/cycle/@types.ts | 5 + src/services/okr/cycle/cycle.service.ts | 11 +- .../okr/key-result/key-result.service.ts | 4 +- 14 files changed, 737 insertions(+), 54 deletions(-) create mode 100644 public/icons/check.svg create mode 100644 src/components/Page/Team/Tabs/BoardFilters/filters.module.css create mode 100644 src/components/Page/Team/Tabs/BoardFilters/index.tsx create mode 100644 src/components/Page/Team/Tabs/BoardFilters/messages.ts create mode 100644 src/components/TaskManagement/InsertDrawer/Form/cycle.tsx create mode 100644 src/components/TaskManagement/hooks/new-task/use-get-team-cycles.ts create mode 100644 src/components/TaskManagement/hooks/use-get-team-cycles-date.ts diff --git a/public/icons/check.svg b/public/icons/check.svg new file mode 100644 index 000000000..42829d01f --- /dev/null +++ b/public/icons/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/KeyResult/hooks/use-get-team-key-result.ts b/src/components/KeyResult/hooks/use-get-team-key-result.ts index d3c75d1d6..ec51e86d9 100644 --- a/src/components/KeyResult/hooks/use-get-team-key-result.ts +++ b/src/components/KeyResult/hooks/use-get-team-key-result.ts @@ -6,14 +6,14 @@ import { ServicesContext } from 'src/components/Base/ServicesProvider/services-p const MODULE = 'KeyResult' const ACTION = 'getAllTeamKR' -export function useTeamKRData(teamId: string, objectiveId: string) { +export function useTeamKRData(teamId: string) { const { servicesPromise } = useContext(ServicesContext) const query = useQuery({ queryKey: [`${MODULE}:${ACTION}:${teamId}`], queryFn: async () => { const { keyResult } = await servicesPromise - const data = await keyResult.getKeyResultTeam(teamId, objectiveId) + const data = await keyResult.getKeyResultTeam(teamId) return data }, }) diff --git a/src/components/Page/Team/Tabs/BoardFilters/filters.module.css b/src/components/Page/Team/Tabs/BoardFilters/filters.module.css new file mode 100644 index 000000000..d7e473e65 --- /dev/null +++ b/src/components/Page/Team/Tabs/BoardFilters/filters.module.css @@ -0,0 +1,147 @@ +.modal_button { + display: flex; + align-items: baseline; + color: var(--chakra-colors-brand-500); + border: 1px solid var(--chakra-colors-brand-200); + font-weight: 500; + font-size: 15px; + border-radius: 4px; + padding: 5px 11px; + margin-right: 10px; + transition: 300ms; +} + +.modal_text { + margin: 0; + margin-right: 5px; +} + +.modal_content { + position: absolute; + background-color: #fff; + width: 170px; + border: 1px solid var(--chakra-colors-new-gray-200); + display: flex; + flex-direction: column; + padding: 5px; + border-radius: 4px; + transition: 300ms; + box-shadow: 0px 5px 10px 5px #B5C0DB1A; + z-index: 99; +} + +.modal_inner_button { + display: flex; + width: 100%; + padding: 10px; + font-size: 14px; + font-weight: 450; + align-items: center; + justify-content: space-between; + border-radius: 4px; +} + +.modal_inner_button_text { + color: var(--chakra-colors-gray-500); +} + +.sub_modal_content { + position: absolute; + display: flex; + flex-direction: column; + top: 15px; + left: 100%; + min-width: 225px; + max-height: 350px; + margin-left: 10px; + padding: 10px; + background-color: #fff; + border: 1px solid var(--chakra-colors-new-gray-200); + overflow: auto; +} + +.sub_modal_title { + padding: 0 8px; + font-weight: 450; + font-size: 12px; + color: #8193AB; +} + +.checkbox { + display: inline-block; + margin: 15px 10px; + cursor: pointer; +} + +.checkbox input { + display: none; +} + +.checkbox span { + position: relative; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; /* Limita a 2 linhas */ + overflow: hidden; + text-overflow: ellipsis; + min-height: 25px; + line-height: 18px; + font-weight: 450; + font-size: 14px; + /* Adicione padding-left para compensar a largura do :before */ + padding-left: 34px; +} + +.checkbox span:before, +.checkbox span:after { + content: ''; +} + +.checkbox span:before { + border: 1px solid var(--chakra-colors-gray-100); + width: 24px; + height: 24px; + position: absolute; + left: 0; + top: 0; + border-radius: 5px; +} + +.checkbox span:hover:before { + border-color: var(--chakra-colors-brand-500); + transition: 300ms; +} + +.checkbox span:after { + background: var(--chakra-colors-brand-500); + width: 24px; + height: 24px; + border-radius: 5px; + position: absolute; + left: 0; + top: 0; + transition: 300ms; + opacity: 0; + content: ''; /* Precisa ser vazio se usar background-image */ + background-image: url('/icons/check.svg'); /* Ou .png */ + background-size: auto; /* Garante que a imagem se ajuste */ + background-repeat: no-repeat; + background-position: center; +} + +.checkbox input:checked+span:after { + opacity: 1; +} + +.no_kr_text { + color: var(--chakra-colors-gray-500); + text-align: center; + padding: 20px 0; +} + +.divider { + margin: 8px 0; + width: 100%; + border: 1px solid #F3F5FA; + height: 1px +} diff --git a/src/components/Page/Team/Tabs/BoardFilters/index.tsx b/src/components/Page/Team/Tabs/BoardFilters/index.tsx new file mode 100644 index 000000000..9f3921c03 --- /dev/null +++ b/src/components/Page/Team/Tabs/BoardFilters/index.tsx @@ -0,0 +1,395 @@ +import { Spinner } from '@chakra-ui/react' +import { useRouter } from 'next/router' +import React, { ChangeEvent, useEffect, useState } from 'react' +import { useIntl } from 'react-intl' + +import { SearchBar } from 'src/components/Base/SearchBar/wrapper' +import ChevronDownIcon from 'src/components/Icon/ChevronDown' +import { useTeamKRData } from 'src/components/KeyResult/hooks/use-get-team-key-result' +import { useGetTeamCyclesDate } from 'src/components/TaskManagement/hooks/use-get-team-cycles-date' + +import styles from './filters.module.css' +import messages from './messages' + +interface BoardFiltersProperties { + teamId: string +} + +interface CycleFilter { + year: string | undefined + quarter: string | undefined +} + +interface FiltersData { + kr: string | undefined + cycle: CycleFilter | undefined + showDone: string | undefined +} + +interface MenuController { + isModalOpen: boolean + isKrOpen: boolean + isCycleOpen: boolean + isDoneOpen: boolean +} + +export const BoardFilters = ({ teamId }: BoardFiltersProperties) => { + const intl = useIntl() + const router = useRouter() + + const [cycleYears, setCycleYears] = useState>() + const defaultCycle = { + year: new Date().getFullYear().toString(), + quarter: Math.ceil((new Date().getMonth() + 1) / 3).toString(), + } + + const [filterData, setFilterData] = useState({ + kr: undefined, + cycle: { + year: defaultCycle.year, + quarter: defaultCycle.quarter, + }, + showDone: undefined, + }) + + const [modalController, setModalController] = useState({ + isModalOpen: false, + isKrOpen: false, + isCycleOpen: false, + isDoneOpen: false, + }) + + const handleAction = (modal: string) => { + switch (modal) { + case 'modal': + setModalController((previousValue) => { + return { + ...previousValue, + isModalOpen: !previousValue.isModalOpen, + isKrOpen: previousValue.isModalOpen ? previousValue.isKrOpen : false, + isCycleOpen: previousValue.isModalOpen ? previousValue.isCycleOpen : false, + isDoneOpen: previousValue.isModalOpen ? previousValue.isDoneOpen : false, + } + }) + break + case 'kr': + setModalController((previousValue) => { + return { + ...previousValue, + isKrOpen: !previousValue.isKrOpen, + isCycleOpen: false, + isDoneOpen: false, + } + }) + break + case 'cycle': + setModalController((previousValue) => { + return { + ...previousValue, + isCycleOpen: !previousValue.isCycleOpen, + isKrOpen: false, + isDoneOpen: false, + } + }) + break + case 'done': + setModalController((previousValue) => { + return { + ...previousValue, + isDoneOpen: !previousValue.isDoneOpen, + isKrOpen: false, + isCycleOpen: false, + } + }) + break + default: + break + } + } + + const checkValue = (oldValue: string | undefined, newValue: string) => { + return oldValue === newValue ? undefined : newValue + } + + const handleChange = (filter: string) => (event: ChangeEvent) => { + setFilterData((previousValue) => { + const data = event.target.value + if (filter === 'kr') { + handleQuery('key_result_id__id', checkValue(previousValue.kr, data)) + return { + ...previousValue, + kr: checkValue(previousValue.kr, data), + } + } + + if (filter === 'cycleYear') { + handleQuery('cy', `${data} + ${previousValue.cycle?.quarter ?? ''}`) + return { + ...previousValue, + cycle: { + year: checkValue(previousValue.cycle?.year, data), + quarter: previousValue.cycle?.quarter, + }, + } + } + + if (filter === 'cycleQuarter') { + handleQuery( + 'cy', + `${previousValue.cycle?.year ?? ''} + ${ + checkValue(previousValue.cycle?.quarter, data) ?? '' + }`, + ) + return { + ...previousValue, + cycle: { + quarter: checkValue(previousValue.cycle?.quarter, data), + year: previousValue.cycle?.year, + }, + } + } + + if (filter === 'showDone') { + handleQuery('show_done', data) + + return { + ...previousValue, + showDone: data === 'none' ? undefined : data, + } + } + + return previousValue + }) + } + + const { data: KeyResultData, isFetching: krFetching } = useTeamKRData(teamId) + const { data: cycles } = useGetTeamCyclesDate(teamId) + + const handleQuery = (key: string, newValue?: string) => { + router.query[key] = newValue === 'none' ? undefined : newValue + router.push(router, undefined, { shallow: true }) + return true + } + + useEffect(() => { + if (cycles) { + const result: Record = {} + for (const item of cycles) { + if (!result[item.year]) { + result[item.year] = [] + } + + result[item.year].push(item.quarter) + } + + setCycleYears(result) + } + }, [cycles]) + + const checkQuery = (index: string) => { + return router.query[index] === '' || router.query[index] === 'none' + ? undefined + : (router.query[index] as string) + } + + useEffect(() => { + const cycle = checkQuery('cy') + + setFilterData({ + kr: checkQuery('key_result_id__id'), + cycle: { + year: + cycle && cycle.length > 0 ? cycle.split('+')[0].replace(/\s/g, '') : defaultCycle.year, + quarter: + cycle && cycle.length > 1 ? cycle.split('+')[1].replace(/\s/g, '') : defaultCycle.quarter, + }, + showDone: checkQuery('show_done'), + }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router.query]) + + return ( +
+ + {modalController.isModalOpen && ( +
+ {/* KR */} + + {modalController.isKrOpen && ( +
+ + {krFetching ? ( + + ) : KeyResultData?.length === 0 ? ( +

Nenhum Resultado-chave Encontrado

+ ) : ( + KeyResultData?.map((kr) => ( + + )) + )} +
+ )} + + {/* CYCLE */} + + {modalController.isCycleOpen && ( +
+

Ciclo Anual

+
+ {cycleYears && + Object.keys(cycleYears).map((cycle) => ( + + ))} +
+ {filterData.cycle?.year && ( + <> + +

Trimestre

+
+ {cycleYears?.[filterData?.cycle?.year].map((cycle) => ( + + ))} +
+ + )} +
+ )} + + + {modalController.isDoneOpen && ( +
+ + + + +
+ )} +
+ )} +
+ ) +} diff --git a/src/components/Page/Team/Tabs/BoardFilters/messages.ts b/src/components/Page/Team/Tabs/BoardFilters/messages.ts new file mode 100644 index 000000000..f31b2b799 --- /dev/null +++ b/src/components/Page/Team/Tabs/BoardFilters/messages.ts @@ -0,0 +1,24 @@ +import { defineMessages } from 'react-intl' + +type SelectMenuMessage = 'iconChevronDownDesc' | 'iconChevronUpDesc' | 'defaultPlaceholder' + +export default defineMessages({ + iconChevronDownDesc: { + defaultMessage: 'Uma seta para baixo. Ao clicar nela você abrirá o menu de seleção', + id: 'rH+dGv', + description: + 'This is the desc attribute of our chevron down icon. It is used by screen readers', + }, + + iconChevronUpDesc: { + defaultMessage: 'Uma seta para cima. Ao clicar nela você fechará o menu de seleção', + id: 'ND5T6U', + description: 'This is the desc attribute of our chevron up icon. It is used by screen readers', + }, + + defaultPlaceholder: { + defaultMessage: 'Filtros', + id: 'IldkUk', + description: 'This is the default placeholder while selecting a given value in a select menu', + }, +}) diff --git a/src/components/Page/Team/Tabs/content/board-tab-content.tsx b/src/components/Page/Team/Tabs/content/board-tab-content.tsx index 709c11b99..512ed90f6 100644 --- a/src/components/Page/Team/Tabs/content/board-tab-content.tsx +++ b/src/components/Page/Team/Tabs/content/board-tab-content.tsx @@ -1,12 +1,10 @@ -import { Box, HStack, MenuItemOption, Stack, Text } from '@chakra-ui/react' +import { Box, HStack, Stack, Text } from '@chakra-ui/react' import { useRouter } from 'next/router' import React, { useEffect, useState } from 'react' import { useIntl } from 'react-intl' import { useRecoilValue, useSetRecoilState } from 'recoil' -import { SelectMenu } from 'src/components/Base' import { SearchBar } from 'src/components/Base/SearchBar/wrapper' -import { useTeamKRData } from 'src/components/KeyResult/hooks/use-get-team-key-result' import BoardWrapper from 'src/components/TaskManagement/Board/wrapper' import { TaskInsertDrawer } from 'src/components/TaskManagement/InsertDrawer/wrapper' import { TaskDrawer } from 'src/components/TaskManagement/TaskDrawer' @@ -14,6 +12,8 @@ import { Team } from 'src/components/Team/types' import { teamAtomFamily } from 'src/state/recoil/team' import { selectedTeamIdHighlight } from 'src/state/recoil/team/highlight/selected-team-id-highlight' +import { BoardFilters } from '../BoardFilters' + import messages from './messages' interface BoardTabContentProperties { @@ -21,40 +21,38 @@ interface BoardTabContentProperties { } const TasksTabContent = ({ teamId }: BoardTabContentProperties) => { - const router = useRouter() - const setSelectedTeamId = useSetRecoilState(selectedTeamIdHighlight) + const defaultCycle = { + year: new Date().getFullYear().toString(), + quarter: Math.ceil((new Date().getMonth() + 1) / 3).toString(), + } const team = useRecoilValue(teamAtomFamily(teamId)) const [searchTaskInput, setSearchTaskInput] = useState() - const { data: KeyResultData, isFetching: krFetching } = useTeamKRData(teamId, '0') + const [resetFilters, setResetFilters] = useState(false) const intl = useIntl() + const router = useRouter() + + useEffect(() => { + if ( + router.query.key_result_id__id || + router.query.cy !== `${defaultCycle.year}+${defaultCycle.quarter}` || + router.query.show_done + ) { + setResetFilters(true) + } + }, [router.query]) useEffect(() => { setSelectedTeamId(teamId) }, [setSelectedTeamId, teamId]) - const handleQuery = (key: string) => (newValue: string | string[]) => { - if (newValue !== 'none') { - router.query[key] = newValue - router.push(router) - return true - } - - router.query[key] = undefined + const onResetFilters = () => { + router.query.key_result_id__id = undefined + router.query.show_done = undefined + router.query.cy = `${defaultCycle.year}+${defaultCycle.quarter}` router.push(router) - return true - } - - const krSelected = (): string | undefined => { - const key = router.query.kr ? router.query.kr : undefined - if (key) { - const selectedKr = KeyResultData?.find((kr) => kr.id === key) - return selectedKr ? selectedKr.title : undefined - } - - return key } return ( @@ -64,25 +62,18 @@ const TasksTabContent = ({ teamId }: BoardTabContentProperties) => { {intl.formatMessage(messages.boardTabHeaderTitle, { team: team?.name })} - - Selecionar - {KeyResultData?.map((keyResult) => ( - - {keyResult.title} - - ))} - + {resetFilters && ( + onResetFilters()} + > + Limpar filtros + + )} + { + const router = useRouter() + const [isOpen, setIsOpen] = useState(false) + + const { values, setFieldValue } = useFormikContext() + const { id: teamId } = router.query + const { data: cycleData } = useGetTeamCycles(teamId as string) + + const handleChange = (newCycle: string | string[]) => { + if (Array.isArray(newCycle)) throw new Error('Cannot parse string array') + setFieldValue('cycle', newCycle) + handleClose() + } + + const handleOpen = () => { + if (!isOpen) setIsOpen(true) + } + + const handleClose = () => { + if (isOpen) setIsOpen(false) + } + + const cycleTitle = () => { + if (values.cycle !== '') { + const cycle = cycleData?.find((cycle) => cycle.id === values.cycle) + return cycle ? cycle.period : 'Selecione um ciclo' + } + + return 'Selecione um ciclo' + } + + return ( + + + + Selecione um ciclo + {cycleData?.map((cycle) => ( + + {cycle.period} + + ))} + + + + ) +} diff --git a/src/components/TaskManagement/InsertDrawer/Form/key-result.tsx b/src/components/TaskManagement/InsertDrawer/Form/key-result.tsx index 18246e24f..25c8bfaf6 100644 --- a/src/components/TaskManagement/InsertDrawer/Form/key-result.tsx +++ b/src/components/TaskManagement/InsertDrawer/Form/key-result.tsx @@ -20,7 +20,7 @@ export const KeyResultInput = ({ isLoading }: KeyResultInputProperties) => { const { values, setFieldValue } = useFormikContext() const { id: teamId } = router.query - const { data: KeyResultData } = useTeamKRData(teamId as string, '0') + const { data: KeyResultData } = useTeamKRData(teamId as string) const handleChange = (newKr: string | string[]) => { if (Array.isArray(newKr)) throw new Error('Cannot parse string array') diff --git a/src/components/TaskManagement/InsertDrawer/Form/wrapper.tsx b/src/components/TaskManagement/InsertDrawer/Form/wrapper.tsx index 59d14d12d..958194ad5 100644 --- a/src/components/TaskManagement/InsertDrawer/Form/wrapper.tsx +++ b/src/components/TaskManagement/InsertDrawer/Form/wrapper.tsx @@ -15,6 +15,7 @@ import meAtom from 'src/state/recoil/user/me' import useColumnTasks from '../../Board/hooks/use-column-tasks' import { FormActions } from './actions' +import { CycleInput } from './cycle' import { DescriptionInput } from './description' import { DueDateInput } from './due-date' import { KeyResultInput } from './key-result' @@ -27,7 +28,7 @@ import { TitleInput } from './title' export type FormValues = { teamId?: string keyResult?: string - cycle?: string + cycle: string title: string priority: TaskPriority description: string @@ -78,9 +79,10 @@ const InsertOrUpdateTaskForm = ({ const NewTaskSchema = Yup.object().shape({ title: Yup.string().required(intl.formatMessage(messages.titleRequiredText)), keyResult: Yup.string(), + cycle: Yup.string().required(), priority: Yup.string().required(), description: Yup.string(), - initialDate: Yup.date(), + initialDate: Yup.date().required(), dueDate: Yup.date() .min(Yup.ref('initialDate'), intl.formatMessage(messages.dueDateBeforeInitialDateText)) .max(new Date(2100, 11, 31), intl.formatMessage(messages.dueDateAfter2030Text)) @@ -96,6 +98,7 @@ const InsertOrUpdateTaskForm = ({ title: '', priority: 4, keyResult: '', + cycle: '', initialDate: new Date(), dueDate: new Date(), description: ' ', @@ -212,6 +215,7 @@ const InsertOrUpdateTaskForm = ({ isLoading={isLoading} /> + { + const { cycle } = await servicesPromise + const data = await cycle.getTeamCycle(teamId) + return data + }, + }) + + return query +} diff --git a/src/components/TaskManagement/hooks/use-get-team-cycles-date.ts b/src/components/TaskManagement/hooks/use-get-team-cycles-date.ts new file mode 100644 index 000000000..2b80a8abd --- /dev/null +++ b/src/components/TaskManagement/hooks/use-get-team-cycles-date.ts @@ -0,0 +1,19 @@ +import { useQuery } from '@tanstack/react-query' +import { useContext } from 'react' + +import { ServicesContext } from 'src/components/Base/ServicesProvider/services-provider' + +export function useGetTeamCyclesDate(teamId: string) { + const { servicesPromise } = useContext(ServicesContext) + + const query = useQuery({ + queryKey: [`taskManager:getTeamCycles:${teamId}`], + queryFn: async () => { + const { cycle } = await servicesPromise + const data = await cycle.getTeamCyclesDate(teamId) + return data + }, + }) + + return query +} diff --git a/src/services/okr/cycle/@types.ts b/src/services/okr/cycle/@types.ts index 3d68a92ae..f6ecdeeb9 100644 --- a/src/services/okr/cycle/@types.ts +++ b/src/services/okr/cycle/@types.ts @@ -13,3 +13,8 @@ export type Cycle = { parent_id: string active: boolean } + +export interface CycleFilter { + year: string + quarter: string +} diff --git a/src/services/okr/cycle/cycle.service.ts b/src/services/okr/cycle/cycle.service.ts index 38eabf8d0..859b6d5a1 100644 --- a/src/services/okr/cycle/cycle.service.ts +++ b/src/services/okr/cycle/cycle.service.ts @@ -1,12 +1,17 @@ import { AxiosInstance } from 'axios' -import { Cycle } from './@types' +import { Cycle, CycleFilter } from './@types' export class CycleService { constructor(private readonly client: AxiosInstance) {} - async getCycleTeam(teamId: string) { - const { data } = await this.client.get(`cycle/${teamId}/`) + async getTeamCyclesDate(teamId: string) { + const { data } = await this.client.get(`api/okr/cycle/date/${teamId}`) + return data + } + + async getTeamCycle(teamId: string) { + const { data } = await this.client.get(`api/okr/cycle/${teamId}`) return data } } diff --git a/src/services/okr/key-result/key-result.service.ts b/src/services/okr/key-result/key-result.service.ts index a0d835429..f5052dade 100644 --- a/src/services/okr/key-result/key-result.service.ts +++ b/src/services/okr/key-result/key-result.service.ts @@ -5,8 +5,8 @@ import { KeyResult, KeyResultWithTasks } from './@types' export class KeyResultService { constructor(private readonly client: AxiosInstance) {} - async getKeyResultTeam(teamId: string, objectiveId: string) { - const { data } = await this.client.get(`kr/${teamId}/${objectiveId}/`) + async getKeyResultTeam(teamId: string) { + const { data } = await this.client.get(`api/okr/key_result/${teamId}`) return data } From 9b2a49f9eef49278ac18043012faf1d6394ee0f4 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 29 Jul 2025 09:28:23 -0300 Subject: [PATCH 2/6] lang att --- lang/pt-BR.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lang/pt-BR.json b/lang/pt-BR.json index 03f14e217..a73e8a836 100644 --- a/lang/pt-BR.json +++ b/lang/pt-BR.json @@ -1291,6 +1291,10 @@ "defaultMessage": "para {confidence}", "description": "This text is displayed as the second line of our confidence tooltip" }, + "IldkUk": { + "defaultMessage": "Filtros", + "description": "This is the default placeholder while selecting a given value in a select menu" + }, "IoZbDV": { "defaultMessage": "Deseja excluir esse comentário?", "description": "This message appears in delete modal confirmation." From 38251f6ac63a87c22fd8bb0b72efe5bc0fd7627c Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 29 Jul 2025 09:32:59 -0300 Subject: [PATCH 3/6] eslint fix --- src/components/Cycle/hooks/use-get-team-cycle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Cycle/hooks/use-get-team-cycle.ts b/src/components/Cycle/hooks/use-get-team-cycle.ts index 60c259970..a4845baf4 100644 --- a/src/components/Cycle/hooks/use-get-team-cycle.ts +++ b/src/components/Cycle/hooks/use-get-team-cycle.ts @@ -13,7 +13,7 @@ export function useTeamCycleData(teamId: string) { queryKey: [`${MODULE}:${ACTION}:${teamId}`], queryFn: async () => { const { cycle } = await servicesPromise - const data = await cycle.getCycleTeam(teamId) + const data = await cycle.getTeamCycle(teamId) return data }, }) From 74ace3779cb02108c88b3bb3d4ec22bdaa2bfe60 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 29 Jul 2025 10:56:59 -0300 Subject: [PATCH 4/6] fix modal z index --- src/components/Page/Team/Tabs/BoardFilters/filters.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Page/Team/Tabs/BoardFilters/filters.module.css b/src/components/Page/Team/Tabs/BoardFilters/filters.module.css index d7e473e65..c936a09ea 100644 --- a/src/components/Page/Team/Tabs/BoardFilters/filters.module.css +++ b/src/components/Page/Team/Tabs/BoardFilters/filters.module.css @@ -27,7 +27,7 @@ border-radius: 4px; transition: 300ms; box-shadow: 0px 5px 10px 5px #B5C0DB1A; - z-index: 99; + z-index: 9; } .modal_inner_button { From 427f423b95dcb6e559bbbd77d0280d83b99d059d Mon Sep 17 00:00:00 2001 From: Kevin Date: Wed, 30 Jul 2025 13:31:32 -0300 Subject: [PATCH 5/6] major name and directory changes + old task manager excluded --- .../kanban-task-card-metadata.tsx | 2 +- .../ActionButtons/create-task-in-kr.tsx | 4 +- .../Checklist/ActionButtons/delete-task.tsx | 2 +- .../Single/Sections/Checklist/checklist.tsx | 2 +- .../Checklist/hooks/use-delete-task.ts | 4 +- .../Checklist/hooks/use-update-task.ts | 6 +- .../Sections/Checklist/inline-tasklist.tsx | 4 +- .../Single/Sections/Checklist/wrapper.tsx | 6 +- .../Sections/Owner/support-team-field.tsx | 2 +- .../hooks/use-add-task-new.ts | 6 +- .../hooks/use-delete-tasks.ts | 4 +- .../Team/Tabs/content/board-tab-content.tsx | 2 + src/components/Task/types.ts | 2 +- .../components/archive-and-delete-menu.tsx | 65 -------- .../components/auto-resize-text-area.tsx | 11 -- .../Board/components/column.tsx | 4 +- .../TaskManagement/Board/components/task.tsx | 4 +- .../Board/hooks/use-column-drop.ts | 4 +- .../Board/hooks/use-column-tasks.ts | 14 +- .../hooks/use-load-owners-and-support-team.ts | 4 +- .../Board/hooks/use-load-users.ts | 28 ---- .../Board/hooks/use-task-collection.ts | 23 --- .../Board/hooks/use-task-drag-and-drop.ts | 2 +- .../TaskManagement/Board/utils/helpers.ts | 2 +- .../TaskManagement/Board/utils/models.ts | 4 +- .../TaskManagement/Board/wrapper.tsx | 6 +- .../InsertDrawer/Form/cycle.tsx | 2 +- .../InsertDrawer/Form/wrapper.tsx | 4 +- .../TaskDrawer/OwnerSection/index.tsx | 9 +- .../TaskDrawer/SupportTeamField/wrapper.tsx | 4 +- .../TaskDrawer/Timeline/Card/index.tsx | 4 +- .../TaskDrawer/Timeline/TaskComment/index.tsx | 2 +- .../TaskDrawer/Timeline/TaskUpdate/index.tsx | 2 +- .../TaskDrawer/Timeline/index.tsx | 6 +- .../TaskDrawer/Timeline/timeline-wrapper.tsx | 4 +- .../TaskDrawer/description-section.tsx | 4 +- .../TaskDrawer/due-date-section.tsx | 6 +- .../TaskDrawer/title-section.tsx | 4 +- .../hooks/new-task/use-add-task.ts | 23 --- .../hooks/new-task/use-get-task.ts | 21 --- .../{new-task => }/use-add-task-comments.ts | 6 +- .../TaskManagement/hooks/use-add-task.ts | 15 +- .../hooks/use-archive-column.ts | 37 ----- .../TaskManagement/hooks/use-delete-column.ts | 38 ----- .../use-delete-task-comments.ts | 4 +- .../hooks/{new-task => }/use-delete-task.ts | 4 +- .../{new-task => }/use-get-task-comments.ts | 4 +- .../hooks/use-get-task-updates.ts | 21 --- .../TaskManagement/hooks/use-get-task.ts | 15 +- .../{new-task => }/use-get-team-cycles.ts | 0 .../{new-task => }/use-get-team-tasks.ts | 4 +- .../hooks/use-remove-task-mutate.ts | 27 ---- .../hooks/use-team-tasks-board-data.ts | 26 --- .../hooks/use-update-board-mutate.ts | 24 --- .../hooks/use-update-task-mutate.ts | 24 --- .../hooks/{new-task => }/use-update-task.ts | 6 +- src/services/index.ts | 6 - src/services/new-task-management/index.ts | 1 - .../new-task-management-instance.ts | 8 - .../new-task-management.service.ts | 126 --------------- src/services/okr/key-result/@types.ts | 2 +- .../@types/task-comment.type.ts | 0 .../@types/task-history.type.ts | 0 .../@types/task-status.enum.ts | 0 .../@types/task-update.type.ts | 0 .../@types/task.type.ts | 0 .../task-management-instance.ts | 4 +- .../task-management.service.ts | 152 ++++++------------ .../task-management-create-task-data.ts | 2 +- .../task-management-delete-task-data.ts | 2 +- ...task-management-update-task-column-data.ts | 2 +- .../drawers/insert/task-insert-drawer.ts | 2 +- .../drawers/task-drawer/task-drawer.ts | 2 +- 73 files changed, 153 insertions(+), 723 deletions(-) rename src/components/{TaskManagement => KeyResult}/hooks/use-add-task-new.ts (75%) rename src/components/{TaskManagement => KeyResult}/hooks/use-delete-tasks.ts (77%) delete mode 100644 src/components/TaskManagement/Board/components/archive-and-delete-menu.tsx delete mode 100644 src/components/TaskManagement/Board/components/auto-resize-text-area.tsx delete mode 100644 src/components/TaskManagement/Board/hooks/use-load-users.ts delete mode 100644 src/components/TaskManagement/Board/hooks/use-task-collection.ts delete mode 100644 src/components/TaskManagement/hooks/new-task/use-add-task.ts delete mode 100644 src/components/TaskManagement/hooks/new-task/use-get-task.ts rename src/components/TaskManagement/hooks/{new-task => }/use-add-task-comments.ts (75%) delete mode 100644 src/components/TaskManagement/hooks/use-archive-column.ts delete mode 100644 src/components/TaskManagement/hooks/use-delete-column.ts rename src/components/TaskManagement/hooks/{new-task => }/use-delete-task-comments.ts (82%) rename src/components/TaskManagement/hooks/{new-task => }/use-delete-task.ts (83%) rename src/components/TaskManagement/hooks/{new-task => }/use-get-task-comments.ts (80%) delete mode 100644 src/components/TaskManagement/hooks/use-get-task-updates.ts rename src/components/TaskManagement/hooks/{new-task => }/use-get-team-cycles.ts (100%) rename src/components/TaskManagement/hooks/{new-task => }/use-get-team-tasks.ts (82%) delete mode 100644 src/components/TaskManagement/hooks/use-remove-task-mutate.ts delete mode 100644 src/components/TaskManagement/hooks/use-team-tasks-board-data.ts delete mode 100644 src/components/TaskManagement/hooks/use-update-board-mutate.ts delete mode 100644 src/components/TaskManagement/hooks/use-update-task-mutate.ts rename src/components/TaskManagement/hooks/{new-task => }/use-update-task.ts (77%) delete mode 100644 src/services/new-task-management/index.ts delete mode 100644 src/services/new-task-management/new-task-management-instance.ts delete mode 100644 src/services/new-task-management/new-task-management.service.ts rename src/services/{new-task-management => task-management}/@types/task-comment.type.ts (100%) rename src/services/{new-task-management => task-management}/@types/task-history.type.ts (100%) rename src/services/{new-task-management => task-management}/@types/task-status.enum.ts (100%) rename src/services/{new-task-management => task-management}/@types/task-update.type.ts (100%) rename src/services/{new-task-management => task-management}/@types/task.type.ts (100%) diff --git a/src/components/Base/KanbanTaskCard/kanban-task-card-metadata.tsx b/src/components/Base/KanbanTaskCard/kanban-task-card-metadata.tsx index b5f6f3d0d..d3cc8d4ac 100644 --- a/src/components/Base/KanbanTaskCard/kanban-task-card-metadata.tsx +++ b/src/components/Base/KanbanTaskCard/kanban-task-card-metadata.tsx @@ -9,7 +9,7 @@ import ClockIcon from 'src/components/Icon/Clock' import LowPriorityIcon from 'src/components/Icon/LowPriorityIcon' import MediumPriorityIcon from 'src/components/Icon/MediumPriorityIcon' import { User } from 'src/components/User/types' -import { TASK_STATUS } from 'src/services/task-management/task-management.service' +import { TASK_STATUS } from 'src/services/task-management/@types/task-status.enum' import selectUser from 'src/state/recoil/user/selector' import { TaskPriority } from './kanban-task-card-root' diff --git a/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/create-task-in-kr.tsx b/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/create-task-in-kr.tsx index 797eac597..441ab054c 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/create-task-in-kr.tsx +++ b/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/create-task-in-kr.tsx @@ -6,9 +6,9 @@ import { useRecoilValue } from 'recoil' import { EditableInputField } from 'src/components/Base' import { PlusOutline } from 'src/components/Icon' +import { useAddTask } from 'src/components/KeyResult/hooks/use-add-task-new' import { NewTask } from 'src/components/Task/types' -import { useAddTask } from 'src/components/TaskManagement/hooks/use-add-task-new' -import { TASK_STATUS } from 'src/services/new-task-management/@types/task-status.enum' +import { TASK_STATUS } from 'src/services/task-management/@types/task-status.enum' import { keyResultAtomFamily } from 'src/state/recoil/key-result' import meAtom from 'src/state/recoil/user/me' diff --git a/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/delete-task.tsx b/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/delete-task.tsx index f779998d4..ee6bb5246 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/delete-task.tsx +++ b/src/components/KeyResult/Single/Sections/Checklist/ActionButtons/delete-task.tsx @@ -2,7 +2,7 @@ import React, { Ref } from 'react' import { useIntl } from 'react-intl' import { DeleteButton } from 'src/components/Base/Button/delete-button' -import { useDeleteTaskByKr } from 'src/components/TaskManagement/hooks/use-delete-tasks' +import { useDeleteTaskByKr } from 'src/components/KeyResult/hooks/use-delete-tasks' import messages from './messages' diff --git a/src/components/KeyResult/Single/Sections/Checklist/checklist.tsx b/src/components/KeyResult/Single/Sections/Checklist/checklist.tsx index 910dce4a6..832a58051 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/checklist.tsx +++ b/src/components/KeyResult/Single/Sections/Checklist/checklist.tsx @@ -2,8 +2,8 @@ import { Stack, StyleProps } from '@chakra-ui/react' import styled from '@emotion/styled' import React, { useRef } from 'react' -import { Task } from 'src/services/new-task-management/@types/task.type' import { TaskSummary } from 'src/services/okr/key-result/@types' +import { Task } from 'src/services/task-management/@types/task.type' import { CreateTaskButton } from './ActionButtons/create-task-in-kr' import { InlineTaskList } from './inline-tasklist' diff --git a/src/components/KeyResult/Single/Sections/Checklist/hooks/use-delete-task.ts b/src/components/KeyResult/Single/Sections/Checklist/hooks/use-delete-task.ts index 995e77e68..320e8b37b 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/hooks/use-delete-task.ts +++ b/src/components/KeyResult/Single/Sections/Checklist/hooks/use-delete-task.ts @@ -12,8 +12,8 @@ export const useDeleteTask = () => { return useMutation({ mutationFn: async ({ taskId }: { taskId: string }) => { - const { newTaskManagement } = await servicesPromise - return newTaskManagement.removeTask(taskId) + const { taskManagement } = await servicesPromise + return taskManagement.removeTask(taskId) }, onSuccess: (_data, variables) => { queryClient.invalidateQueries({ queryKey: [`${MODULE}:${ACTION}:${variables.taskId}`] }) diff --git a/src/components/KeyResult/Single/Sections/Checklist/hooks/use-update-task.ts b/src/components/KeyResult/Single/Sections/Checklist/hooks/use-update-task.ts index d2a3142cc..b3f116c53 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/hooks/use-update-task.ts +++ b/src/components/KeyResult/Single/Sections/Checklist/hooks/use-update-task.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import { useContext } from 'react' import { ServicesContext } from 'src/components/Base/ServicesProvider/services-provider' -import { TaskUpdate } from 'src/services/new-task-management/@types/task-update.type' +import { TaskUpdate } from 'src/services/task-management/@types/task-update.type' export function useUpdateTask({ userId }: { userId: string }) { const { servicesPromise } = useContext(ServicesContext) @@ -10,8 +10,8 @@ export function useUpdateTask({ userId }: { userId: string }) { const updateTaskMutate = useMutation({ mutationFn: async ({ taskId, data }: { taskId: string; data: Partial }) => { - const { newTaskManagement } = await servicesPromise - const response = await newTaskManagement.updateTask(taskId, data) + const { taskManagement } = await servicesPromise + const response = await taskManagement.updateTask(taskId, data) return response }, onSuccess: (_data, _variables) => { diff --git a/src/components/KeyResult/Single/Sections/Checklist/inline-tasklist.tsx b/src/components/KeyResult/Single/Sections/Checklist/inline-tasklist.tsx index 123bbe451..be535cab9 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/inline-tasklist.tsx +++ b/src/components/KeyResult/Single/Sections/Checklist/inline-tasklist.tsx @@ -22,9 +22,9 @@ import { useRecoilValue } from 'recoil' import { EditableInputField } from 'src/components/Base' import { NamedAvatar } from 'src/components/User' import { AllReachableUsers } from 'src/components/User/AllReachableUsers/wrapper' -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 { TaskSummary } from 'src/services/okr/key-result/@types' +import { TASK_STATUS } from 'src/services/task-management/@types/task-status.enum' +import { Task } from 'src/services/task-management/@types/task.type' import meAtom from 'src/state/recoil/user/me' import { DeleteTaskButton } from './ActionButtons/delete-task' diff --git a/src/components/KeyResult/Single/Sections/Checklist/wrapper.tsx b/src/components/KeyResult/Single/Sections/Checklist/wrapper.tsx index d5f94b75d..ae9064c21 100644 --- a/src/components/KeyResult/Single/Sections/Checklist/wrapper.tsx +++ b/src/components/KeyResult/Single/Sections/Checklist/wrapper.tsx @@ -7,9 +7,9 @@ import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { IntlLink } from 'src/components/Base' 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 { useTeamTasksData } from 'src/components/TaskManagement/hooks/use-get-team-tasks' +import { TASK_STATUS } from 'src/services/task-management/@types/task-status.enum' +import { Task } from 'src/services/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 { diff --git a/src/components/KeyResult/Single/Sections/Owner/support-team-field.tsx b/src/components/KeyResult/Single/Sections/Owner/support-team-field.tsx index 59775891b..e1cbfa756 100644 --- a/src/components/KeyResult/Single/Sections/Owner/support-team-field.tsx +++ b/src/components/KeyResult/Single/Sections/Owner/support-team-field.tsx @@ -10,7 +10,7 @@ import GET_KEY_RESULTS_HIGHLIGHTS from 'src/components/Page/Team/Highlights/get- import GET_NO_RELATED_MEMBERS from 'src/components/Page/Team/Highlights/hooks/getNoRelatedMembers/get-no-related-members.gql' import { User } from 'src/components/User/types' import { Except } from 'src/helpers/except' -import { Task } from 'src/services/new-task-management/@types/task.type' +import { Task } from 'src/services/task-management/@types/task.type' import { keyResultAtomFamily } from 'src/state/recoil/key-result' import { ownersAndSupportTeamTaskAtom } from 'src/state/recoil/task-management/board/owners-and-support-team-task' import { taskSupportTeamAtom } from 'src/state/recoil/task-management/drawers/task-drawer/task-support-team' diff --git a/src/components/TaskManagement/hooks/use-add-task-new.ts b/src/components/KeyResult/hooks/use-add-task-new.ts similarity index 75% rename from src/components/TaskManagement/hooks/use-add-task-new.ts rename to src/components/KeyResult/hooks/use-add-task-new.ts index 2f64fa1fb..b62fa9f5b 100644 --- a/src/components/TaskManagement/hooks/use-add-task-new.ts +++ b/src/components/KeyResult/hooks/use-add-task-new.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import { useContext } from 'react' import { ServicesContext } from 'src/components/Base/ServicesProvider/services-provider' -import { TaskInsert } from 'src/services/new-task-management/new-task-management.service' +import { TaskInsert } from 'src/services/task-management/task-management.service' export function useAddTask() { const { servicesPromise } = useContext(ServicesContext) @@ -10,8 +10,8 @@ export function useAddTask() { const addTaskToKrMutate = useMutation({ mutationFn: async (data: TaskInsert) => { - const { newTaskManagement } = await servicesPromise - const response = await newTaskManagement.addTask(data) + const { taskManagement } = await servicesPromise + const response = await taskManagement.addTask(data) return response }, onSuccess: (_data, _variables) => { diff --git a/src/components/TaskManagement/hooks/use-delete-tasks.ts b/src/components/KeyResult/hooks/use-delete-tasks.ts similarity index 77% rename from src/components/TaskManagement/hooks/use-delete-tasks.ts rename to src/components/KeyResult/hooks/use-delete-tasks.ts index a40841018..48ccbc83f 100644 --- a/src/components/TaskManagement/hooks/use-delete-tasks.ts +++ b/src/components/KeyResult/hooks/use-delete-tasks.ts @@ -8,8 +8,8 @@ export const useDeleteTaskByKr = () => { return useMutation({ mutationFn: async ({ taskID }: { taskID: string }) => { - const { newTaskManagement } = await servicesPromise - return newTaskManagement.removeTask(taskID) + const { taskManagement } = await servicesPromise + return taskManagement.removeTask(taskID) }, }) } diff --git a/src/components/Page/Team/Tabs/content/board-tab-content.tsx b/src/components/Page/Team/Tabs/content/board-tab-content.tsx index 512ed90f6..87f74d6b0 100644 --- a/src/components/Page/Team/Tabs/content/board-tab-content.tsx +++ b/src/components/Page/Team/Tabs/content/board-tab-content.tsx @@ -37,11 +37,13 @@ const TasksTabContent = ({ teamId }: BoardTabContentProperties) => { useEffect(() => { if ( router.query.key_result_id__id || + router.query.cy || router.query.cy !== `${defaultCycle.year}+${defaultCycle.quarter}` || router.query.show_done ) { setResetFilters(true) } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [router.query]) useEffect(() => { diff --git a/src/components/Task/types.ts b/src/components/Task/types.ts index 62924759c..5abed46a0 100644 --- a/src/components/Task/types.ts +++ b/src/components/Task/types.ts @@ -1,5 +1,5 @@ import { User } from 'src/components/User/types' -import { TASK_STATUS } from 'src/services/new-task-management/@types/task-status.enum' +import { TASK_STATUS } from 'src/services/task-management/@types/task-status.enum' import { GraphQLConnection, GraphQLNode, GraphQLEntityPolicy } from '../types' diff --git a/src/components/TaskManagement/Board/components/archive-and-delete-menu.tsx b/src/components/TaskManagement/Board/components/archive-and-delete-menu.tsx deleted file mode 100644 index b6409be2c..000000000 --- a/src/components/TaskManagement/Board/components/archive-and-delete-menu.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react' -import React, { useCallback, useState } from 'react' - -import { DangerousActionConfirmationDialog } from 'src/components/Base/Dialogs/Confirmation/DangerousAction/wrapper' -import TreeDotsIcon from 'src/components/Icon/TreeDots' - -import { useArchiveColumn } from '../../hooks/use-archive-column' -import { useDeleteColumn } from '../../hooks/use-delete-column' -import { BOARD_DOMAIN } from '../../hooks/use-team-tasks-board-data' - -interface ArchiveAndDeleteMenuProperties { - boardDomain: BOARD_DOMAIN - teamId: string - ids: string[] -} - -const ArchiveAndDeleteMenu = ({ boardDomain, teamId, ids }: ArchiveAndDeleteMenuProperties) => { - const { mutate: archiveMutate } = useArchiveColumn(boardDomain, teamId) - const { mutate: deleteMutate } = useDeleteColumn(boardDomain, teamId) - - const [isDialogOpen, setDialogOpen] = useState(false) - - const archiveSubmit = useCallback(() => { - archiveMutate({ ids }) - }, [archiveMutate, ids]) - - const deleteSubmit = useCallback(() => { - deleteMutate({ ids }) - }, [deleteMutate, ids]) - - return ( - - setDialogOpen(false)} - /> - - - - - Arquivar todas as tarefas - setDialogOpen(true)}> - Excluir todas as tarefas - - - - ) -} - -export default ArchiveAndDeleteMenu diff --git a/src/components/TaskManagement/Board/components/auto-resize-text-area.tsx b/src/components/TaskManagement/Board/components/auto-resize-text-area.tsx deleted file mode 100644 index 20e412d5e..000000000 --- a/src/components/TaskManagement/Board/components/auto-resize-text-area.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Textarea, TextareaProps } from '@chakra-ui/react' -import React from 'react' -import ResizeTextarea from 'react-textarea-autosize' - -const AutoResizeTextarea = React.forwardRef( - (properties, reference) => { - return