From 42cceb5e65513143c928e80c8304e12d387e8eef Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:57:36 +0530 Subject: [PATCH 01/20] fix: filter state option order (#4284) --- .../issues/issue-layouts/filters/header/filters/state.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/issues/issue-layouts/filters/header/filters/state.tsx b/web/components/issues/issue-layouts/filters/header/filters/state.tsx index 56340e6db..88068d666 100644 --- a/web/components/issues/issue-layouts/filters/header/filters/state.tsx +++ b/web/components/issues/issue-layouts/filters/header/filters/state.tsx @@ -26,7 +26,7 @@ export const FilterState: React.FC = observer((props) => { const sortedOptions = useMemo(() => { const filteredOptions = (states ?? []).filter((s) => s.name.toLowerCase().includes(searchQuery.toLowerCase())); - return sortBy(filteredOptions, [(s) => !(appliedFilters ?? []).includes(s.id), (s) => s.name.toLowerCase()]); + return sortBy(filteredOptions, [(s) => !(appliedFilters ?? []).includes(s.id)]); // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchQuery]); From 88165a8fdbc4ecc5ac74f18ad787d8127e4f2c63 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:58:27 +0530 Subject: [PATCH 02/20] chore: module and cycle sidebar stats item filter implementation (#4286) --- .../core/sidebar/sidebar-progress-stats.tsx | 102 ++++++++++-------- web/components/cycles/sidebar.tsx | 62 +++++++---- web/components/modules/sidebar.tsx | 39 ++++++- 3 files changed, 135 insertions(+), 68 deletions(-) diff --git a/web/components/core/sidebar/sidebar-progress-stats.tsx b/web/components/core/sidebar/sidebar-progress-stats.tsx index 528b8aa18..db9d94a8f 100644 --- a/web/components/core/sidebar/sidebar-progress-stats.tsx +++ b/web/components/core/sidebar/sidebar-progress-stats.tsx @@ -4,6 +4,8 @@ import Image from "next/image"; // headless ui import { Tab } from "@headlessui/react"; import { + IIssueFilterOptions, + IIssueFilters, IModule, TAssigneesDistribution, TCompletionChartDistribution, @@ -37,6 +39,9 @@ type Props = { roundedTab?: boolean; noBackground?: boolean; isPeekView?: boolean; + isCompleted?: boolean; + filters?: IIssueFilters | undefined; + handleFiltersUpdate: (key: keyof IIssueFilterOptions, value: string | string[]) => void; }; export const SidebarProgressStats: React.FC = ({ @@ -47,6 +52,9 @@ export const SidebarProgressStats: React.FC = ({ roundedTab, noBackground, isPeekView = false, + isCompleted = false, + filters, + handleFiltersUpdate, }) => { const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees"); @@ -145,20 +153,11 @@ export const SidebarProgressStats: React.FC = ({ } completed={assignee.completed_issues} total={assignee.total_issues} - {...(!isPeekView && { - onClick: () => { - // TODO: set filters here - // if (filters?.assignees?.includes(assignee.assignee_id ?? "")) - // setFilters({ - // assignees: filters?.assignees?.filter((a) => a !== assignee.assignee_id), - // }); - // else - // setFilters({ - // assignees: [...(filters?.assignees ?? []), assignee.assignee_id ?? ""], - // }); - }, - // selected: filters?.assignees?.includes(assignee.assignee_id ?? ""), - })} + {...(!isPeekView && + !isCompleted && { + onClick: () => handleFiltersUpdate("assignees", assignee.assignee_id ?? ""), + selected: filters?.filters?.assignees?.includes(assignee.assignee_id ?? ""), + })} /> ); else @@ -192,35 +191,52 @@ export const SidebarProgressStats: React.FC = ({ className="flex w-full flex-col gap-1.5 overflow-y-auto pt-3.5 vertical-scrollbar scrollbar-sm" > {distribution && distribution?.labels.length > 0 ? ( - distribution.labels.map((label, index) => ( - - - {label.label_name ?? "No labels"} - - } - completed={label.completed_issues} - total={label.total_issues} - {...(!isPeekView && { - // TODO: set filters here - onClick: () => { - // if (filters.labels?.includes(label.label_id ?? "")) - // setFilters({ - // labels: filters?.labels?.filter((l) => l !== label.label_id), - // }); - // else setFilters({ labels: [...(filters?.labels ?? []), label.label_id ?? ""] }); - }, - // selected: filters?.labels?.includes(label.label_id ?? ""), - })} - /> - )) + distribution.labels.map((label, index) => { + if (label.label_id) { + return ( + + + {label.label_name ?? "No labels"} + + } + completed={label.completed_issues} + total={label.total_issues} + {...(!isPeekView && + !isCompleted && { + onClick: () => handleFiltersUpdate("labels", label.label_id ?? ""), + selected: filters?.filters?.labels?.includes(label.label_id ?? `no-label-${index}`), + })} + /> + ); + } else { + return ( + + + {label.label_name ?? "No labels"} + + } + completed={label.completed_issues} + total={label.total_issues} + /> + ); + } + }) ) : (
diff --git a/web/components/cycles/sidebar.tsx b/web/components/cycles/sidebar.tsx index 106f3b3e0..9ada6cf63 100644 --- a/web/components/cycles/sidebar.tsx +++ b/web/components/cycles/sidebar.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; @@ -16,7 +16,7 @@ import { } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; // types -import { ICycle } from "@plane/types"; +import { ICycle, IIssueFilterOptions } from "@plane/types"; // ui import { Avatar, ArchiveIcon, CustomMenu, Loader, LayersIcon, TOAST_TYPE, setToast, TextArea } from "@plane/ui"; // components @@ -27,12 +27,13 @@ import { DateRangeDropdown } from "@/components/dropdowns"; // constants import { CYCLE_STATUS } from "@/constants/cycle"; import { CYCLE_UPDATED } from "@/constants/event-tracker"; +import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { EUserWorkspaceRoles } from "@/constants/workspace"; // helpers import { findHowManyDaysLeft, getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper"; import { copyUrlToClipboard } from "@/helpers/string.helper"; // hooks -import { useEventTracker, useCycle, useUser, useMember } from "@/hooks/store"; +import { useEventTracker, useCycle, useUser, useMember, useIssues } from "@/hooks/store"; // services import { CycleService } from "@/services/cycle.service"; @@ -191,25 +192,36 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { } }; - // TODO: refactor this - // const handleFiltersUpdate = useCallback( - // (key: keyof IIssueFilterOptions, value: string | string[]) => { - // if (!workspaceSlug || !projectId) return; - // const newValues = issueFilters?.filters?.[key] ?? []; + const { + issuesFilter: { issueFilters, updateFilters }, + } = useIssues(EIssuesStoreType.CYCLE); - // if (Array.isArray(value)) { - // value.forEach((val) => { - // if (!newValues.includes(val)) newValues.push(val); - // }); - // } else { - // if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); - // else newValues.push(value); - // } + const handleFiltersUpdate = useCallback( + (key: keyof IIssueFilterOptions, value: string | string[]) => { + if (!workspaceSlug || !projectId) return; + const newValues = issueFilters?.filters?.[key] ?? []; - // updateFilters(workspaceSlug.toString(), projectId.toString(), EFilterType.FILTERS, { [key]: newValues }, cycleId); - // }, - // [workspaceSlug, projectId, cycleId, issueFilters, updateFilters] - // ); + if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom + value.forEach((val) => { + if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); + }); + } else { + if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); + else newValues.push(value); + } + + updateFilters( + workspaceSlug.toString(), + projectId.toString(), + EIssueFilterType.FILTERS, + { [key]: newValues }, + cycleId + ); + }, + [workspaceSlug, projectId, cycleId, issueFilters, updateFilters] + ); const cycleStatus = cycleDetails?.status?.toLocaleLowerCase(); const isCompleted = cycleStatus === "completed"; @@ -251,8 +263,8 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { ? "0 Issue" : `${cycleDetails.progress_snapshot.completed_issues}/${cycleDetails.progress_snapshot.total_issues}` : cycleDetails.total_issues === 0 - ? "0 Issue" - : `${cycleDetails.completed_issues}/${cycleDetails.total_issues}`; + ? "0 Issue" + : `${cycleDetails.completed_issues}/${cycleDetails.total_issues}`; const daysLeft = findHowManyDaysLeft(cycleDetails.end_date); @@ -551,6 +563,9 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { }} totalIssues={cycleDetails.progress_snapshot.total_issues} isPeekView={Boolean(peekCycle)} + isCompleted={isCompleted} + filters={issueFilters} + handleFiltersUpdate={handleFiltersUpdate} />
)} @@ -570,6 +585,9 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { }} totalIssues={cycleDetails.total_issues} isPeekView={Boolean(peekCycle)} + isCompleted={isCompleted} + filters={issueFilters} + handleFiltersUpdate={handleFiltersUpdate} />
)} diff --git a/web/components/modules/sidebar.tsx b/web/components/modules/sidebar.tsx index f219aeb95..91d69c2e1 100644 --- a/web/components/modules/sidebar.tsx +++ b/web/components/modules/sidebar.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; import { Controller, useForm } from "react-hook-form"; @@ -15,7 +15,7 @@ import { UserCircle2, } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; -import { ILinkDetails, IModule, ModuleLink } from "@plane/types"; +import { IIssueFilterOptions, ILinkDetails, IModule, ModuleLink } from "@plane/types"; // ui import { CustomMenu, @@ -41,13 +41,14 @@ import { MODULE_LINK_UPDATED, MODULE_UPDATED, } from "@/constants/event-tracker"; +import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { MODULE_STATUS } from "@/constants/module"; import { EUserProjectRoles } from "@/constants/project"; // helpers import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper"; import { copyUrlToClipboard } from "@/helpers/string.helper"; // hooks -import { useModule, useUser, useEventTracker } from "@/hooks/store"; +import { useModule, useUser, useEventTracker, useIssues } from "@/hooks/store"; // types const defaultValues: Partial = { @@ -82,6 +83,9 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { const { getModuleById, updateModuleDetails, createModuleLink, updateModuleLink, deleteModuleLink, restoreModule } = useModule(); const { setTrackElement, captureModuleEvent, captureEvent } = useEventTracker(); + const { + issuesFilter: { issueFilters, updateFilters }, + } = useIssues(EIssuesStoreType.MODULE); const moduleDetails = getModuleById(moduleId); const moduleState = moduleDetails?.status?.toLocaleLowerCase(); @@ -245,6 +249,33 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { }); }, [moduleDetails, reset]); + const handleFiltersUpdate = useCallback( + (key: keyof IIssueFilterOptions, value: string | string[]) => { + if (!workspaceSlug || !projectId) return; + const newValues = issueFilters?.filters?.[key] ?? []; + + if (Array.isArray(value)) { + // this validation is majorly for the filter start_date, target_date custom + value.forEach((val) => { + if (!newValues.includes(val)) newValues.push(val); + else newValues.splice(newValues.indexOf(val), 1); + }); + } else { + if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1); + else newValues.push(value); + } + + updateFilters( + workspaceSlug.toString(), + projectId.toString(), + EIssueFilterType.FILTERS, + { [key]: newValues }, + moduleId + ); + }, + [workspaceSlug, projectId, moduleId, issueFilters, updateFilters] + ); + const startDate = getDate(moduleDetails?.start_date); const endDate = getDate(moduleDetails?.target_date); const isStartValid = startDate && startDate <= new Date(); @@ -599,6 +630,8 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { totalIssues={moduleDetails.total_issues} module={moduleDetails} isPeekView={Boolean(peekModule)} + filters={issueFilters} + handleFiltersUpdate={handleFiltersUpdate} /> )} From 80461e6484de47b6c80f347cb7d539f736ff7722 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:21:08 +0530 Subject: [PATCH 03/20] chore: filter member option sorting improvement (#4285) --- web/components/modules/dropdowns/filters/lead.tsx | 13 ++++++++----- .../modules/dropdowns/filters/members.tsx | 10 ++++++---- web/components/pages/list/filters/created-by.tsx | 9 ++++++--- web/components/project/dropdowns/filters/lead.tsx | 10 ++++++---- .../project/dropdowns/filters/members.tsx | 10 ++++++---- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/web/components/modules/dropdowns/filters/lead.tsx b/web/components/modules/dropdowns/filters/lead.tsx index b8dc8a9d4..9fa1ea5d5 100644 --- a/web/components/modules/dropdowns/filters/lead.tsx +++ b/web/components/modules/dropdowns/filters/lead.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite"; // hooks import { Avatar, Loader } from "@plane/ui"; import { FilterHeader, FilterOption } from "@/components/issues"; -import { useMember } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; // components // ui @@ -22,19 +22,22 @@ export const FilterLead: React.FC = observer((props: Props) => { const [previewEnabled, setPreviewEnabled] = useState(true); // store hooks const { getUserDetails } = useMember(); + const { currentUser } = useUser(); const appliedFiltersCount = appliedFilters?.length ?? 0; const sortedOptions = useMemo(() => { - const filteredOptions = (memberIds || []).filter( - (memberId) => getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) + const filteredOptions = (memberIds || []).filter((memberId) => + getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) ); return sortBy(filteredOptions, [ (memberId) => !(appliedFilters ?? []).includes(memberId), + (memberId) => memberId !== currentUser?.id, (memberId) => getUserDetails(memberId)?.display_name.toLowerCase(), ]); - }, [appliedFilters, getUserDetails, memberIds, , searchQuery]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchQuery]); const handleViewToggle = () => { if (!sortedOptions) return; @@ -65,7 +68,7 @@ export const FilterLead: React.FC = observer((props: Props) => { isChecked={appliedFilters?.includes(member.id) ? true : false} onClick={() => handleUpdate(member.id)} icon={} - title={member.display_name} + title={currentUser?.id === member.id ? "You" : member?.display_name} /> ); })} diff --git a/web/components/modules/dropdowns/filters/members.tsx b/web/components/modules/dropdowns/filters/members.tsx index 3db1f5d04..1a23d0c3e 100644 --- a/web/components/modules/dropdowns/filters/members.tsx +++ b/web/components/modules/dropdowns/filters/members.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite"; // hooks import { Avatar, Loader } from "@plane/ui"; import { FilterHeader, FilterOption } from "@/components/issues"; -import { useMember } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; // components // ui @@ -22,16 +22,18 @@ export const FilterMembers: React.FC = observer((props: Props) => { const [previewEnabled, setPreviewEnabled] = useState(true); // store hooks const { getUserDetails } = useMember(); + const { currentUser } = useUser(); const appliedFiltersCount = appliedFilters?.length ?? 0; const sortedOptions = useMemo(() => { - const filteredOptions = (memberIds || []).filter( - (memberId) => getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) + const filteredOptions = (memberIds || []).filter((memberId) => + getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) ); return sortBy(filteredOptions, [ (memberId) => !(appliedFilters ?? []).includes(memberId), + (memberId) => memberId !== currentUser?.id, (memberId) => getUserDetails(memberId)?.display_name.toLowerCase(), ]); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -66,7 +68,7 @@ export const FilterMembers: React.FC = observer((props: Props) => { isChecked={appliedFilters?.includes(member.id) ? true : false} onClick={() => handleUpdate(member.id)} icon={} - title={member.display_name} + title={currentUser?.id === member.id ? "You" : member?.display_name} /> ); })} diff --git a/web/components/pages/list/filters/created-by.tsx b/web/components/pages/list/filters/created-by.tsx index bddacc550..a90d8bd14 100644 --- a/web/components/pages/list/filters/created-by.tsx +++ b/web/components/pages/list/filters/created-by.tsx @@ -6,7 +6,7 @@ import { Avatar, Loader } from "@plane/ui"; // components import { FilterHeader, FilterOption } from "@/components/issues"; // hooks -import { useMember } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; type Props = { appliedFilters: string[] | null; @@ -22,6 +22,7 @@ export const FilterCreatedBy: React.FC = observer((props: Props) => { const [previewEnabled, setPreviewEnabled] = useState(true); // store hooks const { getUserDetails } = useMember(); + const { currentUser } = useUser(); const appliedFiltersCount = appliedFilters?.length ?? 0; @@ -32,9 +33,11 @@ export const FilterCreatedBy: React.FC = observer((props: Props) => { return sortBy(filteredOptions, [ (memberId) => !(appliedFilters ?? []).includes(memberId), + (memberId) => memberId !== currentUser?.id, (memberId) => getUserDetails(memberId)?.display_name.toLowerCase(), ]); - }, [appliedFilters, getUserDetails, memberIds, searchQuery]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchQuery]); const handleViewToggle = () => { if (!sortedOptions) return; @@ -65,7 +68,7 @@ export const FilterCreatedBy: React.FC = observer((props: Props) => { isChecked={appliedFilters?.includes(member.id) ? true : false} onClick={() => handleUpdate(member.id)} icon={} - title={member.display_name} + title={currentUser?.id === member.id ? "You" : member?.display_name} /> ); })} diff --git a/web/components/project/dropdowns/filters/lead.tsx b/web/components/project/dropdowns/filters/lead.tsx index 2bfea97df..9fa1ea5d5 100644 --- a/web/components/project/dropdowns/filters/lead.tsx +++ b/web/components/project/dropdowns/filters/lead.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite"; // hooks import { Avatar, Loader } from "@plane/ui"; import { FilterHeader, FilterOption } from "@/components/issues"; -import { useMember } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; // components // ui @@ -22,16 +22,18 @@ export const FilterLead: React.FC = observer((props: Props) => { const [previewEnabled, setPreviewEnabled] = useState(true); // store hooks const { getUserDetails } = useMember(); + const { currentUser } = useUser(); const appliedFiltersCount = appliedFilters?.length ?? 0; const sortedOptions = useMemo(() => { - const filteredOptions = (memberIds || []).filter( - (memberId) => getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) + const filteredOptions = (memberIds || []).filter((memberId) => + getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) ); return sortBy(filteredOptions, [ (memberId) => !(appliedFilters ?? []).includes(memberId), + (memberId) => memberId !== currentUser?.id, (memberId) => getUserDetails(memberId)?.display_name.toLowerCase(), ]); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -66,7 +68,7 @@ export const FilterLead: React.FC = observer((props: Props) => { isChecked={appliedFilters?.includes(member.id) ? true : false} onClick={() => handleUpdate(member.id)} icon={} - title={member.display_name} + title={currentUser?.id === member.id ? "You" : member?.display_name} /> ); })} diff --git a/web/components/project/dropdowns/filters/members.tsx b/web/components/project/dropdowns/filters/members.tsx index 3db1f5d04..1a23d0c3e 100644 --- a/web/components/project/dropdowns/filters/members.tsx +++ b/web/components/project/dropdowns/filters/members.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite"; // hooks import { Avatar, Loader } from "@plane/ui"; import { FilterHeader, FilterOption } from "@/components/issues"; -import { useMember } from "@/hooks/store"; +import { useMember, useUser } from "@/hooks/store"; // components // ui @@ -22,16 +22,18 @@ export const FilterMembers: React.FC = observer((props: Props) => { const [previewEnabled, setPreviewEnabled] = useState(true); // store hooks const { getUserDetails } = useMember(); + const { currentUser } = useUser(); const appliedFiltersCount = appliedFilters?.length ?? 0; const sortedOptions = useMemo(() => { - const filteredOptions = (memberIds || []).filter( - (memberId) => getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) + const filteredOptions = (memberIds || []).filter((memberId) => + getUserDetails(memberId)?.display_name.toLowerCase().includes(searchQuery.toLowerCase()) ); return sortBy(filteredOptions, [ (memberId) => !(appliedFilters ?? []).includes(memberId), + (memberId) => memberId !== currentUser?.id, (memberId) => getUserDetails(memberId)?.display_name.toLowerCase(), ]); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -66,7 +68,7 @@ export const FilterMembers: React.FC = observer((props: Props) => { isChecked={appliedFilters?.includes(member.id) ? true : false} onClick={() => handleUpdate(member.id)} icon={} - title={member.display_name} + title={currentUser?.id === member.id ? "You" : member?.display_name} /> ); })} From f2fa6452c9278baaf8ff5c599d196d561dd37e19 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:56:51 +0530 Subject: [PATCH 04/20] fix: cycle and module quick action z-index (#4293) --- web/components/cycles/board/cycles-board-card.tsx | 2 +- web/components/cycles/list/cycles-list-item.tsx | 2 +- web/components/modules/module-card-item.tsx | 2 +- web/components/modules/module-list-item.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/components/cycles/board/cycles-board-card.tsx b/web/components/cycles/board/cycles-board-card.tsx index a7ea62946..ea659569c 100644 --- a/web/components/cycles/board/cycles-board-card.tsx +++ b/web/components/cycles/board/cycles-board-card.tsx @@ -235,7 +235,7 @@ export const CyclesBoardCard: FC = observer((props) => { -
+
{isEditingAllowed && ( { diff --git a/web/components/cycles/list/cycles-list-item.tsx b/web/components/cycles/list/cycles-list-item.tsx index a7194ecbd..a6262dfe7 100644 --- a/web/components/cycles/list/cycles-list-item.tsx +++ b/web/components/cycles/list/cycles-list-item.tsx @@ -202,7 +202,7 @@ export const CyclesListItem: FC = observer((props) => {
-
+
{currentCycle && (
= observer((props) => {
-
+
{isEditingAllowed && ( { diff --git a/web/components/modules/module-list-item.tsx b/web/components/modules/module-list-item.tsx index 152ad8ca3..6b2c8c2ba 100644 --- a/web/components/modules/module-list-item.tsx +++ b/web/components/modules/module-list-item.tsx @@ -175,7 +175,7 @@ export const ModuleListItem: React.FC = observer((props) => {
-
+
{moduleStatus && ( Date: Fri, 26 Apr 2024 18:27:32 +0530 Subject: [PATCH 05/20] chore: clear search term on escape key (#4289) --- web/components/command-palette/command-modal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/components/command-palette/command-modal.tsx b/web/components/command-palette/command-modal.tsx index aa36eabed..29734efc9 100644 --- a/web/components/command-palette/command-modal.tsx +++ b/web/components/command-palette/command-modal.tsx @@ -178,7 +178,9 @@ export const CommandModal: React.FC = observer(() => { return 0; }} onKeyDown={(e) => { - // when search is empty and page is undefined + // when search term is not empty, esc should clear the search term + if (e.key === "Escape" && searchTerm) setSearchTerm(""); + // when user tries to close the modal with esc if (e.key === "Escape" && !page && !searchTerm) closePalette(); From ad27184a91a72905a4b32a9f6b3ad7cea43d8475 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:29:18 +0530 Subject: [PATCH 06/20] [WEB-1072] fix: pages UI improvements (#4294) * fix: outline alignment * fix: textarea auto-resize logic --- packages/ui/src/form-fields/textarea.tsx | 2 +- .../ui/src/hooks/use-auto-resize-textarea.ts | 30 +++++++------------ .../editor/summary/heading-components.tsx | 6 ++-- web/components/pages/editor/title.tsx | 11 +++++-- web/components/pages/list/block.tsx | 2 +- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/ui/src/form-fields/textarea.tsx b/packages/ui/src/form-fields/textarea.tsx index 2c47a65f5..e6927a968 100644 --- a/packages/ui/src/form-fields/textarea.tsx +++ b/packages/ui/src/form-fields/textarea.tsx @@ -15,7 +15,7 @@ const TextArea = React.forwardRef((props, re // refs const textAreaRef = useRef(ref); // auto re-size - useAutoResizeTextArea(textAreaRef); + useAutoResizeTextArea(textAreaRef, value); return (