Split company show into ui/business + fix eslint

This commit is contained in:
Félix Malfait
2023-07-08 14:18:18 +02:00
parent 43fae8b638
commit c6a3c211e4
17 changed files with 225 additions and 229 deletions
@@ -1,5 +1,5 @@
import { BlockNoteEditor } from '@blocknote/core';
import { BlockNoteView, useBlockNote } from '@blocknote/react';
import { BlockNoteView } from '@blocknote/react';
import styled from '@emotion/styled';
import { PropertyBox } from '@/ui/components/property-box/PropertyBox';
@@ -54,7 +54,7 @@ const StyledEditableTitleInput = styled.input`
font-weight: ${({ theme }) => theme.font.weight.semiBold};
justify-content: center;
line-height: 120%;
line-height: ${({ theme }) => theme.text.lineHeight.md};
outline: none;
width: 318px;
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { BlockNoteEditor, PartialBlock } from '@blocknote/core';
import { BlockNoteEditor } from '@blocknote/core';
import { BlockNoteView, useBlockNote } from '@blocknote/react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
@@ -9,9 +9,6 @@ import { PropertyBoxItem } from '@/ui/components/property-box/PropertyBoxItem';
import { IconArrowUpRight } from '@/ui/icons/index';
import { useGetCommentThreadQuery } from '~/generated/graphql';
import { CommentableEntity } from '../types/CommentableEntity';
import { CommentThreadForDrawer } from '../types/CommentThreadForDrawer';
import { Comments } from './Comments';
import { CommentThreadRelationPicker } from './CommentThreadRelationPicker';
import { CommentThreadTypeDropdown } from './CommentThreadTypeDropdown';
@@ -59,7 +56,7 @@ const StyledEditableTitleInput = styled.input`
font-weight: ${({ theme }) => theme.font.weight.semiBold};
justify-content: center;
line-height: 120%;
line-height: ${({ theme }) => theme.text.lineHeight.md};
outline: none;
width: 318px;
@@ -22,7 +22,7 @@ const StyledCommentBody = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
font-size: ${({ theme }) => theme.font.size.md};
line-height: ${({ theme }) => theme.text.lineHeight};
line-height: ${({ theme }) => theme.text.lineHeight.md};
overflow-wrap: anywhere;
padding-left: 24px;
@@ -1,5 +1,4 @@
import { useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import {
autoUpdate,
@@ -9,7 +8,6 @@ import {
useFloating,
} from '@floating-ui/react';
import { CommentThreadForDrawer } from '@/comments/types/CommentThreadForDrawer';
import CompanyChip from '@/companies/components/CompanyChip';
import { useHotkeysScopeOnBooleanState } from '@/hotkeys/hooks/useHotkeysScopeOnBooleanState';
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
@@ -47,25 +45,6 @@ const StyledContainer = styled.div`
width: 100%;
`;
const StyledLabelContainer = styled.div`
align-items: center;
display: flex;
flex-direction: row;
gap: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(2)};
`;
const StyledRelationLabel = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
display: flex;
flex-direction: row;
user-select: none;
`;
const StyledRelationContainer = styled.div`
--horizontal-padding: ${({ theme }) => theme.spacing(1)};
--vertical-padding: ${({ theme }) => theme.spacing(1.5)};
@@ -108,8 +87,6 @@ export function CommentThreadRelationPicker({
isMenuOpen,
);
const theme = useTheme();
const peopleIds =
commentThread?.commentThreadTargets
?.filter((relation) => relation.commentableType === 'Person')
@@ -134,6 +111,7 @@ export function CommentThreadRelationPicker({
) {
companyIds.push(commentable.id);
}
return null;
});
const personsForMultiSelect = useFilteredSearchEntityQuery({
@@ -2,7 +2,7 @@ import {
DropdownButton,
DropdownOptionType,
} from '@/ui/components/buttons/DropdownButton';
import { IconNotes, IconPhone } from '@/ui/icons/index';
import { IconNotes } from '@/ui/icons/index';
export function CommentThreadTypeDropdown() {
const options: DropdownOptionType[] = [
@@ -4,13 +4,9 @@ import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { currentUserState } from '@/auth/states/currentUserState';
import { CommentThreadForDrawer } from '@/comments/types/CommentThreadForDrawer';
import { GET_COMPANIES } from '@/companies/services';
import { GET_PEOPLE } from '@/people/services';
import { AutosizeTextInput } from '@/ui/components/inputs/AutosizeTextInput';
import { PropertyBox } from '@/ui/components/property-box/PropertyBox';
import { PropertyBoxItem } from '@/ui/components/property-box/PropertyBoxItem';
import { IconArrowUpRight } from '@/ui/icons/index';
import { logError } from '@/utils/logs/logError';
import { isDefined } from '@/utils/type-guards/isDefined';
import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
@@ -23,7 +19,6 @@ import { GET_COMMENT_THREADS_BY_TARGETS } from '../services';
import { CommentThreadActionBar } from './CommentThreadActionBar';
import { CommentThreadItem } from './CommentThreadItem';
import { CommentThreadRelationPicker } from './CommentThreadRelationPicker';
type OwnProps = {
commentThread: GetCommentThreadQuery['findManyCommentThreads'][0];
@@ -3,7 +3,6 @@ import { useRecoilValue } from 'recoil';
import { RightDrawerBody } from '@/ui/layout/right-drawer/components/RightDrawerBody';
import { RightDrawerPage } from '@/ui/layout/right-drawer/components/RightDrawerPage';
import { RightDrawerTopBar } from '@/ui/layout/right-drawer/components/RightDrawerTopBar';
import { CommentableType } from '~/generated/graphql';
import { viewableCommentThreadIdState } from '../states/viewableCommentThreadIdState';
@@ -4,7 +4,6 @@ import styled from '@emotion/styled';
import { TableActionBarButtonToggleComments } from '@/ui/components/table/action-bar/TableActionBarButtonOpenComments';
import { IconNotes, IconPlus } from '@/ui/icons/index';
import { useOpenRightDrawer } from '@/ui/layout/right-drawer/hooks/useOpenRightDrawer';
import {
beautifyExactDate,
beautifyPastDateRelativeToNow,
@@ -13,7 +12,6 @@ import {
SortOrder,
useGetCommentThreadsByTargetsQuery,
} from '~/generated/graphql';
import { TableActionBarButtonCreateCommentThreadCompany } from '~/pages/companies/table/TableActionBarButtonCreateCommentThreadCompany';
import { useOpenCommentThreadRightDrawer } from '../hooks/useOpenCommentThreadRightDrawer';
import { useOpenCreateCommentThreadDrawer } from '../hooks/useOpenCreateCommentThreadDrawer';
@@ -47,14 +45,14 @@ const StyledEmptyTimelineTitle = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
font-size: ${({ theme }) => theme.font.size.xxl};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
line-height: 120%;
line-height: ${({ theme }) => theme.text.lineHeight.md};
`;
const StyledEmptyTimelineSubTitle = styled.div`
color: ${({ theme }) => theme.font.color.extraLight};
font-size: ${({ theme }) => theme.font.size.xxl};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
line-height: 120%;
line-height: ${({ theme }) => theme.text.lineHeight.md};
`;
const StyledTimelineItemContainer = styled.div`
@@ -135,7 +133,7 @@ const StyledCard = styled.div`
const StyledCardTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-weight: ${({ theme }) => theme.font.weight.medium};
line-height: 150%;
line-height: ${({ theme }) => theme.text.lineHeight.lg};
`;
const StyledCardContent = styled.div`
@@ -11,7 +11,6 @@ import {
import { GET_COMMENT_THREADS_BY_TARGETS } from '../services';
import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect';
import { CommentThreadForDrawer } from '../types/CommentThreadForDrawer';
export function useHandleCheckableCommentThreadTargetChange({
commentThread,
@@ -1,9 +1,7 @@
import { useRecoilState } from 'recoil';
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
import { commentableEntityArrayState } from '../states/commentableEntityArrayState';
import { viewableCommentThreadIdState } from '../states/viewableCommentThreadIdState';
import { CommentableEntity } from '../types/CommentableEntity';
export function useOpenCommentThreadRightDrawer() {
const openRightDrawer = useOpenRightDrawer();
@@ -26,7 +26,7 @@ const StyledButton = styled.button<ButtonProps>`
font-weight: ${({ theme }) => theme.font.weight.medium};
gap: 8px;
height: 24px;
line-height: 150%;
line-height: ${({ theme }) => theme.text.lineHeight.lg};
padding: 3px 8px;
svg {
@@ -8,7 +8,9 @@ const StyledCompanyPropertyBox = styled.div`
gap: 8px;
`;
const StyledCompanyPropertyBoxContainer = styled.div`
const StyledCompanyPropertyBoxContainer = styled.div<{
extraPadding?: boolean;
}>`
align-items: flex-start;
align-self: stretch;
background: ${({ theme }) => theme.background.secondary};
@@ -18,9 +20,18 @@ const StyledCompanyPropertyBoxContainer = styled.div`
flex-direction: column;
gap: 2px;
padding: 4px 12px;
padding: ${({ extraPadding }) => (extraPadding ? '4px 24px' : '4px 12px')};
`;
export function PropertyBox({ children }: { children: JSX.Element }) {
interface PropertyBoxProps {
children: JSX.Element;
extraPadding?: boolean;
}
export function PropertyBox({
children,
extraPadding = false,
}: PropertyBoxProps) {
return (
<StyledCompanyPropertyBox>
<StyledCompanyPropertyBoxContainer>
@@ -9,7 +9,7 @@ const StyledMainSectionTitle = styled.h2`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.xl};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
line-height: 1.5;
line-height: ${({ theme }) => theme.text.lineHeight.lg};
margin: 0;
`;
@@ -0,0 +1,68 @@
import { useParams } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useCompanyQuery } from '@/companies/services';
import { IconBuildingSkyscraper } from '@/ui/icons/index';
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
const StyledCompanyContainer = styled.div`
align-items: center;
align-self: stretch;
background: ${({ theme }) => theme.background.primary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: 8px;
display: flex;
flex: 1 0 0;
`;
const StyledLeftPanelContainer = styled.div`
align-items: flex-start;
align-self: stretch;
background: ${({ theme }) => theme.background.secondary};
border-radius: 8px;
border-right: 1px solid ${({ theme }) => theme.border.color.light};
padding: 0px ${({ theme }) => theme.spacing(3)};
width: 320px;
`;
const StyledRightPanelContainer = styled.div`
align-items: flex-start;
align-self: stretch;
display: flex;
flex: 1 0 0;
flex-direction: column;
justify-content: center;
overflow: hidden;
`;
export function ShowPageLayout({
leftSide,
rightSide,
title,
icon,
}: {
leftSide: JSX.Element;
rightSide: JSX.Element;
title: string;
icon: JSX.Element;
}) {
const companyId = useParams().companyId ?? '';
const { data } = useCompanyQuery(companyId);
const company = data?.findUniqueCompany;
const theme = useTheme();
return (
<WithTopBarContainer
title={company?.name ?? ''}
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
>
<StyledCompanyContainer>
<StyledLeftPanelContainer>{leftSide}</StyledLeftPanelContainer>
<StyledRightPanelContainer>{rightSide}</StyledRightPanelContainer>
</StyledCompanyContainer>
</WithTopBarContainer>
);
}
@@ -0,0 +1,101 @@
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import {
beautifyExactDate,
beautifyPastDateRelativeToNow,
} from '@/utils/datetime/date-utils';
const StyledShowTopLeftImageContainer = styled.div`
align-items: center;
align-self: stretch;
display: flex;
flex-direction: column;
gap: 8px;
justify-content: center;
padding: ${({ theme }) => theme.spacing(6)} ${({ theme }) => theme.spacing(3)}
${({ theme }) => theme.spacing(3)} ${({ theme }) => theme.spacing(3)};
`;
const StyledShowTopLeftImageInsideContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
gap: 12px;
img {
border-radius: 4px;
height: 40px;
width: 40px;
}
div {
align-items: center;
display: flex;
flex-direction: column;
gap: 4px;
}
`;
const StyledDate = styled.div`
color: ${({ theme }) => theme.font.color.tertiary};
`;
const StyledTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.xl};
font-style: normal;
font-weight: ${({ theme }) => theme.font.weight.semiBold};
line-height: ${({ theme }) => theme.text.lineHeight.md};
`;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: 0px 2px 4px 3px
${({ theme }) => theme.background.transparent.light};
box-shadow: 2px 4px 16px 6px
${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.primary};
opacity: 1;
padding: 8px;
`;
export function ShowPageTopLeftContainer({
logoOrAvatar,
title,
date,
}: {
logoOrAvatar: string;
title: string;
date: string;
}) {
if (!date) {
return null;
}
const beautifiedCreatedAt = beautifyPastDateRelativeToNow(date);
const exactCreatedAt = beautifyExactDate(date);
return (
<StyledShowTopLeftImageContainer>
<StyledShowTopLeftImageInsideContainer>
<img src={logoOrAvatar} alt="Logo or Avatar" />
<div>
<StyledTitle>{title}</StyledTitle>
<StyledDate id={`id-${title}`}>
Added {beautifiedCreatedAt} ago
</StyledDate>
<StyledTooltip
anchorSelect={`#id-${title}`}
content={exactCreatedAt}
clickable
noArrow
/>
</div>
</StyledShowTopLeftImageInsideContainer>
</StyledShowTopLeftImageContainer>
);
}
+30 -178
View File
@@ -1,55 +1,16 @@
import { useParams } from 'react-router-dom';
import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Timeline } from '@/comments/components/Timeline';
import { useCompanyQuery } from '@/companies/services';
import { PropertyBox } from '@/ui/components/property-box/PropertyBox';
import { PropertyBoxItem } from '@/ui/components/property-box/PropertyBoxItem';
import { IconBuildingSkyscraper, IconLink, IconMap } from '@/ui/icons/index';
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
import {
beautifyExactDate,
beautifyPastDateRelativeToNow,
} from '@/utils/datetime/date-utils';
import { ShowPageLayout } from '@/ui/layout/show-pages/ShowPageLayout';
import { ShowPageTopLeftContainer } from '@/ui/layout/show-pages/ShowPageTopLeftContainer';
import { getLogoUrlFromDomainName } from '@/utils/utils';
import { CommentableType } from '~/generated/graphql';
const StyledCompanyContainer = styled.div`
align-items: center;
align-self: stretch;
background: ${({ theme }) => theme.background.primary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: 8px;
display: flex;
flex: 1 0 0;
`;
const StyledLeftPanelContainer = styled.div`
align-items: flex-start;
align-self: stretch;
background: ${({ theme }) => theme.background.secondary};
border-radius: 8px;
border-right: 1px solid ${({ theme }) => theme.border.color.light};
padding: 0px ${({ theme }) => theme.spacing(3)};
width: 320px;
`;
const StyledRightPanelContainer = styled.div`
align-items: flex-start;
align-self: stretch;
display: flex;
flex: 1 0 0;
flex-direction: column;
justify-content: center;
overflow: hidden;
`;
const StyledPropertyBoxContainer = styled.div`
padding: 0px 12px;
`;
export function CompanyShow() {
const companyId = useParams().companyId ?? '';
@@ -59,147 +20,38 @@ export function CompanyShow() {
const theme = useTheme();
return (
<WithTopBarContainer
<ShowPageLayout
title={company?.name ?? ''}
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
>
<StyledCompanyContainer>
<StyledLeftPanelContainer>
<TopLeftHeaderOnShowPage
logo={getLogoUrlFromDomainName(company?.domainName ?? '')}
leftSide={
<>
<ShowPageTopLeftContainer
logoOrAvatar={getLogoUrlFromDomainName(company?.domainName ?? '')}
title={company?.name ?? ''}
date={company?.createdAt ?? ''}
/>
<StyledPropertyBoxContainer>
<PropertyBox>
<>
<PropertyBoxItem
icon={<IconLink />}
value={company?.domainName ?? ''}
link={
company?.domainName ? 'https://' + company?.domainName : ''
}
/>
<PropertyBoxItem
icon={<IconMap />}
value={company?.address ? company?.address : 'No address'}
/>
</>
</PropertyBox>
</StyledPropertyBoxContainer>
</StyledLeftPanelContainer>
<StyledRightPanelContainer>
<Timeline
entity={{ id: company?.id ?? '', type: CommentableType.Company }}
/>
</StyledRightPanelContainer>
</StyledCompanyContainer>
</WithTopBarContainer>
<PropertyBox extraPadding={true}>
<>
<PropertyBoxItem
icon={<IconLink />}
value={company?.domainName ?? ''}
link={
company?.domainName ? 'https://' + company?.domainName : ''
}
/>
<PropertyBoxItem
icon={<IconMap />}
value={company?.address ? company?.address : 'No address'}
/>
</>
</PropertyBox>
</>
}
rightSide={
<Timeline
entity={{ id: company?.id ?? '', type: CommentableType.Company }}
/>
}
/>
);
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
const StyledShowTopLeftImageContainer = styled.div`
align-items: center;
align-self: stretch;
display: flex;
flex-direction: column;
gap: 8px;
justify-content: center;
padding: ${({ theme }) => theme.spacing(6)} ${({ theme }) => theme.spacing(3)}
${({ theme }) => theme.spacing(3)} ${({ theme }) => theme.spacing(3)};
`;
const StyledShowTopLeftImageInsideContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
gap: 12px;
img {
border-radius: 4px;
height: 40px;
width: 40px;
}
div {
align-items: center;
display: flex;
flex-direction: column;
gap: 4px;
}
`;
const StyledDate = styled.div`
color: ${({ theme }) => theme.font.color.tertiary};
`;
const StyledTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.xl};
font-style: normal;
font-weight: ${({ theme }) => theme.font.weight.semiBold};
line-height: 120%;
`;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: 0px 2px 4px 3px
${({ theme }) => theme.background.transparent.light};
box-shadow: 2px 4px 16px 6px
${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.primary};
opacity: 1;
padding: 8px;
`;
export function TopLeftHeaderOnShowPage({
logo,
title,
date,
}: {
logo: string;
title: string;
date: string;
}) {
if (!date) {
return null;
}
const beautifiedCreatedAt = beautifyPastDateRelativeToNow(date);
const exactCreatedAt = beautifyExactDate(date);
return (
<StyledShowTopLeftImageContainer>
<StyledShowTopLeftImageInsideContainer>
<img src={logo} alt="Logo or Avatar" />
<div>
<StyledTitle>{title}</StyledTitle>
<StyledDate id={`id-${title}`}>
Added {beautifiedCreatedAt} ago
</StyledDate>
<StyledTooltip
anchorSelect={`#id-${title}`}
content={exactCreatedAt}
clickable
noArrow
/>
</div>
</StyledShowTopLeftImageInsideContainer>
</StyledShowTopLeftImageContainer>
);
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
+1 -1
View File
@@ -1,4 +1,4 @@
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { AuthTokens } from './dto/token.entity';
import { TokenService } from './services/token.service';
import { RefreshTokenInput } from './dto/refresh-token.input';