UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: исправление ширины карточек внешних контуров

This commit is contained in:
DCCONSTRUCTIONS 2026-04-21 08:03:03 +03:00
parent d3b4c0689c
commit ba34162eeb
10 changed files with 48 additions and 37 deletions

View File

@ -41,15 +41,15 @@ export const ExternalContoursBoardColumn = observer(function ExternalContoursBoa
: t("external_contours_page.board.empty.incoming_description");
return (
<section className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[28px] bg-surface-2/30">
<div className="flex items-center justify-between gap-3 border-b border-subtle/40 px-5 py-4">
<section className="flex h-full min-h-0 w-[350px] flex-shrink-0 flex-col">
<div className="flex items-center justify-between gap-3 py-1.5">
<div className="text-15 font-semibold text-primary">{title}</div>
<div className="rounded-full bg-white/5 px-2 py-1 text-12 font-semibold text-secondary">{totalCount}</div>
</div>
<div className="vertical-scrollbar scrollbar-md min-h-0 flex-1 overflow-y-auto p-4">
<div className="vertical-scrollbar scrollbar-md -mr-2 h-full min-h-[120px] flex-1 overflow-y-auto pr-2 pt-3">
{requestIds.length > 0 ? (
<div className="space-y-4">
<>
{requestIds.map((requestId) => {
const request = getRequestById(requestId);
if (!request) return null;
@ -65,7 +65,7 @@ export const ExternalContoursBoardColumn = observer(function ExternalContoursBoa
/>
);
})}
</div>
</>
) : (
<div className="flex h-full min-h-[18rem] items-center justify-center">
<ExternalContoursEmptyState title={emptyTitle} description={emptyDescription} />

View File

@ -219,10 +219,10 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
};
return (
<div className="block">
<div className="group/kanban-block relative mb-2">
<div
data-active={isActive}
className="nodedc-external-card relative flex min-h-[15rem] cursor-pointer flex-col px-6 py-5 transition-all hover:bg-white/5"
className="nodedc-external-card relative flex min-h-[220px] w-full cursor-pointer flex-col p-4 transition-all hover:bg-white/5"
role="button"
tabIndex={0}
onClick={openDetail}

View File

@ -77,7 +77,12 @@ export const ExternalContoursBoardRoot = observer(function ExternalContoursBoard
</div>
)}
<div className={cn("grid min-h-0 h-full grid-cols-1 gap-5 transition-opacity xl:grid-cols-2", { "opacity-60": isFiltering })}>
<div
className={cn(
"horizontal-scrollbar flex h-full min-h-0 items-stretch gap-4 overflow-x-auto overflow-y-hidden pb-1 transition-opacity",
{ "opacity-60": isFiltering }
)}
>
<ExternalContoursBoardColumn
currentTab={currentTab}
direction="outgoing"

View File

@ -216,11 +216,11 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
/>
<Row
className={`relative z-15 hidden h-full w-full items-center justify-between gap-4 px-6 py-5 lg:flex ${
className={`relative z-15 hidden w-full items-center justify-between gap-3 px-5 py-3.5 lg:flex ${
currentMode?.key === "full-screen" ? "border-b border-subtle/70" : ""
}`}
>
<div className="flex min-w-0 items-center gap-4">
<div className="flex min-w-0 items-center gap-3">
<Tooltip tooltipContent={t("common.close_peek_view")}>
<button onClick={removeRoutePeekId}>
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
@ -320,7 +320,8 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
isSubscribed={isSubscribed}
loading={isSubscriptionLoading}
onToggle={handleToggleSubscription}
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"
iconOnly
buttonClassName="size-10 rounded-[18px] border-transparent bg-layer-2/80 px-0 shadow-none backdrop-blur-xl hover:!bg-layer-2-active focus-visible:outline-none"
/>
)}
@ -347,7 +348,7 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
</div>
</Row>
<Header className="justify-start lg:hidden">
<Header className="justify-start px-4 py-3 lg:hidden">
<div className="flex w-full items-center gap-2">
<button onClick={removeRoutePeekId}>
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />

View File

@ -37,7 +37,7 @@ export const ExternalContoursIssueContentProperties = observer(function External
<div className="w-full overflow-visible">
<h5 className="mb-2 text-body-sm-medium">{t("external_contours_page.properties.section_title")}</h5>
<div className={`${!isEditable ? "opacity-60" : ""}`}>
<div className="flex flex-col gap-3">
<div className="grid grid-cols-2 gap-3">
<div className="nodedc-external-property-row">
<div className="nodedc-external-property-label">
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />

View File

@ -193,7 +193,7 @@ export const ExternalContoursIssueMainContent = observer(function ExternalContou
<div className="nodedc-external-section flex flex-col gap-3 px-4 py-4">
<div className="text-body-sm-medium">{t("external_contours_page.properties.section_title")}</div>
<div className="flex flex-col gap-3 text-13 text-secondary">
<div className="grid grid-cols-2 gap-3 text-13 text-secondary">
<div className="nodedc-external-property-row">
<div className="nodedc-external-property-label">
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />

View File

@ -195,9 +195,9 @@ export const ExternalContoursPeekShell = observer(function ExternalContoursPeekS
/>
<div className="vertical-scrollbar relative scrollbar-md h-full w-full overflow-hidden overflow-y-auto">
{["side-peek", "modal"].includes(peekMode) ? (
<div className="relative flex flex-col gap-4 px-8 py-6">{children}</div>
<div className="relative flex flex-col gap-4 px-6 pt-3 pb-5">{children}</div>
) : (
<div className="relative h-full w-full overflow-auto px-6 py-5">{children}</div>
<div className="relative h-full w-full overflow-auto px-5 pt-3 pb-4">{children}</div>
)}
</div>
</div>

View File

@ -84,18 +84,19 @@ type TExternalContourSubscriptionButtonProps = {
loading: boolean;
onToggle: () => Promise<void>;
buttonClassName?: string;
iconOnly?: boolean;
};
export const ExternalContourSubscriptionButton = observer(function ExternalContourSubscriptionButton(
props: TExternalContourSubscriptionButtonProps
) {
const { isSubscribed, loading, onToggle, buttonClassName } = props;
const { isSubscribed, loading, onToggle, buttonClassName, iconOnly = false } = props;
const { t } = useTranslation();
if (isSubscribed === undefined) {
return (
<Loader>
<Loader.Item width="106px" height="40px" />
<Loader.Item width={iconOnly ? "40px" : "106px"} height="40px" />
</Loader>
);
}
@ -109,13 +110,14 @@ export const ExternalContourSubscriptionButton = observer(function ExternalConto
disabled={loading}
size="lg"
>
{loading ? (
<span className="hidden sm:block">{t("common.loading")}</span>
) : isSubscribed ? (
<span className="hidden sm:block">{t("common.actions.unsubscribe")}</span>
) : (
<span className="hidden sm:block">{t("common.actions.subscribe")}</span>
)}
{!iconOnly &&
(loading ? (
<span className="hidden sm:block">{t("common.loading")}</span>
) : isSubscribed ? (
<span className="hidden sm:block">{t("common.actions.unsubscribe")}</span>
) : (
<span className="hidden sm:block">{t("common.actions.subscribe")}</span>
))}
</Button>
);
});

View File

@ -27,10 +27,11 @@ export type TIssueSubscription = {
issueId: string;
serviceType?: EIssueServiceType;
buttonClassName?: string;
iconOnly?: boolean;
};
export const IssueSubscription = observer(function IssueSubscription(props: TIssueSubscription) {
const { workspaceSlug, projectId, issueId, serviceType = EIssueServiceType.ISSUES, buttonClassName } = props;
const { workspaceSlug, projectId, issueId, serviceType = EIssueServiceType.ISSUES, buttonClassName, iconOnly = false } = props;
const { t } = useTranslation();
// hooks
const {
@ -77,7 +78,7 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
if (isNil(isSubscribed))
return (
<Loader>
<Loader.Item width="106px" height="28px" />
<Loader.Item width={iconOnly ? "40px" : "106px"} height={iconOnly ? "40px" : "28px"} />
</Loader>
);
@ -91,15 +92,16 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
disabled={!isEditable || loading}
size="lg"
>
{loading ? (
<span>
<span className="hidden sm:block">{t("common.loading")}</span>
</span>
) : isSubscribed ? (
<div className="hidden sm:block">{t("common.actions.unsubscribe")}</div>
) : (
<div className="hidden sm:block">{t("common.actions.subscribe")}</div>
)}
{!iconOnly &&
(loading ? (
<span>
<span className="hidden sm:block">{t("common.loading")}</span>
</span>
) : isSubscribed ? (
<div className="hidden sm:block">{t("common.actions.unsubscribe")}</div>
) : (
<div className="hidden sm:block">{t("common.actions.subscribe")}</div>
))}
</Button>
</div>
);

View File

@ -207,7 +207,8 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
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"
iconOnly
buttonClassName="size-10 rounded-[18px] border-transparent bg-layer-2/80 px-0 shadow-none backdrop-blur-xl hover:!bg-layer-2-active focus-visible:outline-none"
/>
)}
<Tooltip tooltipContent={t("common.actions.copy_link")} isMobile={isMobile}>