Skip to content

Commit

Permalink
chore(ProjectListItemCollapsable): remove Goals button
Browse files Browse the repository at this point in the history
  • Loading branch information
asabotovich committed Aug 7, 2023
1 parent 41ddaf0 commit 296bc90
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 151 deletions.
45 changes: 29 additions & 16 deletions src/components/CollapsableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const StyledCollapsableHeader = styled.div`

const StyledCollapsableItem = styled.div`
position: relative;
padding-bottom: 1px;
&:before {
content: '';
Expand All @@ -56,7 +57,7 @@ const StyledHeaderContent = styled.div<{ highlighted?: boolean }>`
`}
`;

const StyledCollapsableContainer = styled.div<{ collapsed: boolean; deep: number }>`
const StyledCollapsableContainer = styled.div<{ collapsed: boolean; deep: number; hasChild: boolean }>`
position: relative;
border-radius: ${radiusM};
Expand Down Expand Up @@ -85,8 +86,9 @@ const StyledCollapsableContainer = styled.div<{ collapsed: boolean; deep: number
padding-left: ${collapseOffset}px;
`}
${({ collapsed, deep }) =>
${({ collapsed, deep, hasChild }) =>
!collapsed &&
hasChild &&
css`
padding-left: ${collapseOffset}px;
margin-left: ${deep === 0 ? -collapseOffset : 0}px;
Expand Down Expand Up @@ -143,29 +145,40 @@ const StyledCollapsableContainer = styled.div<{ collapsed: boolean; deep: number
margin-left: -${collapseOffset}px;
}
> ${StyledCollapsableItem}:before {
/** show grey line for additional content section (for example goals list) if it's not last item. See design :) */
// TODO: Remove this here https://github.com/taskany-inc/issues/issues/1448
> ${StyledCollapsableItem}:not(:last-child):before {
display: block;
}
`}
`;

export const CollapsableContentItem: FC<{
children?: ReactNode;
className?: string;
}> = ({ children, className }) => <StyledCollapsableItem className={className}>{children}</StyledCollapsableItem>;

export const CollapsableItem: FC<{
children?: ReactNode;
onClick?: () => void;
header: ReactNode;
content: ReactNode;
deep?: number;
collapsed: boolean;
}> = ({ onClick, children, header, collapsed, deep = 0, content }) => (
<StyledCollapsableContainer collapsed={collapsed} deep={deep}>
<StyledCollapsableHeader onClick={onClick}>
<StyledParentDot />
<StyledDot />
<StyledHeaderContent highlighted={!!onClick && collapsed}>{header}</StyledHeaderContent>
</StyledCollapsableHeader>
{nullable(children, (ch) => (
<StyledCollapsableItem>{ch}</StyledCollapsableItem>
))}
{!collapsed ? content : null}
</StyledCollapsableContainer>
);
hasChild: boolean;
}> = ({ onClick, children, header, collapsed, deep = 0, hasChild, content }) => {
return (
<StyledCollapsableContainer collapsed={collapsed} deep={deep} hasChild={hasChild}>
<StyledCollapsableHeader onClick={onClick}>
<StyledParentDot />
<StyledDot />
<StyledHeaderContent highlighted={!!onClick && collapsed}>{header}</StyledHeaderContent>
</StyledCollapsableHeader>
{nullable(children, (ch) => (
<StyledCollapsableItem>{ch}</StyledCollapsableItem>
))}
{!collapsed ? content : null}
</StyledCollapsableContainer>
);
};
5 changes: 4 additions & 1 deletion src/components/CommonHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface CommonHeaderProps {
preTitle?: React.ReactNode;
description?: React.ReactNode;
children?: React.ReactNode;
actions?: React.ReactNode;
}

const StyledCommonHeader = styled(PageContent)`
Expand All @@ -35,7 +36,7 @@ const StyledCommonHeaderTitle = styled(Text)`
padding-top: ${gapM};
`;

export const CommonHeader: React.FC<CommonHeaderProps> = ({ preTitle, title, description, children }) => {
export const CommonHeader: React.FC<CommonHeaderProps> = ({ preTitle, title, description, children, actions }) => {
return (
<StyledCommonHeader>
<StyledCommonHeaderInfo align="left">
Expand All @@ -56,6 +57,8 @@ export const CommonHeader: React.FC<CommonHeaderProps> = ({ preTitle, title, des
))}
</StyledCommonHeaderInfo>

<div>{actions}</div>

{children}
</StyledCommonHeader>
);
Expand Down
2 changes: 0 additions & 2 deletions src/components/ExplorePageLayout/ExplorePageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export const ExplorePageLayout: React.FC<ExplorePageLayoutProps> = ({ children }
title={tr('Explore')}
description={tr('See what the Taskany community is most excited about today')}
>
<div className="exploreActions"></div>

<TabsMenu>
{tabsMenuOptions.map(([title, href]) => (
<NextLink key={href} href={href} passHref>
Expand Down
1 change: 1 addition & 0 deletions src/components/ProjectListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface ProjectListItemProps {
className?: string;
disabled?: boolean;
averageScore: number | null;
onClick?: (e: React.MouseEvent) => void;
}

const StyledTitleCell = styled(TableCell)`
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,68 +1,51 @@
import React, { MouseEvent, ReactNode, useCallback, useMemo } from 'react';
import NextLink from 'next/link';
import React, { MouseEvent, ReactNode, useMemo } from 'react';
import styled from 'styled-components';
import { Badge, Button, ExternalLinkIcon, Link, Text, nullable } from '@taskany/bricks';
import { gapS, gray7, gray4, radiusM } from '@taskany/colors';
import NextLink from 'next/link';
import { gapXs, gray4, radiusM } from '@taskany/colors';
import { Text, nullable } from '@taskany/bricks';
import { IconServersOutline } from '@taskany/icons';

import { ProjectByIdReturnType } from '../../../trpc/inferredTypes';
import { GoalsListContainer } from '../GoalListItem';
import { CollapsableItem, collapseOffset } from '../CollapsableItem';
import { CollapsableItem, CollapsableContentItem, collapseOffset } from '../CollapsableItem';
import { ProjectListContainer, ProjectListItem } from '../ProjectListItem';

import { tr } from './ProjectListItemCollapsable.i18n';

const StyledNoGoals = styled(Text)`
white-space: nowrap;
`;

const StyledProjectListItemActionsContainer = styled.div`
display: flex;
align-items: center;
`;

const StyledProjectListItemAction = styled.div<{ forceVisibility?: boolean }>`
visibility: ${({ forceVisibility }) => (forceVisibility ? 'visible' : 'hidden')};
margin-left: ${gapS};
&:first-child {
margin-left: 0;
}
`;

const StyledProjectListItem = styled(ProjectListItem)`
&:hover {
${StyledProjectListItemAction} {
visibility: visible;
}
}
`;

const StyledGoalsListContainer = styled(GoalsListContainer)`
background-color: ${gray4};
border-radius: ${radiusM};
margin: 0px;
padding: 0px;
`;

const StyledProjectIcons = styled.div`
display: flex;
align-items: center;
gap: ${gapXs};
`;

interface ProjectListItemCollapsableProps {
href?: string;
project: NonNullable<ProjectByIdReturnType>;
goals?: ReactNode;
children?: ReactNode;
collapsed: boolean;
collapsedGoals: boolean;
onClick?: () => void;
onGoalsClick?: () => void;
loading?: boolean;
deep?: number;
}

const onProjectClickHandler = (e: MouseEvent) => {
if (!e.metaKey && !e.ctrlKey) {
e.preventDefault();
} else {
e.stopPropagation();
}
};

export const ProjectListItemCollapsable: React.FC<ProjectListItemCollapsableProps> = ({
project,
collapsed = true,
collapsedGoals = true,
onClick,
onGoalsClick,
children,
goals,
loading = false,
Expand All @@ -71,69 +54,55 @@ export const ProjectListItemCollapsable: React.FC<ProjectListItemCollapsableProp
}) => {
const childs = useMemo(() => project.children.map(({ id }) => id), [project]);

const onClickEnabled = childs.length;
const contentHidden = !childs.length || collapsed || loading;
const contentHidden = collapsed || loading;

const offset = collapseOffset * (deep > 0 && contentHidden ? deep - 1 : deep);

const onGoalsButtonClick = useCallback(
(e: MouseEvent) => {
e.stopPropagation();

onGoalsClick?.();
},
[onGoalsClick],
const projectComponent = (
<ProjectListItem
as="a"
title={project.title}
owner={project.activity}
participants={project.participants}
starred={project._isStarred}
watching={project._isWatching}
averageScore={project.averageScore}
onClick={onProjectClickHandler}
>
{nullable(childs.length, (c) => (
<StyledProjectIcons>
<IconServersOutline size="xs" />
<Text size="xs">{c}</Text>
</StyledProjectIcons>
))}
</ProjectListItem>
);

const onExternalLinkClick = useCallback((e: MouseEvent) => {
e.stopPropagation();
}, []);

return (
<CollapsableItem
collapsed={contentHidden}
onClick={onClickEnabled ? onClick : undefined}
onClick={onClick}
hasChild={!!childs.length}
header={
<ProjectListContainer offset={offset}>
<StyledProjectListItem
title={project.title}
owner={project.activity}
participants={project.participants}
starred={project._isStarred}
watching={project._isWatching}
disabled={!onClickEnabled}
averageScore={project.averageScore}
>
<StyledProjectListItemActionsContainer>
<StyledProjectListItemAction forceVisibility={!collapsedGoals}>
{project._count.goals ? (
<Button
ghost={collapsedGoals}
onClick={onGoalsButtonClick}
text={tr('Goals')}
iconRight={<Badge size="s">{project._count.goals}</Badge>}
/>
) : (
<StyledNoGoals color={gray7}>{tr('No goals')}</StyledNoGoals>
)}
</StyledProjectListItemAction>
<StyledProjectListItemAction>
{nullable(href, (h) => (
<NextLink href={h} passHref legacyBehavior>
<Link inline target="_blank" onClick={onExternalLinkClick}>
<ExternalLinkIcon size="s" />
</Link>
</NextLink>
))}
</StyledProjectListItemAction>
</StyledProjectListItemActionsContainer>
</StyledProjectListItem>
{href ? (
<NextLink href={href} passHref legacyBehavior>
{projectComponent}
</NextLink>
) : (
projectComponent
)}
</ProjectListContainer>
}
content={children}
content={
<>
<CollapsableContentItem>
<StyledGoalsListContainer offset={offset}>{goals}</StyledGoalsListContainer>
</CollapsableContentItem>
{children}
</>
}
deep={deep}
>
{!collapsedGoals && <StyledGoalsListContainer offset={offset}>{goals}</StyledGoalsListContainer>}
</CollapsableItem>
></CollapsableItem>
);
};
Loading

0 comments on commit 296bc90

Please sign in to comment.