Skip to content

Commit

Permalink
Various styling improvements (twentyhq#766)
Browse files Browse the repository at this point in the history
* Various styling improvements

* Add card styling

* Fix select when editing fields

* Add colors

* Refactor prevent click
  • Loading branch information
emilienchvt authored Jul 19, 2023
1 parent d7efed9 commit 5fb7d75
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 65 deletions.
139 changes: 90 additions & 49 deletions front/src/modules/companies/components/CompanyBoardCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback } from 'react';
import { ReactNode, useCallback, useState } from 'react';
import { getOperationName } from '@apollo/client/utilities';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
Expand All @@ -13,28 +13,32 @@ import { selectedBoardCardsState } from '@/pipeline/states/selectedBoardCardsSta
import { ChipVariant } from '@/ui/chip/components/EntityChip';
import { DateEditableField } from '@/ui/editable-field/variants/components/DateEditableField';
import { NumberEditableField } from '@/ui/editable-field/variants/components/NumberEditableField';
import { IconCheck, IconCurrencyDollar } from '@/ui/icon';
import { IconCurrencyDollar, IconProgressCheck } from '@/ui/icon';
import { IconCalendarEvent } from '@/ui/icon';
import { Checkbox } from '@/ui/input/components/Checkbox';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { useUpdateOnePipelineProgressMutation } from '~/generated/graphql';
import { getLogoUrlFromDomainName } from '~/utils';

import { CompanyAccountOwnerEditableField } from '../editable-field/components/CompanyAccountOwnerEditableField';
import { PipelineProgressForBoard } from '../types/CompanyProgress';

import { CompanyChip } from './CompanyChip';

const StyledBoardCard = styled.div<{ selected: boolean }>`
background-color: ${({ theme, selected }) =>
selected ? theme.selectedCard : theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
selected ? theme.accent.quaternary : theme.background.secondary};
border: 1px solid
${({ theme, selected }) =>
selected ? theme.accent.secondary : theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-shadow: ${({ theme }) => theme.boxShadow.light};
color: ${({ theme }) => theme.font.color.primary};
&:hover {
background-color: ${({ theme, selected }) =>
selected ? theme.selectedCardHover : theme.background.tertiary};
selected && theme.accent.tertiary};
border: 1px solid
${({ theme, selected }) =>
selected ? theme.accent.primary : theme.border.color.medium};
}
cursor: pointer;
`;
Expand All @@ -49,6 +53,7 @@ const StyledBoardCardHeader = styled.div`
flex-direction: row;
font-weight: ${({ theme }) => theme.font.weight.semiBold};
height: 24px;
padding-bottom: ${({ theme }) => theme.spacing(1)};
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(2)};
Expand All @@ -62,7 +67,10 @@ const StyledBoardCardHeader = styled.div`
const StyledBoardCardBody = styled.div`
display: flex;
flex-direction: column;
padding: ${({ theme }) => theme.spacing(2)};
gap: ${({ theme }) => theme.spacing(0.5)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
padding-left: ${({ theme }) => theme.spacing(2.5)};
padding-right: ${({ theme }) => theme.spacing(2)};
span {
align-items: center;
display: flex;
Expand All @@ -74,7 +82,12 @@ const StyledBoardCardBody = styled.div`
}
`;

const StyledFieldContainer = styled.div`
width: max-content;
`;

export function CompanyBoardCard() {
const [isHovered, setIsHovered] = useState(false);
const [updatePipelineProgress] = useUpdateOnePipelineProgressMutation();

const [pipelineProgressId] = useRecoilScopedState(
Expand Down Expand Up @@ -119,17 +132,34 @@ export function CompanyBoardCard() {
[updatePipelineProgress],
);

const handleCheckboxChange = (checked: boolean) => {
setSelected(checked);
};

if (!company || !pipelineProgress) {
return null;
}

function PreventSelectOnClickContainer({
children,
}: {
children: ReactNode;
}) {
return (
<StyledFieldContainer
onClick={(e) => {
e.stopPropagation();
}}
>
{children}
</StyledFieldContainer>
);
}

return (
<StyledBoardCardWrapper>
<StyledBoardCard selected={selected}>
<StyledBoardCard
selected={selected}
onClick={() => setSelected(!selected)}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<StyledBoardCardHeader>
<CompanyChip
id={company.id}
Expand All @@ -139,45 +169,56 @@ export function CompanyBoardCard() {
variant={ChipVariant.transparent}
/>
<div style={{ display: 'flex', flex: 1 }} />
<Checkbox checked={selected} onChange={handleCheckboxChange} />
{(isHovered || selected) && (
<Checkbox
checked={selected}
onChange={() => setSelected(!selected)}
/>
)}
</StyledBoardCardHeader>
<StyledBoardCardBody>
<NumberEditableField
icon={<IconCurrencyDollar />}
placeholder="Opportunity amount"
value={pipelineProgress.amount}
onSubmit={(value) =>
handleCardUpdate({
...pipelineProgress,
amount: value,
})
}
/>
<CompanyAccountOwnerEditableField company={company} />
<DateEditableField
icon={<IconCalendarEvent />}
value={pipelineProgress.closeDate || new Date().toISOString()}
onSubmit={(value) =>
handleCardUpdate({
...pipelineProgress,
closeDate: value,
})
}
/>

<ProbabilityEditableField
icon={<IconCheck />}
value={pipelineProgress.probability}
onSubmit={(value) => {
handleCardUpdate({
...pipelineProgress,
probability: value,
});
}}
/>
<PipelineProgressPointOfContactEditableField
pipelineProgress={pipelineProgress}
/>
<PreventSelectOnClickContainer>
<DateEditableField
icon={<IconCalendarEvent />}
value={pipelineProgress.closeDate || new Date().toISOString()}
onSubmit={(value) =>
handleCardUpdate({
...pipelineProgress,
closeDate: value,
})
}
/>
</PreventSelectOnClickContainer>
<PreventSelectOnClickContainer>
<NumberEditableField
icon={<IconCurrencyDollar />}
placeholder="Opportunity amount"
value={pipelineProgress.amount}
onSubmit={(value) =>
handleCardUpdate({
...pipelineProgress,
amount: value,
})
}
/>
</PreventSelectOnClickContainer>
<PreventSelectOnClickContainer>
<ProbabilityEditableField
icon={<IconProgressCheck />}
value={pipelineProgress.probability}
onSubmit={(value) => {
handleCardUpdate({
...pipelineProgress,
probability: value,
});
}}
/>
</PreventSelectOnClickContainer>
<PreventSelectOnClickContainer>
<PipelineProgressPointOfContactEditableField
pipelineProgress={pipelineProgress}
/>
</PreventSelectOnClickContainer>
</StyledBoardCardBody>
</StyledBoardCard>
</StyledBoardCardWrapper>
Expand Down
3 changes: 2 additions & 1 deletion front/src/modules/pipeline/components/EntityBoardColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const StyledPlaceholder = styled.div`
`;

const StyledNewCardButtonContainer = styled.div`
padding-bottom: ${({ theme }) => theme.spacing(40)};
padding-bottom: ${({ theme }) => theme.spacing(4)};
`;

const BoardColumnCardsContainer = ({
Expand Down Expand Up @@ -86,6 +86,7 @@ export function EntityBoardColumn({
colorCode={column.colorCode}
pipelineStageId={column.pipelineStageId}
totalAmount={boardColumnTotal}
isFirstColumn={column.index === 0}
>
<BoardColumnCardsContainer droppableProvided={droppableProvided}>
{column.pipelineProgressIds.map((pipelineProgressId, index) => (
Expand Down
2 changes: 1 addition & 1 deletion front/src/modules/ui/board/components/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { DropResult } from '@hello-pangea/dnd'; // Atlassian dnd does not suppor
export const StyledBoard = styled.div`
border-radius: ${({ theme }) => theme.spacing(2)};
display: flex;
flex: 1;
flex-direction: row;
overflow-x: auto;
padding-left: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;

export type BoardPipelineStageColumn = {
Expand Down
23 changes: 17 additions & 6 deletions front/src/modules/ui/board/components/BoardColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,48 @@ import { debounce } from '~/utils/debounce';

import { EditColumnTitleInput } from './EditColumnTitleInput';

export const StyledColumn = styled.div`
export const StyledColumn = styled.div<{ isFirstColumn: boolean }>`
background-color: ${({ theme }) => theme.background.primary};
border-left: 1px solid
${({ theme, isFirstColumn }) =>
isFirstColumn ? 'none' : theme.border.color.light};
display: flex;
flex-direction: column;
min-width: 200px;
padding: ${({ theme }) => theme.spacing(2)};
`;

const StyledHeader = styled.div`
align-items: center;
cursor: pointer;
display: flex;
flex-direction: row;
justify-content: space-between;
height: 24px;
justify-content: left;
margin-bottom: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;

export const StyledColumnTitle = styled.h3`
align-items: center;
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ color }) => color};
display: flex;
flex-direction: row;
font-size: ${({ theme }) => theme.font.size.md};
font-style: normal;
font-weight: ${({ theme }) => theme.font.weight.medium};
gap: ${({ theme }) => theme.spacing(2)};
height: 24px;
margin: 0;
margin-bottom: ${({ theme }) => theme.spacing(1)};
padding-bottom: ${({ theme }) => theme.spacing(1)};
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(1)};
`;

const StyledAmount = styled.div`
color: ${({ theme }) => theme.font.color.tertiary};
margin-left: ${({ theme }) => theme.spacing(2)};
`;

type OwnProps = {
Expand All @@ -46,6 +56,7 @@ type OwnProps = {
onTitleEdit: (title: string) => void;
totalAmount?: number;
children: React.ReactNode;
isFirstColumn: boolean;
};

export function BoardColumn({
Expand All @@ -54,6 +65,7 @@ export function BoardColumn({
onTitleEdit,
totalAmount,
children,
isFirstColumn,
}: OwnProps) {
const [isEditing, setIsEditing] = React.useState(false);
const [internalValue, setInternalValue] = React.useState(title);
Expand All @@ -65,10 +77,9 @@ export function BoardColumn({
};

return (
<StyledColumn>
<StyledColumn isFirstColumn={isFirstColumn}>
<StyledHeader onClick={() => setIsEditing(true)}>
<StyledColumnTitle color={colorCode}>
{isEditing ? (
<EditColumnTitleInput
color={colorCode}
Expand Down
7 changes: 4 additions & 3 deletions front/src/modules/ui/board/components/BoardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ type OwnProps<SortField> = {
};

const StyledContainer = styled.div`
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
display: flex;
flex-direction: column;
`;

const StyledTableHeader = styled.div`
const StyledBoardHeader = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.secondary};
display: flex;
Expand Down Expand Up @@ -83,7 +84,7 @@ export function BoardHeader<SortField>({

return (
<StyledContainer>
<StyledTableHeader>
<StyledBoardHeader>
<StyledViewSection>
<StyledIcon>{viewIcon}</StyledIcon>
{viewName}
Expand All @@ -100,7 +101,7 @@ export function BoardHeader<SortField>({
HotkeyScope={FiltersHotkeyScope.FilterDropdownButton}
/>
</StyledFilters>
</StyledTableHeader>
</StyledBoardHeader>
<SortAndFilterBar
context={context}
sorts={sorts}
Expand Down
2 changes: 1 addition & 1 deletion front/src/modules/ui/board/components/NewButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const StyledButton = styled.button`
padding: ${({ theme }) => theme.spacing(1)};
&:hover {
background-color: ${({ theme }) => theme.background.secondary};
background-color: ${({ theme }) => theme.background.tertiary};
}
`;

Expand Down
1 change: 1 addition & 0 deletions front/src/modules/ui/icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { IconSearch } from '@tabler/icons-react';
export { IconSettings } from '@tabler/icons-react';
export { IconLogout } from '@tabler/icons-react';
export { IconColorSwatch } from '@tabler/icons-react';
export { IconProgressCheck } from '@tabler/icons-react';
export { IconX } from '@tabler/icons-react';
export { IconChevronLeft } from '@tabler/icons-react';
export { IconPlus } from '@tabler/icons-react';
Expand Down
15 changes: 15 additions & 0 deletions front/src/modules/ui/themes/accent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { color } from './colors';

export const accentLight = {
primary: color.blueAccent25,
secondary: color.blueAccent20,
tertiary: color.blueAccent15,
quaternary: color.blueAccent10,
};

export const accentDark = {
primary: color.blueAccent75,
secondary: color.blueAccent80,
tertiary: color.blueAccent85,
quaternary: color.blueAccent90,
};
Loading

0 comments on commit 5fb7d75

Please sign in to comment.