UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: исправление ширины карточек внешних контуров
This commit is contained in:
parent
d3b4c0689c
commit
ba34162eeb
|
|
@ -41,15 +41,15 @@ export const ExternalContoursBoardColumn = observer(function ExternalContoursBoa
|
||||||
: t("external_contours_page.board.empty.incoming_description");
|
: t("external_contours_page.board.empty.incoming_description");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[28px] bg-surface-2/30">
|
<section className="flex h-full min-h-0 w-[350px] flex-shrink-0 flex-col">
|
||||||
<div className="flex items-center justify-between gap-3 border-b border-subtle/40 px-5 py-4">
|
<div className="flex items-center justify-between gap-3 py-1.5">
|
||||||
<div className="text-15 font-semibold text-primary">{title}</div>
|
<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 className="rounded-full bg-white/5 px-2 py-1 text-12 font-semibold text-secondary">{totalCount}</div>
|
||||||
</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 ? (
|
{requestIds.length > 0 ? (
|
||||||
<div className="space-y-4">
|
<>
|
||||||
{requestIds.map((requestId) => {
|
{requestIds.map((requestId) => {
|
||||||
const request = getRequestById(requestId);
|
const request = getRequestById(requestId);
|
||||||
if (!request) return null;
|
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">
|
<div className="flex h-full min-h-[18rem] items-center justify-center">
|
||||||
<ExternalContoursEmptyState title={emptyTitle} description={emptyDescription} />
|
<ExternalContoursEmptyState title={emptyTitle} description={emptyDescription} />
|
||||||
|
|
|
||||||
|
|
@ -219,10 +219,10 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="block">
|
<div className="group/kanban-block relative mb-2">
|
||||||
<div
|
<div
|
||||||
data-active={isActive}
|
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"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={openDetail}
|
onClick={openDetail}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,12 @@ export const ExternalContoursBoardRoot = observer(function ExternalContoursBoard
|
||||||
</div>
|
</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
|
<ExternalContoursBoardColumn
|
||||||
currentTab={currentTab}
|
currentTab={currentTab}
|
||||||
direction="outgoing"
|
direction="outgoing"
|
||||||
|
|
|
||||||
|
|
@ -216,11 +216,11 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Row
|
<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" : ""
|
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")}>
|
<Tooltip tooltipContent={t("common.close_peek_view")}>
|
||||||
<button onClick={removeRoutePeekId}>
|
<button onClick={removeRoutePeekId}>
|
||||||
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
|
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
|
||||||
|
|
@ -320,7 +320,8 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
||||||
isSubscribed={isSubscribed}
|
isSubscribed={isSubscribed}
|
||||||
loading={isSubscriptionLoading}
|
loading={isSubscriptionLoading}
|
||||||
onToggle={handleToggleSubscription}
|
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>
|
</div>
|
||||||
</Row>
|
</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">
|
<div className="flex w-full items-center gap-2">
|
||||||
<button onClick={removeRoutePeekId}>
|
<button onClick={removeRoutePeekId}>
|
||||||
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
|
<MoveRight className="h-4 w-4 text-tertiary hover:text-secondary" />
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export const ExternalContoursIssueContentProperties = observer(function External
|
||||||
<div className="w-full overflow-visible">
|
<div className="w-full overflow-visible">
|
||||||
<h5 className="mb-2 text-body-sm-medium">{t("external_contours_page.properties.section_title")}</h5>
|
<h5 className="mb-2 text-body-sm-medium">{t("external_contours_page.properties.section_title")}</h5>
|
||||||
<div className={`${!isEditable ? "opacity-60" : ""}`}>
|
<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-row">
|
||||||
<div className="nodedc-external-property-label">
|
<div className="nodedc-external-property-label">
|
||||||
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||||
|
|
|
||||||
|
|
@ -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="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="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-row">
|
||||||
<div className="nodedc-external-property-label">
|
<div className="nodedc-external-property-label">
|
||||||
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||||
|
|
|
||||||
|
|
@ -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">
|
<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-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>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -84,18 +84,19 @@ type TExternalContourSubscriptionButtonProps = {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
onToggle: () => Promise<void>;
|
onToggle: () => Promise<void>;
|
||||||
buttonClassName?: string;
|
buttonClassName?: string;
|
||||||
|
iconOnly?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ExternalContourSubscriptionButton = observer(function ExternalContourSubscriptionButton(
|
export const ExternalContourSubscriptionButton = observer(function ExternalContourSubscriptionButton(
|
||||||
props: TExternalContourSubscriptionButtonProps
|
props: TExternalContourSubscriptionButtonProps
|
||||||
) {
|
) {
|
||||||
const { isSubscribed, loading, onToggle, buttonClassName } = props;
|
const { isSubscribed, loading, onToggle, buttonClassName, iconOnly = false } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (isSubscribed === undefined) {
|
if (isSubscribed === undefined) {
|
||||||
return (
|
return (
|
||||||
<Loader>
|
<Loader>
|
||||||
<Loader.Item width="106px" height="40px" />
|
<Loader.Item width={iconOnly ? "40px" : "106px"} height="40px" />
|
||||||
</Loader>
|
</Loader>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -109,13 +110,14 @@ export const ExternalContourSubscriptionButton = observer(function ExternalConto
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
size="lg"
|
size="lg"
|
||||||
>
|
>
|
||||||
{loading ? (
|
{!iconOnly &&
|
||||||
|
(loading ? (
|
||||||
<span className="hidden sm:block">{t("common.loading")}</span>
|
<span className="hidden sm:block">{t("common.loading")}</span>
|
||||||
) : isSubscribed ? (
|
) : isSubscribed ? (
|
||||||
<span className="hidden sm:block">{t("common.actions.unsubscribe")}</span>
|
<span className="hidden sm:block">{t("common.actions.unsubscribe")}</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="hidden sm:block">{t("common.actions.subscribe")}</span>
|
<span className="hidden sm:block">{t("common.actions.subscribe")}</span>
|
||||||
)}
|
))}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,11 @@ export type TIssueSubscription = {
|
||||||
issueId: string;
|
issueId: string;
|
||||||
serviceType?: EIssueServiceType;
|
serviceType?: EIssueServiceType;
|
||||||
buttonClassName?: string;
|
buttonClassName?: string;
|
||||||
|
iconOnly?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IssueSubscription = observer(function IssueSubscription(props: TIssueSubscription) {
|
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();
|
const { t } = useTranslation();
|
||||||
// hooks
|
// hooks
|
||||||
const {
|
const {
|
||||||
|
|
@ -77,7 +78,7 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
|
||||||
if (isNil(isSubscribed))
|
if (isNil(isSubscribed))
|
||||||
return (
|
return (
|
||||||
<Loader>
|
<Loader>
|
||||||
<Loader.Item width="106px" height="28px" />
|
<Loader.Item width={iconOnly ? "40px" : "106px"} height={iconOnly ? "40px" : "28px"} />
|
||||||
</Loader>
|
</Loader>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -91,7 +92,8 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
|
||||||
disabled={!isEditable || loading}
|
disabled={!isEditable || loading}
|
||||||
size="lg"
|
size="lg"
|
||||||
>
|
>
|
||||||
{loading ? (
|
{!iconOnly &&
|
||||||
|
(loading ? (
|
||||||
<span>
|
<span>
|
||||||
<span className="hidden sm:block">{t("common.loading")}</span>
|
<span className="hidden sm:block">{t("common.loading")}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -99,7 +101,7 @@ export const IssueSubscription = observer(function IssueSubscription(props: TIss
|
||||||
<div className="hidden sm:block">{t("common.actions.unsubscribe")}</div>
|
<div className="hidden sm:block">{t("common.actions.unsubscribe")}</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="hidden sm:block">{t("common.actions.subscribe")}</div>
|
<div className="hidden sm:block">{t("common.actions.subscribe")}</div>
|
||||||
)}
|
))}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,8 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
issueId={issueId}
|
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}>
|
<Tooltip tooltipContent={t("common.actions.copy_link")} isMobile={isMobile}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue