From 3454a1316374e1545c751a6169c2ac25f60da81e Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Wed, 2 Sep 2026 19:25:39 +0530 Subject: [PATCH 1/8] refactor: update collapsible components to use @makeplane/propel - Migrate collapsible components in issue detail widgets (attachments, links, relations, sub-issues) from @plane/ui to @makeplane/propel. - Adjust props and structure for consistency with new collapsible implementation. - Enhance title components to integrate action buttons and improve accessibility. - Refactor related components to streamline imports and improve code clarity. --- .../issue-detail-widgets/attachments/root.tsx | 28 ++++--- .../attachments/title.tsx | 41 ++-------- .../issue-detail-widgets/links/root.tsx | 20 +++-- .../issue-detail-widgets/links/title.tsx | 31 ++----- .../relations/content.tsx | 11 +-- .../issue-detail-widgets/relations/root.tsx | 20 +++-- .../issue-detail-widgets/relations/title.tsx | 31 ++----- .../sub-issues/issues-list/list-group.tsx | 81 +++++++++---------- .../issue-detail-widgets/sub-issues/root.tsx | 26 +++--- .../issue-detail-widgets/sub-issues/title.tsx | 45 ++++------- .../workspace/settings/members-list.tsx | 37 +++------ 11 files changed, 135 insertions(+), 236 deletions(-) diff --git a/apps/web/core/components/issues/issue-detail-widgets/attachments/root.tsx b/apps/web/core/components/issues/issue-detail-widgets/attachments/root.tsx index e1a94c7d79e..4a78463bbfa 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/attachments/root.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/attachments/root.tsx @@ -7,13 +7,14 @@ import React from "react"; import { observer } from "mobx-react"; // plane imports +import { Collapsible } from "@makeplane/propel/components/collapsible"; import type { TIssueServiceType } from "@plane/types"; -import { Collapsible } from "@plane/ui"; // hooks import { useIssueDetail } from "@/hooks/store/use-issue-detail"; // local imports import { IssueAttachmentsCollapsibleContent } from "./content"; import { IssueAttachmentsCollapsibleTitle } from "./title"; +import { IssueAttachmentActionButton } from "./quick-action-button"; type Props = { workspaceSlug: string; @@ -33,19 +34,20 @@ export const AttachmentsCollapsible = observer(function AttachmentsCollapsible(p return ( toggleOpenWidget("attachments")} - title={ - + open={isCollapsibleOpen} + onOpenChange={() => toggleOpenWidget("attachments")} + trigger={} + trailing={ + isCollapsibleOpen && !disabled ? ( + + ) : undefined } - buttonClassName="w-full" > ( + return ( + + {t("common.attachments")} -

{attachmentCount}

+

{attachmentCount}

- ), - [attachmentCount] - ); - - return ( - - ) - } - /> +
); }); diff --git a/apps/web/core/components/issues/issue-detail-widgets/links/root.tsx b/apps/web/core/components/issues/issue-detail-widgets/links/root.tsx index bd963868a2e..0f30f4e5287 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/links/root.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/links/root.tsx @@ -7,13 +7,14 @@ import React from "react"; import { observer } from "mobx-react"; // plane imports +import { Collapsible } from "@makeplane/propel/components/collapsible"; import type { TIssueServiceType } from "@plane/types"; -import { Collapsible } from "@plane/ui"; // hooks import { useIssueDetail } from "@/hooks/store/use-issue-detail"; // local imports import { IssueLinksCollapsibleContent } from "./content"; import { IssueLinksCollapsibleTitle } from "./title"; +import { IssueLinksActionButton } from "./quick-action-button"; type Props = { workspaceSlug: string; @@ -32,17 +33,14 @@ export const LinksCollapsible = observer(function LinksCollapsible(props: Props) return ( toggleOpenWidget("links")} - title={ - + open={isCollapsibleOpen} + onOpenChange={() => toggleOpenWidget("links")} + trigger={} + trailing={ + isCollapsibleOpen && !disabled ? ( + + ) : undefined } - buttonClassName="w-full" > ( + return ( + + {t("common.links")} -

{linksCount}

+

{linksCount}

- ), - [linksCount] - ); - - return ( - - } - /> +
); }); diff --git a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx index b552380d184..e141be534bc 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx @@ -7,10 +7,10 @@ import { useState } from "react"; import { observer } from "mobx-react"; // plane imports +import { Collapsible } from "@makeplane/propel/components/collapsible"; import { useTranslation } from "@plane/i18n"; import type { TIssue, TIssueServiceType, TIssueRelationTypes } from "@plane/types"; import { EIssueServiceType } from "@plane/types"; -import { Collapsible } from "@plane/ui"; // components import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal"; import { useTimeLineRelationOptions } from "@/components/relations"; @@ -137,14 +137,9 @@ export const RelationsCollapsibleContent = observer(function RelationsCollapsibl {filteredRelationsArray.map((relation) => (
- {relation.icon ? relation.icon(14) : null} - {relation.label} -
- } defaultOpen + icon={relation.icon ? relation.icon(14) : undefined} + trigger={{relation.label}} > toggleOpenWidget("relations")} - title={ - + open={isCollapsibleOpen} + onOpenChange={() => toggleOpenWidget("relations")} + trigger={} + trailing={ + isCollapsibleOpen && !disabled ? ( + + ) : undefined } - buttonClassName="w-full" > ( + return ( + + {t("common.relations")} -

{relationsCount}

+

{relationsCount}

- ), - [relationsCount] - ); - - return ( - - } - /> +
); }); diff --git a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx index b76d7241002..f63f4a41c7b 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx @@ -7,12 +7,10 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { CircleDashed } from "lucide-react"; +import { Collapsible } from "@makeplane/propel/components/collapsible"; import { ALL_ISSUES } from "@plane/constants"; -import { ChevronRightIcon } from "@plane/propel/icons"; import type { IGroupByColumn, TIssue, TIssueServiceType, TSubIssueOperations } from "@plane/types"; import { EIssuesStoreType } from "@plane/types"; -import { Collapsible } from "@plane/ui"; -import { cn } from "@plane/utils"; import { SubIssuesListItem } from "./list-item"; interface TSubIssuesListGroupProps { @@ -57,47 +55,42 @@ export const SubIssuesListGroup = observer(function SubIssuesListGroup(props: TS if (!workItemIds.length) return null; + const items = workItemIds?.map((workItemId) => ( + + )); + + if (isAllIssues) return <>{items}; + return ( - <> - setIsCollapsibleOpen(!isCollapsibleOpen)} - title={ - !isAllIssues && ( -
- -
- {group.icon ?? } -
- {group.name} - {workItemIds.length} -
- ) - } - buttonClassName={cn("hidden", !isAllIssues && "block")} - > - {workItemIds?.map((workItemId) => ( - - ))} -
- + setIsCollapsibleOpen(!isCollapsibleOpen)} + icon={ +
+ {group.icon ?? } +
+ } + trigger={ + <> + {group.name} + {workItemIds.length} + + } + > + {items} +
); }); diff --git a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/root.tsx b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/root.tsx index 4bc8c79690c..eac612e8d87 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/root.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/root.tsx @@ -7,13 +7,14 @@ import React from "react"; import { observer } from "mobx-react"; // plane imports +import { Collapsible } from "@makeplane/propel/components/collapsible"; import type { TIssueServiceType } from "@plane/types"; -import { Collapsible } from "@plane/ui"; // hooks import { useIssueDetail } from "@/hooks/store/use-issue-detail"; // local imports import { SubIssuesCollapsibleContent } from "./content"; import { SubIssuesCollapsibleTitle } from "./title"; +import { SubWorkItemTitleActions } from "./title-actions"; type Props = { workspaceSlug: string; @@ -32,18 +33,19 @@ export const SubIssuesCollapsible = observer(function SubIssuesCollapsible(props return ( toggleOpenWidget("sub-work-items")} - title={ - + open={isCollapsibleOpen} + onOpenChange={() => toggleOpenWidget("sub-work-items")} + trigger={} + trailing={ + isCollapsibleOpen ? ( + + ) : undefined } - buttonClassName="w-full" > - - - {completedCount}/{totalCount} {t("common.done")} - - - } - actionItemElement={ - + {issueServiceType === EIssueServiceType.EPICS ? t("issue.label", { count: 1 }) : t("common.sub_work_items")} + + - } - /> + + {completedCount}/{totalCount} {t("common.done")} + + + ); }); diff --git a/apps/web/core/components/workspace/settings/members-list.tsx b/apps/web/core/components/workspace/settings/members-list.tsx index 41b4bed3fb7..4de2bf41264 100644 --- a/apps/web/core/components/workspace/settings/members-list.tsx +++ b/apps/web/core/components/workspace/settings/members-list.tsx @@ -8,11 +8,9 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; -import { Disclosure } from "@headlessui/react"; // plane imports +import { Collapsible } from "@makeplane/propel/components/collapsible"; import { useTranslation } from "@plane/i18n"; -import { ChevronDownIcon } from "@plane/propel/icons"; -import { Collapsible } from "@plane/ui"; // components import { CountChip } from "@/components/common/count-chip"; import { MembersSettingsLoader } from "@/components/ui/loader/settings/members"; @@ -80,29 +78,20 @@ export const WorkspaceMembersList = observer(function WorkspaceMembersList(props {isAdmin && searchedInvitationsIds && searchedInvitationsIds.length > 0 && ( setShowPendingInvites((prev) => !prev)} - buttonClassName="w-full" - className="" - title={ -
-
-

{t("workspace_settings.settings.members.pending_invites")}

- {searchedInvitationsIds && ( - - )} -
{" "} - -
+ open={showPendingInvites} + onOpenChange={() => setShowPendingInvites((prev) => !prev)} + trigger={ + + {t("workspace_settings.settings.members.pending_invites")} + {searchedInvitationsIds && } + } > - -
- {searchedInvitationsIds?.map((invitationId) => ( - - ))} -
-
+
+ {searchedInvitationsIds?.map((invitationId) => ( + + ))} +
)} From 42843c4fd26aa1d70ade9f92a388182a45be47ec Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Wed, 2 Sep 2026 19:41:31 +0530 Subject: [PATCH 2/8] refactor: enhance icon rendering in relations component - Update the icon rendering logic in the RelationsCollapsibleContent component to apply additional styling using the cn utility. - Ensure that icons are wrapped in a styled span for consistent presentation and alignment. --- .../issues/issue-detail-widgets/relations/content.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx index e141be534bc..2508df9bff9 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx @@ -11,6 +11,7 @@ import { Collapsible } from "@makeplane/propel/components/collapsible"; import { useTranslation } from "@plane/i18n"; import type { TIssue, TIssueServiceType, TIssueRelationTypes } from "@plane/types"; import { EIssueServiceType } from "@plane/types"; +import { cn } from "@plane/utils"; // components import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal"; import { useTimeLineRelationOptions } from "@/components/relations"; @@ -138,7 +139,13 @@ export const RelationsCollapsibleContent = observer(function RelationsCollapsibl
+ {relation.icon(14)} + + ) : undefined + } trigger={{relation.label}} > Date: Wed, 2 Sep 2026 19:45:52 +0530 Subject: [PATCH 3/8] refactor: adjust layout of RelationIssueList in RelationsCollapsibleContent - Wrap RelationIssueList in a div to cancel the nested Collapsible's panel inset, ensuring proper alignment under the outer Relations collapsible. - Improve visual consistency by preventing stacking of insets in the UI. --- .../relations/content.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx index 2508df9bff9..043750fd305 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/relations/content.tsx @@ -148,15 +148,19 @@ export const RelationsCollapsibleContent = observer(function RelationsCollapsibl } trigger={{relation.label}} > - + {/* Cancels this nested Collapsible's own panel inset so rows realign under + the outer Relations collapsible's single inset instead of stacking two. */} +
+ +
))} From e54f3b516e41ae75ea6ac94f59404ca748e3441f Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Wed, 2 Sep 2026 19:48:05 +0530 Subject: [PATCH 4/8] refactor: improve layout of pending invitations in WorkspaceMembersList - Wrap the Collapsible component for pending invitations in a div to enhance layout and spacing. - Ensure consistent visual presentation by adjusting the structure of the component. --- .../workspace/settings/members-list.tsx | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/apps/web/core/components/workspace/settings/members-list.tsx b/apps/web/core/components/workspace/settings/members-list.tsx index 4de2bf41264..d41c9d9bf9f 100644 --- a/apps/web/core/components/workspace/settings/members-list.tsx +++ b/apps/web/core/components/workspace/settings/members-list.tsx @@ -77,22 +77,24 @@ export const WorkspaceMembersList = observer(function WorkspaceMembersList(props )} {isAdmin && searchedInvitationsIds && searchedInvitationsIds.length > 0 && ( - setShowPendingInvites((prev) => !prev)} - trigger={ - - {t("workspace_settings.settings.members.pending_invites")} - {searchedInvitationsIds && } - - } - > -
- {searchedInvitationsIds?.map((invitationId) => ( - - ))} -
-
+
+ setShowPendingInvites((prev) => !prev)} + trigger={ + + {t("workspace_settings.settings.members.pending_invites")} + {searchedInvitationsIds && } + + } + > +
+ {searchedInvitationsIds?.map((invitationId) => ( + + ))} +
+
+
)} ); From 341427afac6a586ceede093fa624c885c3a46f6d Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Wed, 2 Sep 2026 19:52:57 +0530 Subject: [PATCH 5/8] refactor: simplify onOpenChange handlers in collapsible components - Update the onOpenChange prop in SubIssuesListGroup and WorkspaceMembersList to directly use the state setter function, improving code clarity and reducing unnecessary function wrapping. --- .../issue-detail-widgets/sub-issues/issues-list/list-group.tsx | 2 +- apps/web/core/components/workspace/settings/members-list.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx index f63f4a41c7b..b8bd2c5424a 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx @@ -77,7 +77,7 @@ export const SubIssuesListGroup = observer(function SubIssuesListGroup(props: TS return ( setIsCollapsibleOpen(!isCollapsibleOpen)} + onOpenChange={setIsCollapsibleOpen} icon={
{group.icon ?? } diff --git a/apps/web/core/components/workspace/settings/members-list.tsx b/apps/web/core/components/workspace/settings/members-list.tsx index d41c9d9bf9f..99c75a9ce98 100644 --- a/apps/web/core/components/workspace/settings/members-list.tsx +++ b/apps/web/core/components/workspace/settings/members-list.tsx @@ -80,7 +80,7 @@ export const WorkspaceMembersList = observer(function WorkspaceMembersList(props
setShowPendingInvites((prev) => !prev)} + onOpenChange={setShowPendingInvites} trigger={ {t("workspace_settings.settings.members.pending_invites")} From 71591a446c43f2d0f91885e30da6391fdb43911f Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Wed, 2 Sep 2026 19:54:13 +0530 Subject: [PATCH 6/8] refactor: simplify mapping of work item IDs in SubIssuesListGroup - Remove optional chaining from the mapping of workItemIds to enhance code clarity and ensure consistent handling of the array. --- .../issue-detail-widgets/sub-issues/issues-list/list-group.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx index b8bd2c5424a..3b90c173ce6 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/list-group.tsx @@ -55,7 +55,7 @@ export const SubIssuesListGroup = observer(function SubIssuesListGroup(props: TS if (!workItemIds.length) return null; - const items = workItemIds?.map((workItemId) => ( + const items = workItemIds.map((workItemId) => ( Date: Thu, 3 Sep 2026 12:04:34 +0530 Subject: [PATCH 7/8] refactor: adjust padding in attachment list item and link list components - Update padding in the attachment list item for improved spacing and alignment. - Remove unnecessary padding from the link list component to streamline layout. --- .../components/issues/attachment/attachment-list-item.tsx | 4 ++-- .../core/components/issues/issue-detail/links/link-list.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/web/core/components/issues/attachment/attachment-list-item.tsx b/apps/web/core/components/issues/attachment/attachment-list-item.tsx index ed7319a6b8b..6f518fd81c1 100644 --- a/apps/web/core/components/issues/attachment/attachment-list-item.tsx +++ b/apps/web/core/components/issues/attachment/attachment-list-item.tsx @@ -60,14 +60,14 @@ export const IssueAttachmentsListItem = observer(function IssueAttachmentsListIt window.open(fileURL, "_blank"); }} > -
+
{fileIcon}

{`${fileName}.${fileExtension}`}

- {convertBytesToSize(attachment.attributes.size)} + {convertBytesToSize(attachment.attributes.size)}
diff --git a/apps/web/core/components/issues/issue-detail/links/link-list.tsx b/apps/web/core/components/issues/issue-detail/links/link-list.tsx index e691ecba381..937f7e3bd5f 100644 --- a/apps/web/core/components/issues/issue-detail/links/link-list.tsx +++ b/apps/web/core/components/issues/issue-detail/links/link-list.tsx @@ -35,7 +35,7 @@ export const LinkList = observer(function LinkList(props: TLinkList) { if (!issueLinks) return null; return ( -
+
{issueLinks.map((linkId) => ( Date: Thu, 3 Sep 2026 12:20:11 +0530 Subject: [PATCH 8/8] chore: update @makeplane/propel version in lockfile to 0.3.0 Align the pnpm-lock.yaml file to reflect the updated version of @makeplane/propel from 0.2.0 to 0.3.0 for consistency across importers. --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7e8251a913..c1091fa51f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -876,7 +876,7 @@ importers: version: 2.2.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@makeplane/propel': specifier: 'catalog:' - version: 0.2.0(@date-fns/tz@1.4.1)(@types/react@19.2.17)(date-fns@4.1.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.17) + version: 0.3.0(@date-fns/tz@1.4.1)(@types/react@19.2.17)(date-fns@4.1.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.1.17) '@plane/constants': specifier: workspace:* version: link:../../packages/constants