UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: glass shell и компактный composer открытой карточки внутреннего контура

This commit is contained in:
DCCONSTRUCTIONS 2026-04-19 14:21:23 +03:00
parent fc72c35e5a
commit 4ba06307ed
11 changed files with 138 additions and 29 deletions

View File

@ -26,6 +26,7 @@ type TCommentCreate = {
showToolbarInitially?: boolean; showToolbarInitially?: boolean;
projectId?: string; projectId?: string;
onSubmitCallback?: (elementId: string) => void; onSubmitCallback?: (elementId: string) => void;
appearance?: "default" | "issue-peek-compact";
}; };
// services // services
@ -39,6 +40,7 @@ export const CommentCreate = observer(function CommentCreate(props: TCommentCrea
showToolbarInitially = false, showToolbarInitially = false,
projectId, projectId,
onSubmitCallback, onSubmitCallback,
appearance = "default",
} = props; } = props;
// states // states
const [uploadedAssetIds, setUploadedAssetIds] = useState<string[]>([]); const [uploadedAssetIds, setUploadedAssetIds] = useState<string[]>([]);
@ -89,10 +91,13 @@ export const CommentCreate = observer(function CommentCreate(props: TCommentCrea
const commentHTML = watch("comment_html"); const commentHTML = watch("comment_html");
const isEmpty = isCommentEmpty(commentHTML ?? undefined); const isEmpty = isCommentEmpty(commentHTML ?? undefined);
const isCompactAppearance = appearance === "issue-peek-compact";
return ( return (
<div <div
className={cn("sticky bottom-0 z-[4] bg-surface-1 sm:static")} className={cn(
isCompactAppearance ? "relative z-[4] bg-transparent" : "sticky bottom-0 z-[4] bg-surface-1 sm:static"
)}
onKeyDown={(e) => { onKeyDown={(e) => {
if ( if (
e.key === "Enter" && e.key === "Enter" &&
@ -128,7 +133,6 @@ export const CommentCreate = observer(function CommentCreate(props: TCommentCrea
}} }}
ref={editorRef} ref={editorRef}
initialValue={value ?? "<p></p>"} initialValue={value ?? "<p></p>"}
containerClassName="min-h-min"
onChange={(comment_json, comment_html) => onChange(comment_html)} onChange={(comment_json, comment_html) => onChange(comment_html)}
accessSpecifier={accessValue ?? EIssueCommentAccessSpecifier.INTERNAL} accessSpecifier={accessValue ?? EIssueCommentAccessSpecifier.INTERNAL}
handleAccessChange={onAccessChange} handleAccessChange={onAccessChange}
@ -144,7 +148,16 @@ export const CommentCreate = observer(function CommentCreate(props: TCommentCrea
return asset_id; return asset_id;
}} }}
showToolbarInitially={showToolbarInitially} showToolbarInitially={showToolbarInitially}
parentClassName="p-2" parentClassName={cn(
isCompactAppearance
? "rounded-[20px] border border-subtle/70 bg-layer-2/75 p-4 backdrop-blur-xl"
: "p-2"
)}
variant={isCompactAppearance ? "full" : "full"}
toolbarMode={isCompactAppearance ? "compact-comment" : "default"}
showPlaceholderOnEmpty={isCompactAppearance}
editorClassName={cn(isCompactAppearance && "min-h-[112px]")}
containerClassName={cn(isCompactAppearance ? "min-h-[112px] border-none p-0" : "min-h-min")}
displayConfig={{ displayConfig={{
fontSize: "small-font", fontSize: "small-font",
}} }}

View File

@ -45,6 +45,7 @@ type LiteTextEditorWrapperProps = MakeOptional<
parentClassName?: string; parentClassName?: string;
editorClassName?: string; editorClassName?: string;
submitButtonText?: string; submitButtonText?: string;
toolbarMode?: "default" | "compact-comment";
} & ( } & (
| { | {
editable: false; editable: false;
@ -81,6 +82,7 @@ export const LiteTextEditor = React.forwardRef(function LiteTextEditor(
editorClassName = "", editorClassName = "",
showPlaceholderOnEmpty = true, showPlaceholderOnEmpty = true,
submitButtonText = "common.comment", submitButtonText = "common.comment",
toolbarMode = "default",
...rest ...rest
} = props; } = props;
// states // states
@ -217,6 +219,7 @@ export const LiteTextEditor = React.forwardRef(function LiteTextEditor(
editorRef={editorRef} editorRef={editorRef}
showSubmitButton={showSubmitButton} showSubmitButton={showSubmitButton}
submitButtonText={submitButtonText} submitButtonText={submitButtonText}
mode={toolbarMode}
/> />
</div> </div>
)} )}

View File

@ -5,6 +5,7 @@
*/ */
import React, { useEffect, useState, useCallback } from "react"; import React, { useEffect, useState, useCallback } from "react";
import { ArrowUp, Paperclip, SmilePlus } from "lucide-react";
import type { LucideIcon } from "lucide-react"; import type { LucideIcon } from "lucide-react";
import { EIssueCommentAccessSpecifier } from "@plane/constants"; import { EIssueCommentAccessSpecifier } from "@plane/constants";
@ -20,7 +21,7 @@ import { Tooltip } from "@plane/propel/tooltip";
// constants // constants
import { cn } from "@plane/utils"; import { cn } from "@plane/utils";
import type { ToolbarMenuItem } from "@/constants/editor"; import type { ToolbarMenuItem } from "@/constants/editor";
import { TOOLBAR_ITEMS } from "@/constants/editor"; import { IMAGE_ITEM, TOOLBAR_ITEMS } from "@/constants/editor";
// helpers // helpers
type Props = { type Props = {
@ -34,6 +35,7 @@ type Props = {
showSubmitButton: boolean; showSubmitButton: boolean;
editorRef: EditorRefApi | null; editorRef: EditorRefApi | null;
submitButtonText?: string; submitButtonText?: string;
mode?: "default" | "compact-comment";
}; };
type TCommentAccessType = { type TCommentAccessType = {
@ -56,6 +58,13 @@ const COMMENT_ACCESS_SPECIFIERS: TCommentAccessType[] = [
]; ];
const toolbarItems = TOOLBAR_ITEMS.lite; const toolbarItems = TOOLBAR_ITEMS.lite;
const EMOJI_ITEM: ToolbarMenuItem<"emoji"> = {
itemKey: "emoji",
renderKey: "emoji",
name: "Emoji",
icon: SmilePlus,
editors: ["lite", "document"],
};
export function IssueCommentToolbar(props: Props) { export function IssueCommentToolbar(props: Props) {
const { t } = useTranslation(); const { t } = useTranslation();
@ -70,6 +79,7 @@ export function IssueCommentToolbar(props: Props) {
showSubmitButton, showSubmitButton,
editorRef, editorRef,
submitButtonText = "common.comment", submitButtonText = "common.comment",
mode = "default",
} = props; } = props;
// State to manage active states of toolbar items // State to manage active states of toolbar items
const [activeStates, setActiveStates] = useState<Record<string, boolean>>({}); const [activeStates, setActiveStates] = useState<Record<string, boolean>>({});
@ -102,6 +112,43 @@ export function IssueCommentToolbar(props: Props) {
const isEditorReadyToDiscard = editorRef?.isEditorReadyToDiscard(); const isEditorReadyToDiscard = editorRef?.isEditorReadyToDiscard();
const isSubmitButtonDisabled = isCommentEmpty || !isEditorReadyToDiscard; const isSubmitButtonDisabled = isCommentEmpty || !isEditorReadyToDiscard;
if (mode === "compact-comment") {
return (
<div className="flex items-center justify-between gap-3 border-t border-subtle/70 pt-3">
<div className="flex items-center gap-2">
<Tooltip tooltipContent={t("common.attach")}>
<button
type="button"
onClick={() => executeCommand(IMAGE_ITEM)}
className="grid size-10 place-items-center rounded-[16px] bg-layer-1/85 text-secondary transition-colors hover:bg-layer-1 focus-visible:outline-none"
>
<Paperclip className="h-4 w-4" strokeWidth={2} />
</button>
</Tooltip>
<Tooltip tooltipContent="Emoji">
<button
type="button"
onClick={() => executeCommand(EMOJI_ITEM)}
className="grid size-10 place-items-center rounded-[16px] bg-layer-1/85 text-secondary transition-colors hover:bg-layer-1 focus-visible:outline-none"
>
<SmilePlus className="h-4 w-4" strokeWidth={2} />
</button>
</Tooltip>
</div>
{showSubmitButton && (
<button
type="button"
onClick={handleSubmit}
disabled={isSubmitButtonDisabled || isSubmitting}
className="grid size-10 place-items-center rounded-[16px] bg-accent-primary text-on-color transition-colors hover:bg-accent-primary-hover focus-visible:outline-none disabled:bg-layer-disabled disabled:text-on-color-disabled"
>
<ArrowUp className="h-4 w-4" strokeWidth={2} />
</button>
)}
</div>
);
}
return ( return (
<div className="flex h-9 w-full items-stretch gap-1.5 overflow-x-scroll bg-surface-2"> <div className="flex h-9 w-full items-stretch gap-1.5 overflow-x-scroll bg-surface-2">
{showAccessSpecifier && ( {showAccessSpecifier && (

View File

@ -10,6 +10,7 @@ import { useTranslation } from "@plane/i18n";
import { LinkIcon, ViewsIcon, RelationPropertyIcon } from "@plane/propel/icons"; import { LinkIcon, ViewsIcon, RelationPropertyIcon } from "@plane/propel/icons";
// plane imports // plane imports
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types"; import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
import { cn } from "@plane/utils";
// plane web imports // plane web imports
import { WorkItemAdditionalWidgetActionButtons } from "@/plane-web/components/issues/issue-detail-widgets/action-buttons"; import { WorkItemAdditionalWidgetActionButtons } from "@/plane-web/components/issues/issue-detail-widgets/action-buttons";
// local imports // local imports
@ -26,15 +27,16 @@ type Props = {
disabled: boolean; disabled: boolean;
issueServiceType: TIssueServiceType; issueServiceType: TIssueServiceType;
hideWidgets?: TWorkItemWidgets[]; hideWidgets?: TWorkItemWidgets[];
compactView?: boolean;
}; };
export function IssueDetailWidgetActionButtons(props: Props) { export function IssueDetailWidgetActionButtons(props: Props) {
const { workspaceSlug, projectId, issueId, disabled, issueServiceType, hideWidgets } = props; const { workspaceSlug, projectId, issueId, disabled, issueServiceType, hideWidgets, compactView = false } = props;
// translation // translation
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="flex flex-wrap items-center gap-2"> <div className={cn("flex flex-wrap items-center gap-2", compactView ? "justify-center" : "justify-start")}>
{!hideWidgets?.includes("sub-work-items") && ( {!hideWidgets?.includes("sub-work-items") && (
<SubIssuesActionButton <SubIssuesActionButton
issueId={issueId} issueId={issueId}
@ -43,6 +45,7 @@ export function IssueDetailWidgetActionButtons(props: Props) {
title={t("issue.add.sub_issue")} title={t("issue.add.sub_issue")}
icon={<ViewsIcon className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />} icon={<ViewsIcon className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled} disabled={disabled}
compactView={compactView}
/> />
} }
disabled={disabled} disabled={disabled}
@ -57,6 +60,7 @@ export function IssueDetailWidgetActionButtons(props: Props) {
title={t("issue.add.relation")} title={t("issue.add.relation")}
icon={<RelationPropertyIcon className="h-3.5 w-3.5 flex-shrink-0" />} icon={<RelationPropertyIcon className="h-3.5 w-3.5 flex-shrink-0" />}
disabled={disabled} disabled={disabled}
compactView={compactView}
/> />
} }
disabled={disabled} disabled={disabled}
@ -70,6 +74,7 @@ export function IssueDetailWidgetActionButtons(props: Props) {
title={t("issue.add.link")} title={t("issue.add.link")}
icon={<LinkIcon className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />} icon={<LinkIcon className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled} disabled={disabled}
compactView={compactView}
/> />
} }
disabled={disabled} disabled={disabled}
@ -86,6 +91,7 @@ export function IssueDetailWidgetActionButtons(props: Props) {
title={t("common.attach")} title={t("common.attach")}
icon={<Paperclip className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />} icon={<Paperclip className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled} disabled={disabled}
compactView={compactView}
/> />
} }
disabled={disabled} disabled={disabled}

View File

@ -20,6 +20,7 @@ type Props = {
renderWidgetModals?: boolean; renderWidgetModals?: boolean;
issueServiceType: TIssueServiceType; issueServiceType: TIssueServiceType;
hideWidgets?: TWorkItemWidgets[]; hideWidgets?: TWorkItemWidgets[];
compactView?: boolean;
}; };
export function IssueDetailWidgets(props: Props) { export function IssueDetailWidgets(props: Props) {
@ -31,6 +32,7 @@ export function IssueDetailWidgets(props: Props) {
renderWidgetModals = true, renderWidgetModals = true,
issueServiceType, issueServiceType,
hideWidgets, hideWidgets,
compactView = false,
} = props; } = props;
return ( return (
@ -43,6 +45,7 @@ export function IssueDetailWidgets(props: Props) {
disabled={disabled} disabled={disabled}
issueServiceType={issueServiceType} issueServiceType={issueServiceType}
hideWidgets={hideWidgets} hideWidgets={hideWidgets}
compactView={compactView}
/> />
<IssueDetailWidgetCollapsibles <IssueDetailWidgetCollapsibles
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}

View File

@ -7,17 +7,29 @@
import React from "react"; import React from "react";
// helpers // helpers
import { Button } from "@plane/propel/button"; import { Button } from "@plane/propel/button";
import { cn } from "@plane/utils";
type Props = { type Props = {
icon: React.ReactNode; icon: React.ReactNode;
title: string; title: string;
disabled?: boolean; disabled?: boolean;
compactView?: boolean;
}; };
export function IssueDetailWidgetButton(props: Props) { export function IssueDetailWidgetButton(props: Props) {
const { icon, title, disabled = false } = props; const { icon, title, disabled = false, compactView = false } = props;
return ( return (
<Button variant={"secondary"} disabled={disabled} size="lg"> <Button
variant={"secondary"}
disabled={disabled}
size="xl"
className={cn(
"border-transparent shadow-none focus-visible:outline-none",
compactView
? "h-10 rounded-[18px] bg-layer-2/80 px-4 backdrop-blur-xl hover:bg-layer-2-active"
: "rounded-md"
)}
>
{icon && icon} {icon && icon}
<span className="text-body-xs-medium">{title}</span> <span className="text-body-xs-medium">{title}</span>
</Button> </Button>

View File

@ -15,6 +15,7 @@ import { useLocalStorage } from "@plane/hooks";
import { useTranslation } from "@plane/i18n"; import { useTranslation } from "@plane/i18n";
//types //types
import type { TFileSignedURLResponse, TIssueComment } from "@plane/types"; import type { TFileSignedURLResponse, TIssueComment } from "@plane/types";
import { cn } from "@plane/utils";
// components // components
import { CommentCreate } from "@/components/comments/comment-create"; import { CommentCreate } from "@/components/comments/comment-create";
// hooks // hooks
@ -34,6 +35,7 @@ type TIssueActivity = {
issueId: string; issueId: string;
disabled?: boolean; disabled?: boolean;
isIntakeIssue?: boolean; isIntakeIssue?: boolean;
compactComposer?: boolean;
}; };
export type TActivityOperations = { export type TActivityOperations = {
@ -44,7 +46,7 @@ export type TActivityOperations = {
}; };
export const IssueActivity = observer(function IssueActivity(props: TIssueActivity) { export const IssueActivity = observer(function IssueActivity(props: TIssueActivity) {
const { workspaceSlug, projectId, issueId, disabled = false, isIntakeIssue = false } = props; const { workspaceSlug, projectId, issueId, disabled = false, isIntakeIssue = false, compactComposer = false } = props;
// i18n // i18n
const { t } = useTranslation(); const { t } = useTranslation();
// hooks // hooks
@ -92,15 +94,19 @@ export const IssueActivity = observer(function IssueActivity(props: TIssueActivi
const project = getProjectById(projectId); const project = getProjectById(projectId);
const renderCommentCreationBox = useMemo( const renderCommentCreationBox = useMemo(
() => ( () => (
<CommentCreate <div className={cn(compactComposer && "space-y-3 rounded-[24px] border border-subtle/70 bg-surface-2/70 p-4 backdrop-blur-xl")}>
workspaceSlug={workspaceSlug} {compactComposer && <div className="text-body-sm-medium text-primary">{t("issue.comments.placeholder")}</div>}
entityId={issueId} <CommentCreate
activityOperations={activityOperations} workspaceSlug={workspaceSlug}
showToolbarInitially entityId={issueId}
projectId={projectId} activityOperations={activityOperations}
/> showToolbarInitially
projectId={projectId}
appearance={compactComposer ? "issue-peek-compact" : "default"}
/>
</div>
), ),
[workspaceSlug, issueId, activityOperations, projectId] [workspaceSlug, issueId, activityOperations, projectId, compactComposer, t]
); );
if (!project) return <></>; if (!project) return <></>;

View File

@ -16,6 +16,7 @@ import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EIssueServiceType } from "@plane/types"; import { EIssueServiceType } from "@plane/types";
import { Loader } from "@plane/ui"; import { Loader } from "@plane/ui";
import { cn } from "@plane/utils";
// hooks // hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useUserPermissions } from "@/hooks/store/user"; import { useUserPermissions } from "@/hooks/store/user";
@ -25,10 +26,11 @@ export type TIssueSubscription = {
projectId: string; projectId: string;
issueId: string; issueId: string;
serviceType?: EIssueServiceType; serviceType?: EIssueServiceType;
buttonClassName?: string;
}; };
export const IssueSubscription = observer(function IssueSubscription(props: TIssueSubscription) { export const IssueSubscription = observer(function IssueSubscription(props: TIssueSubscription) {
const { workspaceSlug, projectId, issueId, serviceType = EIssueServiceType.ISSUES } = props; const { workspaceSlug, projectId, issueId, serviceType = EIssueServiceType.ISSUES, buttonClassName } = props;
const { t } = useTranslation(); const { t } = useTranslation();
// hooks // hooks
const { const {
@ -84,7 +86,7 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
<Button <Button
prependIcon={isSubscribed ? <BellOff /> : <Bell className="h-3 w-3" />} prependIcon={isSubscribed ? <BellOff /> : <Bell className="h-3 w-3" />}
variant="secondary" variant="secondary"
className="hover:!bg-accent-primary/20" className={cn("hover:!bg-accent-primary/20", buttonClassName)}
onClick={handleSubscription} onClick={handleSubscription}
disabled={!isEditable || loading} disabled={!isEditable || loading}
size="lg" size="lg"

View File

@ -37,6 +37,7 @@ type TWorkItemDetailQuickActionProps = IQuickActionProps & {
toggleDuplicateIssueModal?: (value: boolean) => void; toggleDuplicateIssueModal?: (value: boolean) => void;
toggleArchiveIssueModal?: (value: boolean) => void; toggleArchiveIssueModal?: (value: boolean) => void;
isPeekMode?: boolean; isPeekMode?: boolean;
buttonClassName?: string;
}; };
export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickActions( export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickActions(
@ -57,6 +58,7 @@ export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickA
toggleDuplicateIssueModal, toggleDuplicateIssueModal,
toggleArchiveIssueModal, toggleArchiveIssueModal,
isPeekMode = false, isPeekMode = false,
buttonClassName,
} = props; } = props;
// router // router
const { workspaceSlug } = useParams(); const { workspaceSlug } = useParams();
@ -241,7 +243,7 @@ export const WorkItemDetailQuickActions = observer(function WorkItemDetailQuickA
<CustomMenu <CustomMenu
ellipsis ellipsis
placement={placements} placement={placements}
customButton={<IconButton size="lg" variant="secondary" icon={Ellipsis} />} customButton={<IconButton size="lg" variant="secondary" icon={Ellipsis} className={buttonClassName} />}
portalElement={portalElement} portalElement={portalElement}
menuItemsClassName="z-[14]" menuItemsClassName="z-[14]"
maxHeight="lg" maxHeight="lg"

View File

@ -154,8 +154,8 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
return ( return (
<div <div
className={`relative flex items-center justify-between p-4 ${ className={`relative flex items-center justify-between px-6 py-5 ${
currentMode?.key === "full-screen" ? "border-b border-subtle" : "" currentMode?.key === "full-screen" ? "border-b border-subtle/70" : ""
}`} }`}
> >
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@ -203,10 +203,21 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
<NameDescriptionUpdateStatus isSubmitting={isSubmitting} /> <NameDescriptionUpdateStatus isSubmitting={isSubmitting} />
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{currentUser && !isArchived && ( {currentUser && !isArchived && (
<IssueSubscription workspaceSlug={workspaceSlug} projectId={projectId} issueId={issueId} /> <IssueSubscription
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
buttonClassName="!h-10 rounded-[18px] border-transparent bg-layer-2/80 px-4 shadow-none backdrop-blur-xl hover:!bg-layer-2-active focus-visible:outline-none"
/>
)} )}
<Tooltip tooltipContent={t("common.actions.copy_link")} isMobile={isMobile}> <Tooltip tooltipContent={t("common.actions.copy_link")} isMobile={isMobile}>
<IconButton variant="secondary" size="lg" onClick={handleCopyText} icon={CopyLinkIcon} /> <IconButton
variant="secondary"
size="lg"
onClick={handleCopyText}
icon={CopyLinkIcon}
className="size-10 rounded-[18px] border-transparent bg-layer-2/80 shadow-none backdrop-blur-xl hover:bg-layer-2-active focus-visible:outline-none"
/>
</Tooltip> </Tooltip>
{issueDetails && ( {issueDetails && (
<WorkItemDetailQuickActions <WorkItemDetailQuickActions
@ -221,6 +232,7 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
toggleDuplicateIssueModal={toggleDuplicateIssueModal} toggleDuplicateIssueModal={toggleDuplicateIssueModal}
toggleEditIssueModal={toggleEditIssueModal} toggleEditIssueModal={toggleEditIssueModal}
isPeekMode isPeekMode
buttonClassName="size-10 rounded-[18px] border-transparent bg-layer-2/80 shadow-none backdrop-blur-xl hover:bg-layer-2-active focus-visible:outline-none"
/> />
)} )}
</div> </div>

View File

@ -120,12 +120,13 @@ export const IssueView = observer(function IssueView(props: IIssueView) {
const peekOverviewIssueClassName = cn( const peekOverviewIssueClassName = cn(
!embedIssue !embedIssue
? "absolute z-[25] flex flex-col overflow-hidden rounded-sm border border-subtle bg-surface-1 transition-all duration-300" ? "absolute z-[25] flex flex-col overflow-hidden border border-subtle/70 bg-surface-1/80 backdrop-blur-2xl transition-all duration-300"
: `h-full w-full`, : `h-full w-full`,
!embedIssue && { !embedIssue && {
"top-0 right-0 bottom-0 w-full border-0 border-l md:w-[50%]": peekMode === "side-peek", "top-3 right-3 bottom-3 w-[calc(100%-1.5rem)] resize-x rounded-[28px] border md:w-[50%] md:min-w-[640px] md:max-w-[calc(100vw-1.5rem)]":
"top-[8.33%] left-[8.33%] size-5/6": peekMode === "modal", peekMode === "side-peek",
"absolute inset-0 m-4": peekMode === "full-screen", "top-[8.33%] left-[8.33%] size-5/6 rounded-[28px]": peekMode === "modal",
"absolute inset-0 m-4 rounded-[28px]": peekMode === "full-screen",
} }
); );
@ -174,7 +175,7 @@ export const IssueView = observer(function IssueView(props: IIssueView) {
{/* content */} {/* content */}
<div className="vertical-scrollbar relative scrollbar-md h-full w-full overflow-hidden overflow-y-auto"> <div className="vertical-scrollbar relative scrollbar-md h-full w-full overflow-hidden overflow-y-auto">
{["side-peek", "modal"].includes(peekMode) ? ( {["side-peek", "modal"].includes(peekMode) ? (
<div className="relative flex flex-col gap-3 space-y-3 px-8 py-5"> <div className="relative flex flex-col gap-4 space-y-3 px-8 py-6">
<PeekOverviewIssueDetails <PeekOverviewIssueDetails
editorRef={editorRef} editorRef={editorRef}
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}
@ -193,6 +194,7 @@ export const IssueView = observer(function IssueView(props: IIssueView) {
projectId={projectId} projectId={projectId}
issueId={issueId} issueId={issueId}
disabled={disabled || is_archived} disabled={disabled || is_archived}
compactView
issueServiceType={EIssueServiceType.ISSUES} issueServiceType={EIssueServiceType.ISSUES}
/> />
</div> </div>
@ -210,6 +212,7 @@ export const IssueView = observer(function IssueView(props: IIssueView) {
projectId={projectId} projectId={projectId}
issueId={issueId} issueId={issueId}
disabled={is_archived} disabled={is_archived}
compactComposer
/> />
</div> </div>
) : ( ) : (