diff --git a/apps/web/ce/components/issues/issue-details/sidebar.tsx/date-alert.tsx b/apps/web/ce/components/issues/issue-details/sidebar/date-alert.tsx similarity index 100% rename from apps/web/ce/components/issues/issue-details/sidebar.tsx/date-alert.tsx rename to apps/web/ce/components/issues/issue-details/sidebar/date-alert.tsx diff --git a/apps/web/core/components/common/activity/activity-block.tsx b/apps/web/core/components/common/activity/activity-block.tsx index 1805dc304e4..5ed9e17beb2 100644 --- a/apps/web/core/components/common/activity/activity-block.tsx +++ b/apps/web/core/components/common/activity/activity-block.tsx @@ -12,7 +12,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os"; import { User } from "./user"; type TActivityBlockComponent = { - icon?: ReactNode; + icon?: FC<{ className?: string }>; activity: TWorkspaceBaseActivity; ends: "top" | "bottom" | undefined; children: ReactNode; @@ -20,19 +20,19 @@ type TActivityBlockComponent = { }; export function ActivityBlockComponent(props: TActivityBlockComponent) { - const { icon, activity, ends, children, customUserName } = props; + const { icon: Icon, activity, ends, children, customUserName } = props; // hooks const { isMobile } = usePlatformOS(); if (!activity) return <>; return (
-
- {icon ? icon : } +
+ {Icon ? : }
diff --git a/apps/web/core/components/common/activity/helper.tsx b/apps/web/core/components/common/activity/helper.tsx index 22bc3de1ae4..f0f0cb0cb56 100644 --- a/apps/web/core/components/common/activity/helper.tsx +++ b/apps/web/core/components/common/activity/helper.tsx @@ -1,9 +1,8 @@ -import type { ReactNode } from "react"; +import type { FC, ReactNode } from "react"; import { RotateCcw, Network, Link as LinkIcon, - Calendar, Inbox, AlignLeft, Paperclip, @@ -13,7 +12,6 @@ import { Hash, Clock, Bell, - LayoutGrid, GitBranch, Timer, ListTodo, @@ -24,54 +22,55 @@ import { import { ArchiveIcon, CycleIcon, - StatePropertyIcon, + DueDatePropertyIcon, + EstimatePropertyIcon, + GridLayoutIcon, IntakeIcon, + LabelPropertyIcon, + MembersPropertyIcon, ModuleIcon, PriorityPropertyIcon, StartDatePropertyIcon, - DueDatePropertyIcon, - LabelPropertyIcon, - MembersPropertyIcon, - EstimatePropertyIcon, + StatePropertyIcon, } from "@plane/propel/icons"; import { store } from "@/lib/store-context"; import type { TProjectActivity } from "@/plane-web/types"; type ActivityIconMap = { - [key: string]: ReactNode; + [key: string]: FC<{ className?: string }>; }; export const iconsMap: ActivityIconMap = { - priority: , - archived_at: , - restored: , - link: , - start_date: , - target_date: , - label: , - inbox: , - description: , - assignee: , - attachment: , - name: , - state: , - estimate: , - cycle: , - module: , - page: , - network: , - identifier: , - timezone: , - is_project_updates_enabled: , - is_epic_enabled: , - is_workflow_enabled: , - is_time_tracking_enabled: , - is_issue_type_enabled: , - default: , - module_view: , - cycle_view: , - issue_views_view: , - page_view: , - intake_view: , + priority: PriorityPropertyIcon, + archived_at: ArchiveIcon, + restored: RotateCcw, + link: LinkIcon, + start_date: StartDatePropertyIcon, + target_date: DueDatePropertyIcon, + label: LabelPropertyIcon, + inbox: Inbox, + description: AlignLeft, + assignee: MembersPropertyIcon, + attachment: Paperclip, + name: Type, + state: StatePropertyIcon, + estimate: EstimatePropertyIcon, + cycle: CycleIcon, + module: ModuleIcon, + page: FileText, + network: Globe, + identifier: Hash, + timezone: Clock, + is_project_updates_enabled: Bell, + is_epic_enabled: GridLayoutIcon, + is_workflow_enabled: GitBranch, + is_time_tracking_enabled: Timer, + is_issue_type_enabled: ListTodo, + default: Network, + module_view: ModuleIcon, + cycle_view: CycleIcon, + issue_views_view: Layers, + page_view: FileText, + intake_view: IntakeIcon, }; export const messages = (activity: TProjectActivity): { message: string | ReactNode; customUserName?: string } => { diff --git a/apps/web/core/components/common/layout/sidebar/property-list-item.tsx b/apps/web/core/components/common/layout/sidebar/property-list-item.tsx new file mode 100644 index 00000000000..4aae69e61f4 --- /dev/null +++ b/apps/web/core/components/common/layout/sidebar/property-list-item.tsx @@ -0,0 +1,23 @@ +import type { ReactNode } from "react"; + +type TSidebarPropertyListItemProps = { + icon: React.FC<{ className?: string }>; + label: string; + children: ReactNode; + appendElement?: ReactNode; +}; + +export function SidebarPropertyListItem(props: TSidebarPropertyListItemProps) { + const { icon: Icon, label, children, appendElement } = props; + + return ( +
+
+ + {label} + {appendElement} +
+
{children}
+
+ ); +} diff --git a/apps/web/core/components/issues/issue-detail-widgets/root.tsx b/apps/web/core/components/issues/issue-detail-widgets/root.tsx index d7a3518b6dd..44b5a76f71c 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/root.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/root.tsx @@ -30,7 +30,7 @@ export function IssueDetailWidgets(props: Props) { return ( <> -
+
+
+ ); } diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx index 8dbdad4faf4..8534e71710e 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/activity-filter.tsx @@ -3,7 +3,7 @@ import { Check, ListFilter } from "lucide-react"; // plane imports import type { TActivityFilters, TActivityFilterOption } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { Button } from "@plane/propel/button"; +import { IconButton } from "@plane/propel/icon-button"; import { PopoverMenu } from "@plane/ui"; // helper import { cn } from "@plane/utils"; @@ -24,12 +24,12 @@ export const ActivityFilter = observer(function ActivityFilter(props: TActivityF } className="relative"> - {t("common.filters")} + <> + {selectedFilters.length < filterOptions.length && ( )} - + } panelClassName="p-2 rounded-md border border-subtle bg-surface-1" data={filterOptions} diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/activity-block.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/activity-block.tsx index 95879e568d9..5cc9eea4443 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/activity-block.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/helpers/activity-block.tsx @@ -30,12 +30,12 @@ export function IssueActivityBlockComponent(props: TIssueActivityBlockComponent) if (!activity) return <>; return (
-
-
+
+
{icon ? icon : }
diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/root.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/root.tsx index 12eb17e3cb6..b6951acd7b3 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/root.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/root.tsx @@ -99,7 +99,7 @@ export const IssueActivity = observer(function IssueActivity(props: TIssueActivi if (!project) return <>; return ( -
+
{/* header */}
{t("common.activity")}
diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx index 1ae69db97dd..8e6a64e3124 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/sort-root.tsx @@ -2,32 +2,15 @@ import { memo } from "react"; import { ArrowUpWideNarrow, ArrowDownWideNarrow } from "lucide-react"; // plane package imports import { E_SORT_ORDER } from "@plane/constants"; -import { cn } from "@plane/utils"; -import { Button } from "@plane/propel/button"; +import { IconButton } from "@plane/propel/icon-button"; export type TActivitySortRoot = { sortOrder: E_SORT_ORDER; toggleSort: () => void; - className?: string; - iconClassName?: string; }; export const ActivitySortRoot = memo(function ActivitySortRoot(props: TActivitySortRoot) { - return ( - - ); + const SortIcon = props.sortOrder === E_SORT_ORDER.ASC ? ArrowUpWideNarrow : ArrowDownWideNarrow; + return ; }); ActivitySortRoot.displayName = "ActivitySortRoot"; diff --git a/apps/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx b/apps/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx index 7e919ee2193..471274b66d5 100644 --- a/apps/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx @@ -5,6 +5,7 @@ import { LinkIcon } from "lucide-react"; // plane imports import { WORK_ITEM_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; +import { IconButton } from "@plane/propel/icon-button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { Tooltip } from "@plane/propel/tooltip"; import { EIssuesStoreType } from "@plane/types"; @@ -149,19 +150,13 @@ export const IssueDetailQuickActions = observer(function IssueDetailQuickActions return ( <>
-
+
{currentUser && !issue?.archived_at && ( )} -
+
- + +
{issueLinks.map((linkId) => ( ) : (
-
+
{t("common.properties")}
- {/* TODO: render properties using a common component */}
-
-
- - {t("common.state")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { state_id: val })} projectId={projectId?.toString() ?? ""} disabled={!isEditable} buttonVariant="transparent-with-text" - className="group w-3/5 flex-grow" + className="group w-full grow" buttonContainerClassName="w-full text-left" buttonClassName="text-body-xs-regular" dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ -
-
- - {t("common.assignees")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { assignee_ids: val })} @@ -115,49 +107,35 @@ export const IssueDetailsSidebar = observer(function IssueDetailsSidebar(props: placeholder={t("issue.add.assignee")} multiple buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"} - className="group w-3/5 flex-grow" + className="group w-full grow" buttonContainerClassName="w-full text-left" buttonClassName={`text-body-xs-regular justify-between ${issue?.assignee_ids?.length > 0 ? "" : "text-placeholder"}`} hideIcon={issue.assignee_ids?.length === 0} dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ -
-
- - {t("common.priority")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { priority: val })} disabled={!isEditable} buttonVariant="border-with-text" - className="w-3/5 flex-grow rounded-sm px-2 hover:bg-layer-1" + className="w-full grow" buttonContainerClassName="w-full text-left" buttonClassName="w-min h-auto whitespace-nowrap" /> -
+ {createdByDetails && ( -
-
- - {t("common.created_by")} -
-
- - {createdByDetails?.display_name} -
-
+ + + {createdByDetails?.display_name} + )} -
-
- - {t("common.order_by.start_date")} -
+ -
+ -
-
- - {t("common.order_by.due_date")} -
+
{issue.target_date && }
-
+ {projectId && areEstimateEnabledByProjectId(projectId) && ( -
-
- - {t("common.estimate")} -
+ @@ -225,7 +191,7 @@ export const IssueDetailsSidebar = observer(function IssueDetailsSidebar(props: projectId={projectId} disabled={!isEditable} buttonVariant="transparent-with-text" - className="group w-3/5 flex-grow" + className="group w-full grow" buttonContainerClassName="w-full text-left" buttonClassName={`text-body-xs-regular ${issue?.estimate_point !== null ? "" : "text-placeholder"}`} placeholder={t("common.none")} @@ -233,73 +199,58 @@ export const IssueDetailsSidebar = observer(function IssueDetailsSidebar(props: dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ )} {projectDetails?.module_view && ( -
-
- - {t("common.modules")} -
+ -
+ )} {projectDetails?.cycle_view && ( -
-
- - {t("common.cycle")} - -
+ } + > -
+ )} -
-
- - {t("common.parent")} -
+ -
+ -
-
- - {t("common.labels")} -
-
- -
-
+ + + {loading ? ( diff --git a/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/issue-detail.tsx b/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/issue-detail.tsx index 3e011c5efb7..2df94630123 100644 --- a/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/issue-detail.tsx +++ b/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/issue-detail.tsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { omit } from "lodash-es"; import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; +import { Ellipsis } from "lucide-react"; // plane imports import { ARCHIVABLE_STATE_GROUPS, @@ -29,6 +30,7 @@ import { CreateUpdateIssueModal } from "../../issue-modal/modal"; import type { IQuickActionProps } from "../list/list-view-types"; import type { MenuItemFactoryProps } from "./helper"; import { useWorkItemDetailMenuItems } from "./helper"; +import { IconButton } from "@plane/propel/icon-button"; type TWorkItemDetailQuickActionProps = IQuickActionProps & { toggleEditIssueModal?: (value: boolean) => void; @@ -47,7 +49,6 @@ export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickA handleUpdate, handleArchive, handleRestore, - customActionButton, portalElement, readOnly = false, placements = "bottom-end", @@ -243,7 +244,7 @@ export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickA } portalElement={portalElement} menuItemsClassName="z-[14]" maxHeight="lg" diff --git a/apps/web/core/components/issues/peek-overview/properties.tsx b/apps/web/core/components/issues/peek-overview/properties.tsx index 97f057b636d..6aecfa6f317 100644 --- a/apps/web/core/components/issues/peek-overview/properties.tsx +++ b/apps/web/core/components/issues/peek-overview/properties.tsx @@ -24,6 +24,7 @@ import { ButtonAvatars } from "@/components/dropdowns/member/avatar"; import { MemberDropdown } from "@/components/dropdowns/member/dropdown"; import { PriorityDropdown } from "@/components/dropdowns/priority"; import { StateDropdown } from "@/components/dropdowns/state/dropdown"; +import { SidebarPropertyListItem } from "@/components/common/layout/sidebar/property-list-item"; // helpers import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useMember } from "@/hooks/store/use-member"; @@ -32,8 +33,8 @@ import { useProjectState } from "@/hooks/store/use-project-state"; // plane web components import { WorkItemAdditionalSidebarProperties } from "@/plane-web/components/issues/issue-details/additional-properties"; import { IssueParentSelectRoot } from "@/plane-web/components/issues/issue-details/parent-select-root"; +import { DateAlert } from "@/plane-web/components/issues/issue-details/sidebar/date-alert"; import { TransferHopInfo } from "@/plane-web/components/issues/issue-details/sidebar/transfer-hop-info"; -import { DateAlert } from "@/plane-web/components/issues/issue-details/sidebar.tsx/date-alert"; import { IssueWorklogProperty } from "@/plane-web/components/issues/worklog/property"; import type { TIssueOperations } from "../issue-detail"; import { IssueCycleSelect } from "../issue-detail/cycle-select"; @@ -75,34 +76,23 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p return (
{t("common.properties")}
- {/* TODO: render properties using a common component */}
- {/* state */} -
-
- - {t("common.state")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { state_id: val })} projectId={projectId} disabled={disabled} buttonVariant="transparent-with-text" - className="w-3/4 flex-grow group" + className="w-full grow group" buttonContainerClassName="w-full text-left" buttonClassName="text-body-xs-regular" dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ - {/* assignee */} -
-
- - {t("common.assignees")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { assignee_ids: val })} @@ -111,57 +101,40 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p placeholder={t("issue.add.assignee")} multiple buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"} - className="w-3/4 flex-grow group" + className="w-full grow group" buttonContainerClassName="w-full text-left" buttonClassName={`text-body-xs-regular justify-between ${issue?.assignee_ids?.length > 0 ? "" : "text-placeholder"}`} hideIcon={issue.assignee_ids?.length === 0} dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ - {/* priority */} -
-
- - {t("common.priority")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { priority: val })} disabled={disabled} buttonVariant="border-with-text" - className="w-3/4 flex-grow rounded-sm px-2 hover:bg-layer-1 group" + className="w-full grow group" buttonContainerClassName="w-full text-left" buttonClassName="w-min h-auto whitespace-nowrap" /> -
+ - {/* created by */} {createdByDetails && ( -
-
- - {t("common.created_by")} -
-
- - - {createdByDetails?.display_name.includes("-intake") ? "Plane" : createdByDetails?.display_name} - -
-
+ + + + {createdByDetails?.display_name.includes("-intake") ? "Plane" : createdByDetails?.display_name} + + )} - {/* start date */} -
-
- - {t("common.order_by.start_date")} -
+ @@ -173,22 +146,15 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p buttonVariant="transparent-with-text" maxDate={maxDate ?? undefined} disabled={disabled} - className="w-3/4 flex-grow group" + className="w-full grow group" buttonContainerClassName="w-full text-left" buttonClassName={`text-body-xs-regular ${issue?.start_date ? "" : "text-placeholder"}`} hideIcon clearIconClassName="h-3 w-3 hidden group-hover:inline" - // TODO: add this logic - // showPlaceholderIcon /> -
+ - {/* due date */} -
-
- - {t("common.order_by.due_date")} -
+
{issue.target_date && }
-
+ - {/* estimate */} {isEstimateEnabled && ( -
-
- - {t("common.estimate")} -
+ issueOperations.update(workspaceSlug, projectId, issueId, { estimate_point: val })} projectId={projectId} disabled={disabled} buttonVariant="transparent-with-text" - className="w-3/4 flex-grow group" + className="w-full grow group" buttonContainerClassName="w-full text-left" buttonClassName={`text-body-xs-regular ${issue?.estimate_point !== undefined ? "" : "text-placeholder"}`} placeholder="None" @@ -237,70 +196,53 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" /> -
+ )} {projectDetails?.module_view && ( -
-
- - {t("common.modules")} -
+ -
+ )} {projectDetails?.cycle_view && ( -
-
- - {t("common.cycle")} - -
+ } + > -
+ )} - {/* parent */} -
-
- -

{t("common.parent")}

-
+ -
+ - {/* label */} -
-
- - {t("common.labels")} -
-
- -
-
+ + + {["side-peek", "modal"].includes(peekMode) ? ( -
+